Three.js: 无法使用 THREE.ExtrudeGeometry 打孔(切割)线形
Three.js: not able to punch(cut) line shape by using THREE.ExtrudeGeometry
大家好我是Three.js
的新手
我想用THREE.ExtrudeGeometry.
在素板上打孔(切割)一些形状
这是我的代码片段。
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 10;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var light = new THREE.PointLight(0xffffff, 2, 100);
light.position.z = 10;
scene.add(light);
let boardHeight = 100;
let boardWidth = 100;
const boardShape = new THREE.Shape();
boardShape.moveTo(0, 0);
boardShape.lineTo(0, boardHeight);
boardShape.lineTo(boardWidth, boardHeight);
boardShape.lineTo(boardWidth, 0);
boardShape.lineTo(0, 0);
var hole1 = new THREE.Path();
hole1.moveTo(20, 20);
hole1.lineTo(18, 20);
boardShape.holes.push(hole1);
hole1 = new THREE.Path();
hole1.moveTo(50, 50);
hole1.absarc(30, 50, 20, 0.0000, Math.PI*2, true);
boardShape.holes.push(hole1);
hole1 = new THREE.Path();
hole1.moveTo(25, 25);
hole1.lineTo(27, 25);
boardShape.holes.push(hole1);
var material = new THREE.MeshBasicMaterial( { color: 0x005E99 } );
const extrudeSettings = { depth: 1, bevelEnabled: false, bevelSegments: 1, steps: 1, bevelSize: 1, bevelThickness: 1, UVGenerator: THREE.ExtrudeGeometry.WorldUVGenerator };
const geometry = new THREE.ExtrudeGeometry(boardShape, extrudeSettings);
var cube = new THREE.Mesh( geometry, material );
geometry.scale(0.02, 0.02, 0.02);
cube.position.set(-boardWidth / 2 * 0.02, -boardHeight / 2 * 0.02, 0.02 * 0.5);
scene.add( cube );
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
//cube.rotation.x += 0.1;
//cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
// Rotate the mesh based on mouse position
document.body.onmousemove = function(e){
//cube.rotation.z = e.pageX / 100;
//cube.rotation.x = e.pageY / 100;
}
// Click to toggle wireframe mode
document.body.onclick = function(e){
cube.material.wireframe = !cube.material.wireframe;
}
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/build/three.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/examples/js/controls/OrbitControls.js"></script>
<script src="https://rawgit.com/Wilt/ThreeCSG/develop/ThreeCSG.js"></script>
<div id="container"></div>
我在给定的示例中添加了一个圆形和两条线形。
我可以为圆形打孔,但对于线形它不起作用。
我还附上了当前输出和预期输出的图像
当前输出:
预期输出:
您需要用路径描绘一个圆角矩形。
以直线(x1, y1) 和(x2, y2) 为端点的两个点,可以得到矩形对应的8个顶点作为路径:
const getPath = (x1, y1, x2, y2, thickness = 1, radius = 0) => {
const vector1 = new THREE.Vector2(x1, y1);
const vector2 = new THREE.Vector2(x2, y2);
const direction = vector2.clone().sub(vector1).normalize();
const angle = direction.angle();
const perpendicularDirection = direction.clone().rotateAround(new THREE.Vector2(0, 0), Math.PI / 2);
const path = new THREE.Path();
path.moveTo(...vector2.clone().addScaledVector(perpendicularDirection, thickness - radius).toArray());
if(radius > 0) {
path.arc(...direction.clone().multiplyScalar(-radius).toArray(), radius, angle, angle + Math.PI / 2);
}
path.lineTo(
...vector1.clone()
.addScaledVector(perpendicularDirection, thickness)
.addScaledVector(direction, radius)
.toArray()
);
if(radius > 0) {
path.arc(...perpendicularDirection.clone().multiplyScalar(-radius).toArray(), radius, angle + Math.PI / 2, angle + Math.PI);
}
path.lineTo(
...vector1.clone()
.addScaledVector(perpendicularDirection, -(thickness - radius))
.toArray()
);
if(radius > 0) {
path.arc(...direction.clone().multiplyScalar(radius).toArray(), radius, angle + Math.PI, angle + 1.5 * Math.PI);
}
path.lineTo(
...vector2.clone()
.addScaledVector(perpendicularDirection, -(thickness))
.addScaledVector(direction, -radius)
.toArray()
);
if(radius > 0) {
path.arc(...perpendicularDirection.clone().multiplyScalar(radius).toArray(), radius, angle + 1.5 * Math.PI, angle + 2 * Math.PI);
}
path.lineTo(...vector2.clone().addScaledVector(perpendicularDirection, thickness - radius).toArray());
return path;
};
因此
var hole1 = getPath(10, 200, 400, 300, 40, 20);
boardShape.holes.push(hole1);
大家好我是Three.js
的新手我想用THREE.ExtrudeGeometry.
在素板上打孔(切割)一些形状这是我的代码片段。
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 50, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 10;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var light = new THREE.PointLight(0xffffff, 2, 100);
light.position.z = 10;
scene.add(light);
let boardHeight = 100;
let boardWidth = 100;
const boardShape = new THREE.Shape();
boardShape.moveTo(0, 0);
boardShape.lineTo(0, boardHeight);
boardShape.lineTo(boardWidth, boardHeight);
boardShape.lineTo(boardWidth, 0);
boardShape.lineTo(0, 0);
var hole1 = new THREE.Path();
hole1.moveTo(20, 20);
hole1.lineTo(18, 20);
boardShape.holes.push(hole1);
hole1 = new THREE.Path();
hole1.moveTo(50, 50);
hole1.absarc(30, 50, 20, 0.0000, Math.PI*2, true);
boardShape.holes.push(hole1);
hole1 = new THREE.Path();
hole1.moveTo(25, 25);
hole1.lineTo(27, 25);
boardShape.holes.push(hole1);
var material = new THREE.MeshBasicMaterial( { color: 0x005E99 } );
const extrudeSettings = { depth: 1, bevelEnabled: false, bevelSegments: 1, steps: 1, bevelSize: 1, bevelThickness: 1, UVGenerator: THREE.ExtrudeGeometry.WorldUVGenerator };
const geometry = new THREE.ExtrudeGeometry(boardShape, extrudeSettings);
var cube = new THREE.Mesh( geometry, material );
geometry.scale(0.02, 0.02, 0.02);
cube.position.set(-boardWidth / 2 * 0.02, -boardHeight / 2 * 0.02, 0.02 * 0.5);
scene.add( cube );
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
//cube.rotation.x += 0.1;
//cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
// Rotate the mesh based on mouse position
document.body.onmousemove = function(e){
//cube.rotation.z = e.pageX / 100;
//cube.rotation.x = e.pageY / 100;
}
// Click to toggle wireframe mode
document.body.onclick = function(e){
cube.material.wireframe = !cube.material.wireframe;
}
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/build/three.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r124/examples/js/controls/OrbitControls.js"></script>
<script src="https://rawgit.com/Wilt/ThreeCSG/develop/ThreeCSG.js"></script>
<div id="container"></div>
我在给定的示例中添加了一个圆形和两条线形。
我可以为圆形打孔,但对于线形它不起作用。
我还附上了当前输出和预期输出的图像
当前输出:
预期输出:
您需要用路径描绘一个圆角矩形。 以直线(x1, y1) 和(x2, y2) 为端点的两个点,可以得到矩形对应的8个顶点作为路径:
const getPath = (x1, y1, x2, y2, thickness = 1, radius = 0) => {
const vector1 = new THREE.Vector2(x1, y1);
const vector2 = new THREE.Vector2(x2, y2);
const direction = vector2.clone().sub(vector1).normalize();
const angle = direction.angle();
const perpendicularDirection = direction.clone().rotateAround(new THREE.Vector2(0, 0), Math.PI / 2);
const path = new THREE.Path();
path.moveTo(...vector2.clone().addScaledVector(perpendicularDirection, thickness - radius).toArray());
if(radius > 0) {
path.arc(...direction.clone().multiplyScalar(-radius).toArray(), radius, angle, angle + Math.PI / 2);
}
path.lineTo(
...vector1.clone()
.addScaledVector(perpendicularDirection, thickness)
.addScaledVector(direction, radius)
.toArray()
);
if(radius > 0) {
path.arc(...perpendicularDirection.clone().multiplyScalar(-radius).toArray(), radius, angle + Math.PI / 2, angle + Math.PI);
}
path.lineTo(
...vector1.clone()
.addScaledVector(perpendicularDirection, -(thickness - radius))
.toArray()
);
if(radius > 0) {
path.arc(...direction.clone().multiplyScalar(radius).toArray(), radius, angle + Math.PI, angle + 1.5 * Math.PI);
}
path.lineTo(
...vector2.clone()
.addScaledVector(perpendicularDirection, -(thickness))
.addScaledVector(direction, -radius)
.toArray()
);
if(radius > 0) {
path.arc(...perpendicularDirection.clone().multiplyScalar(radius).toArray(), radius, angle + 1.5 * Math.PI, angle + 2 * Math.PI);
}
path.lineTo(...vector2.clone().addScaledVector(perpendicularDirection, thickness - radius).toArray());
return path;
};
因此
var hole1 = getPath(10, 200, 400, 300, 40, 20);
boardShape.holes.push(hole1);