Skip to content

Instantly share code, notes, and snippets.

@SabrinaMarkon
Last active March 23, 2019 04:27
Show Gist options
  • Save SabrinaMarkon/953883726508fa15a4d279190885ac4c to your computer and use it in GitHub Desktop.
Save SabrinaMarkon/953883726508fa15a4d279190885ac4c to your computer and use it in GitHub Desktop.
Three.js Methane Molecule - https://jsbin.com/jemuwec
<!DOCTYPE html>
<html>
<head>
<!--<script src="https://getfirebug.com/firebug-lite-debug.js"></script>-->
<meta name="description" content=">Three.js Methane Molecule" />
<meta charset="utf-8" />
<title>Three.js Methane Molecule</title>
<style>
#container {
background: #000000;
width: 100%;
height: 100%;
}
</style>
<meta charset=utf-8 />
<style id="jsbin-css">
</style>
</head>
<body>
<div id="container">
</div>
</body>
<script>'use strict';</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.4.2/math.min.js"></script>
<script>
// Set the scene size.
const WIDTH = 800, HEIGHT = 800;
// Set some camera attributes.
const VIEW_ANGLE = 30, ASPECT = WIDTH / HEIGHT, NEAR = 1, FAR = 1000;
// Get the DOM element to attach to.
const $container = $('#container');
// Create a WebGL renderer, camera, and a scene.
const renderer = new THREE.WebGLRenderer();
// Turn on shadows!
renderer.shadowMap.enabled = true;
const scene = new THREE.Scene();
let clock = new THREE.Clock(); // clock is not a constant because we need to reset it during the scale animation.
const camera = new THREE.PerspectiveCamera(VIEW_ANGLE,ASPECT,NEAR,FAR);
// the camera starts at 0,0,0 so pull it back
camera.position.z = 500;
// add the camera to the scene
scene.add(camera)
// Set it up so we can move the grouped model with the mouse, but not the plane or lighting.
var canvas = renderer.domElement;
canvas.addEventListener('mousemove', function() {
group.rotation.x += event.movementX * 0.005;
group.rotation.y += event.movementY * 0.005;
//group.rotation.z += event.movementZ * 0.005;
});
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
// attach the render-supplied DOM element
$container.append(renderer.domElement);
// ----------------------------------------------------------------------------------------
// END OF THE STANDARD CODE FOR THE ASSIGNMENT
// Following this is where you must place your own custom code to complete the assignment
// ----------------------------------------------------------------------------------------
// LIGHTING
// a PointLight is a light that sits at a point and shoots light in all
// directions from that point" (ThreeJSFundamentals.org, n.d.)
// IF there is no point light and you use the mouse to orbit the donuts you will see that the light stays
// shining on the same side of the donut.
const plightcolor = 0xFFFFFF;
const plightintensity = 2;
const pointlight = new THREE.PointLight(plightcolor, plightintensity);
pointlight.position.set(35, 125, 100);
pointlight.castShadow = true; // pointlight is able to cause models to cast shadows.
scene.add(pointlight);
// shows a plane, to represent the light, and a line from the light to the target (ThreeJSFundamentals.org, n.d.)
// const plighthelper = new THREE.PointLightHelper(pointlight);
// scene.add(plighthelper);
// "The AmbientLight effectively just multiply's the material's color
// by the light's color times the intensity" (ThreeJSFundamentals.org, n.d.)
const ambientlight = new THREE.AmbientLight(0x666666);
scene.add(ambientlight);
// PLANE
const planegeometry = new THREE.PlaneBufferGeometry(400, 300, 8, 8);
const planematerial = new THREE.MeshPhongMaterial({ color: 0x203030, side: THREE.DoubleSide });
const plane = new THREE.Mesh(planegeometry, planematerial);
plane.rotateX(-70);
plane.rotateZ(25);
plane.position.y = -50;
plane.receiveShadow = true; // plane receives (shows) shadows cast by models.
scene.add(plane);
// Set up the Carbon Atom (red sphere) properties.
const carbonradius = 20, segments = 100, rings = 100;
// LARGE SPHERE - CARBON ATOM (0xFF0000 - Red) - Using Phong so shading is shown.
const carbonMaterial = new THREE.MeshPhongMaterial({color: 0xFF0000, shininess: 50});
const carbon = new THREE.Mesh(
new THREE.SphereGeometry(carbonradius, segments, rings),
carbonMaterial);
carbon.position.set(30, 30, 30);
carbon.castShadow = true; // atom models and bonds cast shadows.
carbon.receiveShadow = true; // atom models and bonds receuve shadows from other models.
// set up the Hydrogen Atom (blue spheres) properties.
const hydrogenradius = 10;
// SMALL SPHERES - HYDROGEN ATOM (0x0000FF - Blue) - Using Phong so shading is shown.
const hydrogenMaterial = new THREE.MeshPhongMaterial({color: 0x0000FF, shininess: 50});
// Set up the Bond (white cylinders) properties.
const bondradiustop = 3, bondradiusbottom = 3, height = 50, radialSegments = 8, heightSegments = 1,
openEnded = true, thetaStart = 30, thetaLength = Math.PI*2;
// BOND MATERIAL (0xFFFFFF - White).
const bondMaterial = new THREE.MeshPhongMaterial({color: 0xFFFFFF, shininess: 10});
// BOND #1
const vector1 = new THREE.Vector3(65, 0, 0);
const bond1geometry = new THREE.CylinderGeometry( bondradiustop, bondradiusbottom, vector1.length(), rings, radialSegments,
heightSegments, openEnded );
// shift it so one end rests on the origin.
bond1geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, height / 2, 0 ) );
// rotate it the right way.
bond1geometry.applyMatrix( new THREE.Matrix4().makeRotationX( THREE.Math.degToRad( 52 ) ) );
bond1geometry.applyMatrix( new THREE.Matrix4().makeRotationY( THREE.Math.degToRad( 43 ) ) );
bond1geometry.applyMatrix( new THREE.Matrix4().makeRotationZ( THREE.Math.degToRad( -1 ) ) );
// Make a mesh with the geometry.
const bond1 = new THREE.Mesh( bond1geometry, bondMaterial );
carbon.castShadow = true; // atom models and bonds cast shadows.
carbon.receiveShadow = true; // atom models and bonds receuve shadows from other models.
// BOND #2
var bond2geometry = new THREE.CylinderGeometry( bondradiustop, bondradiusbottom, height, rings, radialSegments,
heightSegments, openEnded );
// shift it so one end rests on the origin
bond2geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, height / 2, 0 ) );
// rotate it the right way.
bond2geometry.applyMatrix( new THREE.Matrix4().makeRotationX( THREE.Math.degToRad( -46 ) ) );
bond2geometry.applyMatrix( new THREE.Matrix4().makeRotationY( THREE.Math.degToRad( -45 ) ) );
bond2geometry.applyMatrix( new THREE.Matrix4().makeRotationZ( THREE.Math.degToRad( 77 ) ) );
// Make a mesh with the geometry.
var bond2 = new THREE.Mesh( bond2geometry, bondMaterial );
// BOND #3
var bond3geometry = new THREE.CylinderGeometry( bondradiustop, bondradiusbottom, height, rings, radialSegments,
heightSegments, openEnded );
// shift it so one end rests on the origin
bond3geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, height / 2, 0 ) );
// rotate it the right way.
bond3geometry.applyMatrix( new THREE.Matrix4().makeRotationX( THREE.Math.degToRad( 91 ) ) );
bond3geometry.applyMatrix( new THREE.Matrix4().makeRotationY( THREE.Math.degToRad( -47 ) ) );
bond3geometry.applyMatrix( new THREE.Matrix4().makeRotationZ( THREE.Math.degToRad( 42 ) ) );
// Make a mesh with the geometry.
var bond3 = new THREE.Mesh( bond3geometry, bondMaterial );
// BOND #4
var bond4geometry = new THREE.CylinderGeometry( bondradiustop, bondradiusbottom, height, rings, radialSegments,
heightSegments, openEnded );
// shift it so one end rests on the origin
bond4geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, height / 2, 0 ) );
// rotate it the right way.
bond4geometry.applyMatrix( new THREE.Matrix4().makeRotationX( THREE.Math.degToRad( 310 ) ) );
bond4geometry.applyMatrix( new THREE.Matrix4().makeRotationY( THREE.Math.degToRad( -45 ) ) );
bond4geometry.applyMatrix( new THREE.Matrix4().makeRotationZ( THREE.Math.degToRad( -89 ) ) );
// Make a mesh with the geometry.
var bond4 = new THREE.Mesh( bond4geometry, bondMaterial );
// HYDROGEN ATOM #1
const hydrogen1 = new THREE.Mesh(
new THREE.SphereGeometry(hydrogenradius, segments, rings),
hydrogenMaterial);
hydrogen1.position.set(65, 0, 0);
hydrogen1.castShadow = true; // atom models and bonds cast shadows.
hydrogen1.receiveShadow = true; // atom models and bonds receuve shadows from other models.
// HYDROGEN ATOM #2
const hydrogen2 = new THREE.Mesh(
new THREE.SphereGeometry(hydrogenradius, segments, rings),
hydrogenMaterial);
hydrogen2.position.set(0, 65, 0);
hydrogen2.castShadow = true; // atom models and bonds cast shadows.
hydrogen2.receiveShadow = true; // atom models and bonds receuve shadows from other models.
// HYDROGEN ATOM #3
const hydrogen3 = new THREE.Mesh(
new THREE.SphereGeometry(hydrogenradius, segments, rings),
hydrogenMaterial);
hydrogen3.position.set(0, 0, 65);
hydrogen3.castShadow = true; // atom models and bonds cast shadows.
hydrogen3.receiveShadow = true; // atom models and bonds receuve shadows from other models.
// HYDROGEN ATOM #4
const hydrogen4 = new THREE.Mesh(
new THREE.SphereGeometry(hydrogenradius, segments, rings),
hydrogenMaterial);
hydrogen4.position.set(65, 65, 65);
hydrogen4.castShadow = true; // atom models and bonds cast shadows.
hydrogen4.receiveShadow = true; // atom models and bonds receuve shadows from other models.
//create an empty group container.
group = new THREE.Object3D();
// Add all the models (atoms and bonds, but not lights or plane) to the group,
// so we can rotate or shadow them all at once.
group.add(carbon);
// adding bonds to carbon made them all easy (well once I thought of it, which took forever)
// to position from the origin - the middle of the carbon atom.
carbon.add(bond1);
carbon.add(bond2);
carbon.add(bond3);
carbon.add(bond4);
group.add( hydrogen1);
group.add( hydrogen2);
group.add( hydrogen3);
group.add( hydrogen4);
//when done, add the group to the scene at once.
scene.add( group );
// standard functions for rendering the scene. Notice how we have the animate function
// which submits a call to requestAnimationFrame to call animate. This creates a loop
// that will render the scene again whenever something within the scene changes.
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
animate();
/*
References
Cunningham, S. (2003). Computer Graphics: Programming, Problem Solving, and Visual Communication. Retrieved from https://my.uopeople.edu/pluginfile.php/389065/mod_resource/content/4/ComputerGraphics-SteveCunningham.pdf
ThreeJSFundamentals.org (n.d.). Three.js Lights. Retrieved from https://threejsfundamentals.org/threejs/lessons/threejs-lights.html
Threejs.org (n.d.). Three.js docs: OrbitControls. Retrieved from https://threejs.org/docs/#examples/controls/OrbitControls
*/
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment