简体   繁体   中英

threejs geometry triangle rotate not centered

I have been trying for a while, but I can't figure out why my triangle is not rotating around the center. I want 2 triangles next to each other and 1 rotated for 60 degrees. But somehow if I rotate, all corners should be the same size.

Below you can find my code snippet. How is it possible the blue triangle moves to the left? Because the orange right top is bigger than the other 2...

 <!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - geometries</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { color: #eee; font-family:Monospace; font-size:13px; text-align:center; background-color: #ffffff; margin: 0px; padding: 0px; overflow: hidden; } #info { position: absolute; top: 0px; width: 100%; padding: 5px; } a { color: #0080ff; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.js"></script> <script> var SCREEN_WIDTH = window.innerWidth; var SCREEN_HEIGHT = window.innerHeight; var aspect = SCREEN_WIDTH / SCREEN_HEIGHT; var camera, scene, renderer, stats; var frustumSize = 100000; function init() { camera = new THREE.OrthographicCamera( 0.5 * frustumSize * aspect / - 2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, -1000, 10000 ); camera.position.y = 400; scene = new THREE.Scene(); scene.background = new THREE.Color( 0xf0f0f0 ); camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set( 0, 0, 2 ); camera.lookAt(0, 0, 0) scene.add( camera ); var light = new THREE.PointLight( 0xffffff, 0.8 ); camera.add( light ); drawSquare() var margin = 0.2; var t = new triangle(0.5); t.draw(); t.createSides(margin); // renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // window.addEventListener( 'resize', onWindowResize, false ); } class triangle { constructor(length){ this.length = length; } draw(color='orange'){ var h = this.length * (Math.sqrt(3)/2); var shape = new THREE.Shape(); shape.moveTo( 0,-h/2 ); shape.lineTo( -this.length / 2, h / 2 ); shape.lineTo( this.length / 2, h / 2 ); var extrudeSettings = { steps: 2, depth: 0.4, bevelEnabled: false }; var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings ); geometry.center(); var line2 = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( {color: color} ) ); line2.position.set(0, 0, 0); scene.add(line2); this.mesh = line2; } createSides(margin){ for(var i = 0;i<3;i++){ var t = new triangle(this.length); t.draw('blue'); //t.mesh.position.x += this.length; t.mesh.geometry.rotateZ(THREE.Math.degToRad(60)); } } } function drawSquare(){ var size = 1; var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3(0, 0, 0), new THREE.Vector3(size, 0, 0), new THREE.Vector3(size, size, 0), new THREE.Vector3(0, size, 0), new THREE.Vector3(0, 0, 0)); var line2 = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: "red"})); line2.position.set(-size/2, -size/2, 0); scene.add(line2); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } // function animate() { requestAnimationFrame( animate ); render(); } function render() { renderer.render( scene, camera ); } init(); animate(); </script> </body> </html> 

The center or the center of the Circumscribed circle of an Equilateral triangle is not the center of the bounding box:

A Equilateral triangle where (0, 0) is the the center of the circumscribed circle is:

var l = this.length;
var h = l * Math.sqrt(3) / 2; // 0.866
shape.moveTo(  0,      h * 2/3 );
shape.lineTo( -l / 2, -h * 1/3 );
shape.lineTo(  l / 2, -h * 1/3 );

Furtner note that, the function .center() of THREE.BufferGeometry

Center the geometry based on the bounding box.

you have to remove it:

var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
geometry.center();

Of course the triangle is not centered to the box, but it roates around the center of the circumscribed circle. But this can be compensated by shifting the triangle along the y axis by -h/6 :

var line2 = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( {color: color} ) );
line2.position.set(0, -h / 6, 0);

See the example.

 var SCREEN_WIDTH = window.innerWidth; var SCREEN_HEIGHT = window.innerHeight; var aspect = SCREEN_WIDTH / SCREEN_HEIGHT; var camera, scene, renderer, stats; var frustumSize = 100000; var triangles = []; var rot = 0 function init() { camera = new THREE.OrthographicCamera( 0.5 * frustumSize * aspect / - 2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, -1000, 10000 ); camera.position.y = 400; scene = new THREE.Scene(); scene.background = new THREE.Color( 0xf0f0f0 ); camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set( 0, 0, 2 ); camera.lookAt(0, 0, 0) scene.add( camera ); var light = new THREE.PointLight( 0xffffff, 0.8 ); camera.add( light ); drawSquare(); drawCircle(1.0); var margin = 0.2; var t = new triangle(1.0); t.draw(); t.createSides(margin); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); } class triangle { constructor(length){ this.length = length; } draw(color='orange'){ var shape = new THREE.Shape(); var l = this.length; var h = l * Math.sqrt(3) / 2; // 0.866 shape.moveTo( 0, h * 2/3 ); shape.lineTo( -l / 2, -h * 1/3 ); shape.lineTo( l / 2, -h * 1/3 ); var extrudeSettings = { steps: 2, depth: 0.0, bevelEnabled: false }; var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings ); //geometry.center(); var triangle = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: color, polygonOffset: true, polygonOffsetFactor: 1.0, polygonOffsetUnits: 4.0 } ) ); triangle.position.set(0, -h / 6, 0); scene.add(triangle); this.mesh = triangle; } createSides(margin){ for(var i = 0;i<1;i++){ var t = new triangle(this.length); t.draw('blue'); //t.mesh.position.x += this.length; t.mesh.geometry.rotateZ(THREE.Math.degToRad(60)); triangles.push(t); } } } function drawSquare(){ var size = 1; var geometry1 = new THREE.Geometry(); geometry1.vertices.push( new THREE.Vector3(-size/2, -size/2, 0), new THREE.Vector3(size/2, -size/2, 0), new THREE.Vector3(size/2, size/2, 0), new THREE.Vector3(-size/2, size/2, 0)); var line1 = new THREE.LineLoop(geometry1, new THREE.LineBasicMaterial({color: "green"})); line1.position.set(0, 0, 0.0); scene.add(line1); var geometry2 = new THREE.Geometry(); geometry2.vertices.push( new THREE.Vector3(-size/2, -size/2, 0), new THREE.Vector3(size/2, size/2, 0), new THREE.Vector3(size/2, -size/2, 0), new THREE.Vector3(-size/2, size/2, 0)); var line2 = new THREE.LineSegments(geometry2, new THREE.LineBasicMaterial({color: "green"})); line2.position.set(0, 0, 0.0); scene.add(line2); } function drawCircle(l){ var h = l * 0.866; var geometry3 = new THREE.Geometry(); geometry3.vertices.push( new THREE.Vector3(0, 0), new THREE.Vector3(0, h * 2/3), new THREE.Vector3(0, 0), new THREE.Vector3(-l / 2, -h * 1/3), new THREE.Vector3(0, 0), new THREE.Vector3(l / 2, -h * 1/3)); var line3 = new THREE.LineSegments(geometry3, new THREE.LineBasicMaterial({color: "red"})); line3.position.set(0, -h/6, 0.0); scene.add(line3); var geometry4 = new THREE.CircleGeometry( h * 2/3, 128 ); geometry4.vertices.shift(); var line4 = new THREE.LineLoop( geometry4, new THREE.LineBasicMaterial( { color: "red" } ) ); line4.position.set(0, -h/6, 0.0); scene.add(line4); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { requestAnimationFrame( animate ); render(); } function render() { triangles[0].mesh.geometry.rotateZ(THREE.Math.degToRad(1)); rot += 1; renderer.render( scene, camera ); } init(); animate(); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM