Interactive 3D Graphics-Lesson2 Problem Set

来源:互联网 发布:天皇电影知乎 编辑:程序博客网 时间:2024/06/05 23:55

Interactive 3D Graphics是Udacity上的一门图形学公开课(需要翻墙),最近在学习,在这里记录一下课程的学习进度和作业的答案。


多边形的三角形划分

由于在图形学中,面的表示通常是用三角形来表示,所以要显示多边形的时候,就要将其碎片化。

////////////////////////////////////////////////////////////////////////////////// Polygon Creation Exercise// Your task is to complete the function PolygonGeometry(sides)// which takes 1 argument://   sides - how many edges the polygon has.// Return the mesh that defines the minimum number of triangles necessary// to draw the polygon.// Radius of the polygon is 1. Center of the polygon is at 0, 0./////////////////////////////////////////////////////////////////////////////////*global, THREE, Coordinates, $, document, window*/var camera, scene, renderer;var windowScale;function PolygonGeometry(sides) {var geo = new THREE.Geometry();// generate verticesfor ( var pt = 0 ; pt < sides; pt++ ){// Add 90 degrees so we start at +Y axis, rotate counterclockwise aroundvar angle = (Math.PI/2) + (pt / sides) * 2 * Math.PI;var x = Math.cos( angle );var y = Math.sin( angle );// YOUR CODE HERE        //Save the vertex location - fill in the code        geo.vertices.push(new THREE.Vector3(x,y,0));}    // YOUR CODE HERE// Write the code to generate minimum number of faces for the polygon.    for ( var fc = 0 ; fc < sides-1; fc++ ){    geo.faces.push( new THREE.Face3( 0, fc, fc+1) );    }// Return the geometry objectreturn geo;}function init() {//  Setting up some parametersvar canvasWidth = 846;var canvasHeight = 494;var canvasRatio = canvasWidth / canvasHeight;// scenescene = new THREE.Scene();// Camera: Y up, X right, Z upwindowScale = 4;var windowWidth = windowScale * canvasRatio;var windowHeight = windowScale;camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, windowHeight / 2, windowHeight / - 2, 0, 40 );var focus = new THREE.Vector3( 0,1,0 );camera.position.x = focus.x;camera.position.y = focus.y;camera.position.z = 10;camera.lookAt(focus);renderer = new THREE.WebGLRenderer({ antialias: false, preserveDrawingBuffer: true});renderer.gammaInput = true;renderer.gammaOutput = true;renderer.setSize( canvasWidth, canvasHeight );renderer.setClearColorHex( 0xffffff, 1.0 );}function showGrids() {  // Background grid and axes. Grid step size is 1, axes cross at 0, 0Coordinates.drawGrid({size:100,scale:1,orientation:"z"});Coordinates.drawAxes({axisLength:4,axisOrientation:"x",axisRadius:0.02});Coordinates.drawAxes({axisLength:3,axisOrientation:"y",axisRadius:0.02});}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 render() {renderer.render( scene, camera );}// Main body of the scriptinit();showGrids();addToDOM();var geo = PolygonGeometry(5);var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.FrontSide } );var mesh = new THREE.Mesh( geo, material );scene.add( mesh );render();

运行结果:




在制定位置绘制制定半径的多边形

原先的函数变成了PolygonGeometry(sides,radius, location),只要在生成vertex的时候对坐标进行相应的变换就可已了。

////////////////////////////////////////////////////////////////////////////////// Polygon Radius Exercise// Your task is to write a function that will take 3 arguments://   sides - how many edges the polygon has.//   location - location of the center of the polygon as a THREE.Vector3.//   radius - radius of the polygon.// Return the mesh that defines the minimum number of triangles necessary// to draw the polygon./////////////////////////////////////////////////////////////////////////////////*global, THREE, Coordinates, $, document, window*/var camera, scene, renderer;var windowScale;function PolygonGeometry(sides, location, radius) {var geo = new THREE.Geometry();// generate verticesfor ( var pt = 0 ; pt < sides; pt++ ){// Add 90 degrees so we start at +Y axis, rotate counterclockwise aroundvar angle = (Math.PI/2) + (pt / sides) * 2 * Math.PI;var x = radius*Math.cos(angle) + location.x;var y = radius*Math.sin(angle) + location.y;// Save the vertex locationgeo.vertices.push( new THREE.Vector3( x, y, 0.0 ) );}// generate facesfor ( var face = 0 ; face < sides-2; face++ ){// this makes a triangle fan, from the first +Y point aroundgeo.faces.push( new THREE.Face3( 0, face+1, face+2 ) );}// done: return it.return geo;}function init() {//  Setting up some parametersvar canvasWidth = 846;var canvasHeight = 494;var canvasRatio = canvasWidth / canvasHeight;// scenescene = new THREE.Scene();// Camera: Y up, X right, Z upwindowScale = 12;var windowWidth = windowScale * canvasRatio;var windowHeight = windowScale;camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, windowHeight / 2, windowHeight / - 2, 0, 40 );var focus = new THREE.Vector3( 5,5,0 );camera.position.x = focus.x;camera.position.y = focus.y;camera.position.z = 10;camera.lookAt(focus);renderer = new THREE.WebGLRenderer({ antialias: false, preserveDrawingBuffer: true});renderer.gammaInput = true;renderer.gammaOutput = true;renderer.setSize(canvasWidth, canvasHeight);renderer.setClearColorHex( 0xffffff, 1.0 );}function showGrids() {  // Background grid and axes. Grid step size is 1, axes cross at 0, 0Coordinates.drawGrid({size:100,scale:1,orientation:"z"});Coordinates.drawAxes({axisLength:4,axisOrientation:"x",axisRadius:0.02});Coordinates.drawAxes({axisLength:3,axisOrientation:"y",axisRadius:0.02});}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 render() {renderer.render( scene, camera );}// Main body of the scriptinit();showGrids();addToDOM();var geo = PolygonGeometry(9, new THREE.Vector3( 5, 5, 0 ), 4);var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.FrontSide } );var mesh = new THREE.Mesh( geo, material );scene.add( mesh );render();




建造楼梯

搭建一个楼梯,最终获得奖杯。

////////////////////////////////////////////////////////////////////////////////// Staircase exercise                                                         //// Your task is to complete the model for simple stairs                       //// Using the provided sizes and colors, complete the staircase                //// and reach the Gold Cup!                                                    ///////////////////////////////////////////////////////////////////////////////////*global, THREE, Coordinates, $, document, window, dat*/var camera, scene, renderer;var cameraControls, effectController;var clock = new THREE.Clock();var gridX = false;var gridY = false;var gridZ = false;var axes = false;var ground = true;function createStairs() {// MATERIALSvar stepMaterialVertical = new THREE.MeshLambertMaterial( { color: 0xA85F35 } );var stepMaterialHorizontal = new THREE.MeshLambertMaterial( { color: 0xBC7349 } );var stepWidth = 500;var stepSize = 200;var stepThickness = 50;// height from top of one step to bottom of next step upvar verticalStepHeight = stepSize;var horizontalStepDepth = stepSize*2;var stepHalfThickness = stepThickness/2;// +Y direction is up// Define the two pieces of the step, vertical and horizontal// THREE.CubeGeometry takes (width, height, depth)var stepVertical = new THREE.CubeGeometry(stepWidth, verticalStepHeight, stepThickness);var stepHorizontal = new THREE.CubeGeometry(stepWidth, stepThickness, horizontalStepDepth);var stepMesh;     for( var i=0;i<6;i++ )    {        stepMesh = new THREE.Mesh( stepVertical, stepMaterialVertical );// The position is where the center of the block will be put.// You can define position as THREE.Vector3(x, y, z) or in the following way:        stepMesh.position.x = 0;// centered at origin        stepMesh.position.y = i*verticalStepHeight+verticalStepHeight/2+i*stepThickness;// half of height: put it above ground plane        stepMesh.position.z = i*horizontalStepDepth-i*stepThickness;// centered at origin        scene.add( stepMesh );    }// Make and position the horizontal part     for( var i=0;i<6;i++ )    {        stepMesh = new THREE.Mesh( stepHorizontal, stepMaterialHorizontal );        stepMesh.position.x = 0;        // Push up by half of horizontal step's height, plus vertical step's height        stepMesh.position.y = i*stepThickness + (i+1)*verticalStepHeight+stepHalfThickness;        // Push step forward by half the depth, minus half the vertical step's thickness        stepMesh.position.z = i*horizontalStepDepth+horizontalStepDepth/2 -  i*stepThickness-stepHalfThickness;        scene.add( stepMesh );    }}function createCup() {var cupMaterial = new THREE.MeshLambertMaterial( { color: 0xFDD017});// THREE.CylinderGeometry takes (radiusTop, radiusBottom, height, segmentsRadius)var cupGeo = new THREE.CylinderGeometry( 200, 50, 400, 32 );var cup = new THREE.Mesh( cupGeo, cupMaterial );cup.position.x = 0;cup.position.y = 1725;cup.position.z = 1925;scene.add( cup );cupGeo = new THREE.CylinderGeometry( 100, 100, 50, 32 );cup = new THREE.Mesh( cupGeo, cupMaterial );cup.position.x = 0;cup.position.y = 1525;cup.position.z = 1925;scene.add( cup );}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( 45, canvasRatio, 1, 40000 );camera.position.set( -700, 500, -1600 );// CONTROLScameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);cameraControls.target.set(0,600,0);// Camera(2) for testing has following values:// camera.position.set( 1225, 2113, 1814 );// cameraControls.target.set(-1800,180,630);  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 fillScene() {// SCENEscene = new THREE.Scene();scene.fog = new THREE.Fog( 0x808080, 3000, 6000 );// 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( -400, 200, -300 );scene.add(ambientLight);scene.add(light);scene.add(light2);scene.add(camera);if (ground) {Coordinates.drawGround({size:1000});}if (gridX) {Coordinates.drawGrid({size:1000,scale:0.01});}if (gridY) {Coordinates.drawGrid({size:1000,scale:0.01, orientation:"y"});}if (gridZ) {Coordinates.drawGrid({size:1000,scale:0.01, orientation:"z"});}if (axes) {Coordinates.drawAllAxes({axisLength:300,axisRadius:2,axisTess:50});}createCup();var stairs = createStairs();scene.add(stairs);}//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,dummy: function() {}};var gui = new dat.GUI();gui.add(effectController, "newGridX").name("Show XZ grid");gui.add( effectController, "newGridY" ).name("Show YZ grid");gui.add( effectController, "newGridZ" ).name("Show XY grid");gui.add( effectController, "newGround" ).name("Show ground");gui.add( effectController, "newAxes" ).name("Show axes");}init();addToDOM();setupGui();animate();



