threejs几何三角形旋转不居中

时间:2019-04-12 19:53:51

标签: javascript three.js

我已经尝试了一段时间,但是我不知道为什么我的三角形没有绕中心旋转。我想要2个三角形彼此相邻并且1个旋转60度。但是如果我旋转的话,所有的角都应该是相同的大小。

下面您可以找到我的代码段。蓝色三角形怎么可能向左移动?因为橙色的右上方大于其他两个...

<!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>

1 个答案:

答案 0 :(得分:0)

Circumscribed circle的中心或Equilateral triangle的中心不是边界框的中心:

等边三角形,其中(0,0)是外接圆的中心是:

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注意,.center()的功能THREE.BufferGeometry

  

根据边界框将几何体居中。

您必须将其删除:

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

当然,三角形不是位于框的中心,而是围绕外接圆的中心旋转。但这可以通过将三角形沿y轴移动-h/6来补偿:

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

请参见示例。

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>