Interactive 3D Graphics-Lesson4 Problem Set

来源:互联网 发布:数据交易 qq 编辑:程序博客网 时间:2024/06/05 19:44

第四课讲的是变换,还有坐标系之类的,不是很深。

第四课的Problem set记录。

1.机器人手臂

要求是添加机器人手臂的底座,只要理解好THREE.Object3D()就可以了。参考一下原有的代码就可以得到结果。

/////////////////////////////////////////////////////////////////////////////////*global THREE, Coordinates, $, document, window, dat*/var camera, scene, renderer;var cameraControls, effectController;var clock = new THREE.Clock();var gridX = true;var gridY = false;var gridZ = false;var axes = true;var ground = true;var arm, forearm, body;function fillScene() {scene = new THREE.Scene();scene.fog = new THREE.Fog( 0x808080, 2000, 4000 );// LIGHTSvar ambientLight = new THREE.AmbientLight( 0x222222 );var light = new THREE.DirectionalLight( 0xffffff, 1.0 );light.position.set( 200, 400, 500 );var light2 = new THREE.DirectionalLight( 0xffffff, 1.0 );light2.position.set( -500, 250, -200 );scene.add(ambientLight);scene.add(light);scene.add(light2);    // Robot definitionsvar robotBaseMaterial = new THREE.MeshPhongMaterial( { color: 0x6E23BB, specular: 0x6E23BB, shininess: 20 } );var robotForearmMaterial = new THREE.MeshPhongMaterial( { color: 0xF4C154, specular: 0xF4C154, shininess: 100 } );var robotUpperArmMaterial = new THREE.MeshPhongMaterial( { color: 0x95E4FB, specular: 0x95E4FB, shininess: 100 } );var robotBodyMaterial = new THREE.MeshPhongMaterial( { color: 0x279933, specular: 0x279933, shininess: 100 } );var torus = new THREE.Mesh( new THREE.TorusGeometry( 22, 15, 32, 32 ), robotBaseMaterial );torus.rotation.x = 90 * Math.PI/180;scene.add( torus );forearm = new THREE.Object3D();var faLength = 80;createRobotExtender( forearm, faLength, robotForearmMaterial );arm = new THREE.Object3D();var uaLength = 120;createRobotCrane( arm, uaLength, robotUpperArmMaterial );// Move the forearm itself to the end of the upper arm.forearm.position.y = uaLength;arm.add( forearm );//scene.add( arm );    // YOUR CODE HERE  body = new THREE.Object3D();var bodyLength = 60;        arm.position.y = bodyLength;        body.add( arm );        createRobotBody( body, bodyLength, robotBodyMaterial );        scene.add( body );}function createRobotExtender( part, length, material ){var cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 22, 22, 6, 32 ), material );part.add( cylinder );var i;for ( i = 0; i < 4; i++ ){var box = new THREE.Mesh( new THREE.CubeGeometry( 4, length, 4 ), material );box.position.x = (i < 2) ? -8 : 8;box.position.y = length/2;box.position.z = (i%2) ? -8 : 8;part.add( box );}cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 15, 15, 40, 32 ), material );cylinder.rotation.x = 90 * Math.PI/180;cylinder.position.y = length;part.add( cylinder );}function createRobotCrane( part, length, material ){var box = new THREE.Mesh( new THREE.CubeGeometry( 18, length, 18 ), material );box.position.y = length/2;part.add( box );var sphere = new THREE.Mesh( new THREE.SphereGeometry( 20, 32, 16 ), material );// place sphere at end of armsphere.position.y = length;part.add( sphere );}function createRobotBody( part, length, material ){var cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 50, 12, length/2, 18 ), material );cylinder.position.y = length/4;part.add( cylinder );cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 12, 50, length/2, 18 ), material );cylinder.position.y = 3*length/4;part.add( cylinder );var box = new THREE.Mesh( new THREE.CubeGeometry( 12, length/4, 110 ), material );box.position.y = length/2;part.add( box );var sphere = new THREE.Mesh( new THREE.SphereGeometry( 20, 32, 16 ), material );// place sphere at end of armsphere.position.y = length;part.add( sphere );}function init() {var canvasWidth = 846;var canvasHeight = 494;var canvasRatio = canvasWidth / canvasHeight;// RENDERERrenderer = new THREE.WebGLRenderer( { antialias: true } );renderer.gammaInput = true;renderer.gammaOutput = true;renderer.setSize(canvasWidth, canvasHeight);renderer.setClearColorHex( 0xAAAAAA, 1.0 );// CAMERAcamera = new THREE.PerspectiveCamera( 38, canvasRatio, 1, 10000 );camera.position.set( -510, 240, 100 );// CONTROLScameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);cameraControls.target.set(0,120,0);camera.position.set(-102, 177, 20);cameraControls.target.set(-13, 60, 2);fillScene();}function addToDOM() {    var container = document.getElementById('container');    var canvas = container.getElementsByTagName('canvas');    if (canvas.length>0) {        container.removeChild(canvas[0]);    }    container.appendChild( renderer.domElement );}function drawHelpers() {    if (ground) {Coordinates.drawGround({size:10000});}if (gridX) {Coordinates.drawGrid({size:10000,scale:0.01});}if (gridY) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"});}if (gridZ) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"});}if (axes) {Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50});}}function animate() {window.requestAnimationFrame(animate);render();}function render() {var delta = clock.getDelta();cameraControls.update(delta);if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes){gridX = effectController.newGridX;gridY = effectController.newGridY;gridZ = effectController.newGridZ;ground = effectController.newGround;axes = effectController.newAxes;fillScene();}      // UNCOMMENT FOLLOWING LINES TO ENABLE CONTROLS FOR BODY:  // body.rotation.y = effectController.by * Math.PI/180;// yawarm.rotation.y = effectController.uy * Math.PI/180;// yawarm.rotation.z = effectController.uz * Math.PI/180;// rollforearm.rotation.y = effectController.fy * Math.PI/180;// yawforearm.rotation.z = effectController.fz * Math.PI/180;// rollrenderer.render(scene, camera);}function setupGui() {effectController = {newGridX: gridX,newGridY: gridY,newGridZ: gridZ,newGround: ground,newAxes: axes,        // UNCOMMENT FOLLOWING LINE TO SET DEFAULT VALUE OF CONTROLS FOR BODY:// by: 0.0,uy: 70.0,uz: -15.0,fy: 10.0,fz: 60.0};var gui = new dat.GUI();var h = gui.addFolder("Grid display");h.add( effectController, "newGridX").name("Show XZ grid");h.add( effectController, "newGridY" ).name("Show YZ grid");h.add( effectController, "newGridZ" ).name("Show XY grid");h.add( effectController, "newGround" ).name("Show ground");h.add( effectController, "newAxes" ).name("Show axes");h = gui.addFolder("Arm angles");// student, uncomment: h.add(effectController, "by", -180.0, 180.0, 0.025).name("Body y");h.add(effectController, "uy", -180.0, 180.0, 0.025).name("Upper arm y");h.add(effectController, "uz", -45.0, 45.0, 0.025).name("Upper arm z");h.add(effectController, "fy", -180.0, 180.0, 0.025).name("Forearm y");h.add(effectController, "fz", -120.0, 120.0, 0.025).name("Forearm z");}init();fillScene();drawHelpers();addToDOM();setupGui();animate();