空间建模

第三题十一个三维建模的题目,需要一些空间想象。

和3dmax的建模类似,在max中建模是交互的,但这里是需要代码来实现。

主要用到了三个函数来创建空间物体:

//Create boxboxGeometry = New THREE.CubeGeometry(float width,float,height,float depth);//Create spheresphereGeometry = New THREE.SphereGeometry(float radius,int segsWidth,int segsHeight);// Create cylindercylinderGeometry = New THREE.CylinderGeometry(float radius1,float radius1,int height,int segs);

平面图如下:




代码如下

////////////////////////////////////////////////////////////////////////////////// Drinking Bird Model exercise                                               //// Your task is to complete the model for the drinking bird                   //// The following forms and sizes should be used:                              //// Hat: cylinder. color blue (cylinderMaterial)                               ////      Diameter top 80, bottom, full height 80, edge 10                      //// Head: sphere, red (sphereMaterial), diameter 104                           //// Middle of base: cube, color orange (cubeMaterial), width 77, length 194     //// Feet: cube, color orange, width 6, length 194, height 52                    //// Legs: cube, color orange, width 6, length 64, height 386                    //// Body: sphere, red, diameter 116                                            //// Spine: cylinder, blue, diameter 24, length 390                             ///////////////////////////////////////////////////////////////////////////////////*global, THREE, Coordinates, $, document, window, dat*/var camera, scene, renderer;var cameraControls, effectController;var clock = new THREE.Clock();var gridX = false;var gridY = false;var gridZ = false;var axes = false;var ground = true;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( 45, canvasRatio, 1, 40000 );// CONTROLScameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);camera.position.set( -480, 659, -619 );cameraControls.target.set(4,301,92);fillScene();}// Supporting frame for the bird - base + legs + feetfunction createSupport() {   var cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xF07020 } );// basevar cube;cube = new THREE.Mesh( new THREE.CubeGeometry( 20+64+110, 4, 2*77 ), cubeMaterial );cube.position.x = -45;// (20+32) - half of width (20+64+110)/2cube.position.y = 4/2;// half of heightcube.position.z = 0;// centered at originscene.add( cube );// left footcube = new THREE.Mesh( new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial );cube.position.x = -45;// (20+32) - half of width (20+64+110)/2cube.position.y = 52/2;// half of heightcube.position.z = 77 + 6/2;// offset 77 + half of depth 6/2scene.add( cube );// left legcube = new THREE.Mesh( new THREE.CubeGeometry( 64, 334+52, 6 ), cubeMaterial );cube.position.x = 0;// centered on origin along Xcube.position.y = (334+52)/2;cube.position.z = 77 + 6/2;// offset 77 + half of depth 6/2scene.add( cube );// right footcube = new THREE.Mesh( new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial );cube.position.x = -45;// (20+32) - half of width (20+64+110)/2cube.position.y = 52/2;// half of heightcube.position.z = -77 + -6/2;// offset 77 + half of depth 6/2scene.add( cube );// right leg    cube = new THREE.Mesh( new THREE.CubeGeometry( 64, 334+52, 6 ), cubeMaterial );cube.position.x = 0;// centered on origin along Xcube.position.y = (334+52)/2;cube.position.z = -77 + -6/2;// offset 77 + half of depth 6/2scene.add( cube );}// Body of the bird - body and the connector of body and headfunction createBody() {   var sphereMaterial = new THREE.MeshLambertMaterial( { color: 0xA00000 } );   var cylinderMaterial = new THREE.MeshLambertMaterial( { color: 0x0000D0 } );        //Create two balls    var sphere;   sphere = new THREE.Mesh( new THREE.SphereGeometry( 116/2, 32, 16 ), sphereMaterial );sphere.position.x = 0;sphere.position.y = 160;sphere.position.z = 0;scene.add( sphere );        sphere = new THREE.Mesh( new THREE.SphereGeometry( 104/2, 32, 16 ), sphereMaterial );sphere.position.x = 0;sphere.position.y = 390+160;sphere.position.z = 0;scene.add( sphere );        //Create a stick    var cylinder;    cylinder=new THREE.Mesh(new THREE.CylinderGeometry( 12, 12, 390, 32 ), cylinderMaterial);    cylinder.position.x = 0;cylinder.position.y = 160+390/2;cylinder.position.z = 0;scene.add( cylinder );}// Head of the bird - head + hatfunction createHead() {   var sphereMaterial = new THREE.MeshLambertMaterial( { color: 0xA00000 } );   var cylinderMaterial = new THREE.MeshLambertMaterial( { color: 0x0000D0 } );    //Create cap   var cylinder;    cylinder=new THREE.Mesh(new THREE.CylinderGeometry( 142/2, 142/2, 10, 32 ), cylinderMaterial);    cylinder.position.x = 0;cylinder.position.y = 160+390+40+5;cylinder.position.z = 0;scene.add( cylinder );        cylinder=new THREE.Mesh(new THREE.CylinderGeometry( 80/2, 80/2, 70, 32 ), cylinderMaterial);    cylinder.position.x = 0;cylinder.position.y = 160+390+40+10+70/2;cylinder.position.z = 0;scene.add( cylinder );}function createDrinkingBird() {// MODELS// base + legs + feetcreateSupport();// body + body/head connectorcreateBody();// head + hatcreateHead();}function fillScene() {// SCENEscene = new THREE.Scene();scene.fog = new THREE.Fog( 0x808080, 3000, 6000 );// 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( -400, 200, -300 );scene.add(ambientLight);scene.add(light);scene.add(light2);scene.add(camera);if (ground) {Coordinates.drawGround({size:1000});}if (gridX) {Coordinates.drawGrid({size:1000,scale:0.01});}if (gridY) {Coordinates.drawGrid({size:1000,scale:0.01, orientation:"y"});}if (gridZ) {Coordinates.drawGrid({size:1000,scale:0.01, orientation:"z"});}if (axes) {Coordinates.drawAllAxes({axisLength:300,axisRadius:2,axisTess:50});}createDrinkingBird();}//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 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,dummy: function() {}};var gui = new dat.GUI();gui.add(effectController, "newGridX").name("Show XZ grid");gui.add( effectController, "newGridY" ).name("Show YZ grid");gui.add( effectController, "newGridZ" ).name("Show XY grid");gui.add( effectController, "newGround" ).name("Show ground");gui.add( effectController, "newAxes" ).name("Show axes");}init();addToDOM();setupGui();animate();

运行效果:



原创粉丝点击