2.添加机器人手指

首先参照leftHand的创建方式创建rightHand,然后在render()方法中添加对手指的控制。

/////////////////////////////////////////////////////////////////////////////////*global THREE, Coordinates, $, document, window, dat*/var camera, scene, renderer;var cameraControls, effectController;var clock = new THREE.Clock();var gridX = true;var gridY = false;var gridZ = false;var axes = true;var ground = true;var arm, forearm, body, handLeft, handRight;function fillScene() {scene = new THREE.Scene();scene.fog = new THREE.Fog( 0x808080, 2000, 4000 );// LIGHTSvar ambientLight = new THREE.AmbientLight( 0x222222 );var light = new THREE.DirectionalLight( 0xffffff, 1.0 );light.position.set( 200, 400, 500 );var light2 = new THREE.DirectionalLight( 0xffffff, 1.0 );light2.position.set( -500, 250, -200 );scene.add(ambientLight);scene.add(light);scene.add(light2);    // Robot definitionsvar robotHandLeftMaterial = new THREE.MeshPhongMaterial( { color: 0xCC3399, specular: 0xCC3399, shininess: 20 } );var robotHandRightMaterial = new THREE.MeshPhongMaterial( { color: 0xDD3388, specular: 0xDD3388, shininess: 20 } );var robotBaseMaterial = new THREE.MeshPhongMaterial( { color: 0x6E23BB, specular: 0x6E23BB, shininess: 20 } );var robotForearmMaterial = new THREE.MeshPhongMaterial( { color: 0xF4C154, specular: 0xF4C154, shininess: 100 } );var robotUpperArmMaterial = new THREE.MeshPhongMaterial( { color: 0x95E4FB, specular: 0x95E4FB, shininess: 100 } );var torus = new THREE.Mesh( new THREE.TorusGeometry( 22, 15, 32, 32 ), robotBaseMaterial );torus.rotation.x = 90 * Math.PI/180;scene.add( torus );forearm = new THREE.Object3D();var faLength = 80;createRobotExtender( forearm, faLength, robotForearmMaterial );arm = new THREE.Object3D();var uaLength = 120;createRobotCrane( arm, uaLength, robotUpperArmMaterial );// Move the forearm itself to the end of the upper arm.forearm.position.y = uaLength;arm.add( forearm );scene.add( arm );var handLength = 38;handLeft = new THREE.Object3D();createRobotGrabber( handLeft, handLength, robotHandLeftMaterial );// Move the hand part to the end of the forearm.handLeft.position.y = faLength;forearm.add( handLeft );      // YOUR CODE HERE// Add the second grabber handRight. Note that it uses a different color, defined above     handRight= new THREE.Object3D();createRobotGrabber( handRight, handLength, robotHandRightMaterial );// Move the hand part to the end of the forearm.handRight.position.y = faLength;forearm.add( handRight );    // ALSO EDIT render() TO ENABLE CONTROLS FOR GRABBER}function createRobotGrabber( part, length, material ){var box = new THREE.Mesh( new THREE.CubeGeometry( 30, length, 4 ), material );box.position.y = length/2;part.add( box );}function createRobotExtender( part, length, material ){var cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 22, 22, 6, 32 ), material );part.add( cylinder );var i;for ( i = 0; i < 4; i++ ){var box = new THREE.Mesh( new THREE.CubeGeometry( 4, length, 4 ), material );box.position.x = (i < 2) ? -8 : 8;box.position.y = length/2;box.position.z = (i%2) ? -8 : 8;part.add( box );}cylinder = new THREE.Mesh( new THREE.CylinderGeometry( 15, 15, 40, 32 ), material );cylinder.rotation.x = 90 * Math.PI/180;cylinder.position.y = length;part.add( cylinder );}function createRobotCrane( part, length, material ){var box = new THREE.Mesh( new THREE.CubeGeometry( 18, length, 18 ), material );box.position.y = length/2;part.add( box );var sphere = new THREE.Mesh( new THREE.SphereGeometry( 20, 32, 16 ), material );// place sphere at end of armsphere.position.y = length;part.add( sphere );}function init() {var canvasWidth = 846;var canvasHeight = 494;var canvasRatio = canvasWidth / canvasHeight;// RENDERERrenderer = new THREE.WebGLRenderer( { antialias: true } );renderer.gammaInput = true;renderer.gammaOutput = true;renderer.setSize(canvasWidth, canvasHeight);renderer.setClearColorHex( 0xAAAAAA, 1.0 );// CAMERAcamera = new THREE.PerspectiveCamera( 38, canvasRatio, 1, 10000 );// CONTROLScameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);camera.position.set(-49, 242,54);cameraControls.target.set(54, 106, 33);fillScene();}function addToDOM() {    var container = document.getElementById('container');    var canvas = container.getElementsByTagName('canvas');    if (canvas.length>0) {        container.removeChild(canvas[0]);    }    container.appendChild( renderer.domElement );}function drawHelpers() {    if (ground) {Coordinates.drawGround({size:10000});}if (gridX) {Coordinates.drawGrid({size:10000,scale:0.01});}if (gridY) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"});}if (gridZ) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"});}if (axes) {Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50});}}function animate() {window.requestAnimationFrame(animate);render();}function render() {var delta = clock.getDelta();cameraControls.update(delta);if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes){gridX = effectController.newGridX;gridY = effectController.newGridY;gridZ = effectController.newGridZ;ground = effectController.newGround;axes = effectController.newAxes;fillScene();}  arm.rotation.y = effectController.uy * Math.PI/180;// yawarm.rotation.z = effectController.uz * Math.PI/180;// rollforearm.rotation.y = effectController.fy * Math.PI/180;// yawforearm.rotation.z = effectController.fz * Math.PI/180;// roll    // ADD handRight yaw AND translate HERE    handLeft.rotation.z = effectController.hz * Math.PI/180;// yawhandLeft.position.z = effectController.htz;// translate        handRight.rotation.z = effectController.hz * Math.PI/180;    handRight.position.z = -effectController.htz;renderer.render(scene, camera);}function setupGui() {effectController = {newGridX: gridX,newGridY: gridY,newGridZ: gridZ,newGround: ground,newAxes: axes,uy: 70.0,uz: -15.0,fy: 10.0,fz: 60.0,                hz: 30.0,htz: 12.0};var gui = new dat.GUI();var h = gui.addFolder("Grid display");h.add( effectController, "newGridX").name("Show XZ grid");h.add( effectController, "newGridY" ).name("Show YZ grid");h.add( effectController, "newGridZ" ).name("Show XY grid");h.add( effectController, "newGround" ).name("Show ground");h.add( effectController, "newAxes" ).name("Show axes");h = gui.addFolder("Arm angles");h.add(effectController, "uy", -180.0, 180.0, 0.025).name("Upper arm y");h.add(effectController, "uz", -45.0, 45.0, 0.025).name("Upper arm z");h.add(effectController, "fy", -180.0, 180.0, 0.025).name("Forearm y");h.add(effectController, "fz", -120.0, 120.0, 0.025).name("Forearm z");    h.add(effectController, "hz", -45.0, 45.0, 0.025).name("Hand z");h.add(effectController, "htz", 2.0, 17.0, 0.025).name("Hand spread");}init();fillScene();drawHelpers();addToDOM();setupGui();animate();



3.画一朵花

这里给出了花的柄,要求画出24朵花瓣。

花瓣的绘制方法已经给出,通过循环变换就可以绘制出来,注意变换的顺序。

////////////////////////////////////////////////////////////////////////////////// Make a Flower/////////////////////////////////////////////////////////////////////////////////*global THREE, Coordinates, document, window, dat*/var camera, scene, renderer;var cameraControls, effectController;var clock = new THREE.Clock();var gridX = true;var gridY = false;var gridZ = false;var axes = true;var ground = true;function fillScene() {scene = new THREE.Scene();scene.fog = new THREE.Fog( 0x808080, 2000, 4000 );// LIGHTSvar ambientLight = new THREE.AmbientLight( 0x222222 );var light = new THREE.DirectionalLight( 0xffffff, 1.0 );light.position.set( 200, 400, 500 );var light2 = new THREE.DirectionalLight( 0xffffff, 1.0 );light2.position.set( -500, 250, -200 );scene.add(ambientLight);scene.add(light);scene.add(light2);    // FLOWER    var petalMaterial = new THREE.MeshLambertMaterial( { color: 0xCC5920 } );var flowerHeight = 200;var petalLength = 120;var cylGeom = new THREE.CylinderGeometry( 15, 0, petalLength, 32 );var flower = new THREE.Object3D();        /////////    // YOUR CODE HERE// add code here to make 24 petals, radiating around the sphere    for (var i=0;i<24;i++)    {    var cylinder = new THREE.Mesh( cylGeom, petalMaterial );                cylinder.rotation.x = 90*Math.PI/180;        cylinder.position.z = petalLength/2;        var petal = new THREE.Object3D();        petal.position.y = flowerHeight;         petal.rotation.y = i*15*Math.PI/180;        petal.add( cylinder );        flower.add( petal );    }    var stamenMaterial = new THREE.MeshLambertMaterial( { color: 0x333310 } );var stamen = new THREE.Mesh( new THREE.SphereGeometry( 20, 32, 16 ), stamenMaterial );stamen.position.y = flowerHeight;// move to flower centerflower.add( stamen );var stemMaterial = new THREE.MeshLambertMaterial( { color: 0x339424 } );var stem = new THREE.Mesh( new THREE.CylinderGeometry( 10, 10, flowerHeight, 32 ), stemMaterial );stem.position.y = flowerHeight/2;// move from ground to stamenflower.add( stem );scene.add( flower );}function init() {var canvasWidth = 846; var canvasHeight = 494;var canvasRatio = canvasWidth / canvasHeight;// RENDERERrenderer = new THREE.WebGLRenderer( { antialias: false } );renderer.gammaInput = true;renderer.gammaOutput = true;renderer.setSize(canvasWidth, canvasHeight);renderer.setClearColorHex( 0xAAAAAA, 1.0 );// CAMERAcamera = new THREE.PerspectiveCamera( 38, canvasRatio, 1, 10000 );// CONTROLScameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);camera.position.set(-200, 400, 20);cameraControls.target.set(0,150,0);fillScene();}function addToDOM() {    var container = document.getElementById('container');    var canvas = container.getElementsByTagName('canvas');    if (canvas.length>0) {        container.removeChild(canvas[0]);    }    container.appendChild( renderer.domElement );}function drawHelpers() {  if (ground) {Coordinates.drawGround({size:10000});}if (gridX) {Coordinates.drawGrid({size:10000,scale:0.01});}if (gridY) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"});}if (gridZ) {Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"});}if (axes) {Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50});}}function animate() {window.requestAnimationFrame(animate);render();}function render() {var delta = clock.getDelta();cameraControls.update(delta);if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes){gridX = effectController.newGridX;gridY = effectController.newGridY;gridZ = effectController.newGridZ;ground = effectController.newGround;axes = effectController.newAxes;fillScene();}renderer.render(scene, camera);}function setupGui() {effectController = {newGridX: gridX,newGridY: gridY,newGridZ: gridZ,newGround: ground,newAxes: axes};var gui = new dat.GUI();var h = gui.addFolder("Grid display");h.add( effectController, "newGridX").name("Show XZ grid");h.add( effectController, "newGridY" ).name("Show YZ grid");h.add( effectController, "newGridZ" ).name("Show XY grid");h.add( effectController, "newGround" ).name("Show ground");h.add( effectController, "newAxes" ).name("Show axes");}// this is the main action sequenceinit();fillScene();drawHelpers();addToDOM();setupGui();animate();



4.压扁的花

在上一个程序上的改进,然它看起来更棒一些。
对花瓣继续进行处理,压扁,并且产生一些倾角。最终效果如下:


关键代码

    

 for (var i=0;i<24;i++)    {    var cylinder = new THREE.Mesh( cylGeom, petalMaterial );       // cylinder.position.y = petalHeight;        cylinder.scale.z = 0.25;        cylinder.rotation.x = 90*Math.PI/180;        //cylinder.rotation.x = -20*Math.PI/180;        cylinder.position.z = petalLength/2;        var petal = new THREE.Object3D();                petal.add( cylinder );        petal.rotation.x = -20*Math.PI/180;        var tmpObject = new THREE.Object3D();        tmpObject.add( petal);        tmpObject.rotation.y = i*15*Math.PI/180;        tmpObject.position.y = flowerHeight;                         flower.add( tmpObject );    }