如何将 THREE.CatmullRomCurve3 转换为网格?
How Can I Convert a THREE.CatmullRomCurve3 to a Mesh?
我使用 THREE.js 和 CatmullRomCurve3 class 创建了一个 3D 线图,它处理我想要的曲线和平滑。
不幸的是,现在我想把那条曲线变成一个网格,也许挤出那个网格,看来我做不到。当我尝试这样的事情时:
var geometry = new THREE.ShapeGeometry( curve );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material ) ;
我得到的错误证明曲线不是几何构造函数想要的:
three.js:27731 Uncaught TypeError: shape.extractPoints is not a function
at ExtrudeBufferGeometry.addShape (three.js:27731)
at ExtrudeBufferGeometry.addShapeList (three.js:27656)
at new ExtrudeBufferGeometry (three.js:27612)
at new ChartTest (ChartTest.js:33)
at createSceneSubjects (SceneManager.js:89)
at new SceneManager (SceneManager.js:27)
at main.js:16
我见过将曲线作为 extrudePath 参数传递的示例,例如:
var extrudeSettings = {
steps : 100,
bevelEnabled : false,
extrudePath : curve
};
但这需要将形状与 extrudeSettings 一起传递给 ExtrudeGeometry,但是必须有比尝试创建单独的形状更直接的方法,当曲线已经定义我想要挤出的形状。 (这似乎也挤出了路径而不是它描述的形状。)
如有任何帮助,我们将不胜感激!
ShapeGeometry
需要类型 THREE.Shape
的实例作为参数,而不是类型 THREE.Curve
的对象。此外,THREE.CatmullRomCurve3
是 3D 曲线,而 THREE.Shape
是 2D 实体。这意味着您的形状将始终是平坦的。您可以执行以下操作来使事情正常进行:
首先对曲线进行采样,然后创建 THREE.Shape
的实例。请记住,给定点中的 z-coordinates 将被忽略。
const points = curve.getPoints( 64 );
const shape = new THREE.Shape( points );
const geometry = new THREE.ShapeGeometry( shape );
https://jsfiddle.net/f2Lommf5/3775/
three.js R91
在这种情况下,如果您想要某种丝带,这里有一个粗略的概念:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-0.5, 4, 5);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var curve = new THREE.CatmullRomCurve3(
[
new THREE.Vector3(-2, 2, 0),
new THREE.Vector3(-1, 0.5, 0),
new THREE.Vector3(0, 1, 0),
new THREE.Vector3(1, 3, 0),
new THREE.Vector3(2, 1, 0)
]
);
var pointsCount = 50;
var pointsCount1 = pointsCount + 1;
var points = curve.getPoints(pointsCount);
var pts = curve.getPoints(pointsCount);
var width = 2;
var widthSteps = 1;
let pts2 = curve.getPoints(pointsCount);
pts2.forEach(p => {
p.z += width;
});
pts = pts.concat(pts2);
var ribbonGeom = new THREE.BufferGeometry().setFromPoints(pts);
var indices = [];
for (iy = 0; iy < widthSteps; iy++) { // the idea taken from PlaneBufferGeometry
for (ix = 0; ix < pointsCount; ix++) {
var a = ix + pointsCount1 * iy;
var b = ix + pointsCount1 * (iy + 1);
var c = (ix + 1) + pointsCount1 * (iy + 1);
var d = (ix + 1) + pointsCount1 * iy;
// faces
indices.push(a, b, d);
indices.push(b, c, d);
}
}
ribbonGeom.setIndex(indices);
ribbonGeom.computeVertexNormals();
var ribbon = new THREE.Mesh(ribbonGeom, new THREE.MeshNormalMaterial({
side: THREE.DoubleSide
}));
scene.add(ribbon);
var line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), new THREE.LineBasicMaterial({
color: "red",
depthTest: false
}));
scene.add(line);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
我使用 THREE.js 和 CatmullRomCurve3 class 创建了一个 3D 线图,它处理我想要的曲线和平滑。
不幸的是,现在我想把那条曲线变成一个网格,也许挤出那个网格,看来我做不到。当我尝试这样的事情时:
var geometry = new THREE.ShapeGeometry( curve );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material ) ;
我得到的错误证明曲线不是几何构造函数想要的:
three.js:27731 Uncaught TypeError: shape.extractPoints is not a function
at ExtrudeBufferGeometry.addShape (three.js:27731)
at ExtrudeBufferGeometry.addShapeList (three.js:27656)
at new ExtrudeBufferGeometry (three.js:27612)
at new ChartTest (ChartTest.js:33)
at createSceneSubjects (SceneManager.js:89)
at new SceneManager (SceneManager.js:27)
at main.js:16
我见过将曲线作为 extrudePath 参数传递的示例,例如:
var extrudeSettings = {
steps : 100,
bevelEnabled : false,
extrudePath : curve
};
但这需要将形状与 extrudeSettings 一起传递给 ExtrudeGeometry,但是必须有比尝试创建单独的形状更直接的方法,当曲线已经定义我想要挤出的形状。 (这似乎也挤出了路径而不是它描述的形状。)
如有任何帮助,我们将不胜感激!
ShapeGeometry
需要类型 THREE.Shape
的实例作为参数,而不是类型 THREE.Curve
的对象。此外,THREE.CatmullRomCurve3
是 3D 曲线,而 THREE.Shape
是 2D 实体。这意味着您的形状将始终是平坦的。您可以执行以下操作来使事情正常进行:
首先对曲线进行采样,然后创建 THREE.Shape
的实例。请记住,给定点中的 z-coordinates 将被忽略。
const points = curve.getPoints( 64 );
const shape = new THREE.Shape( points );
const geometry = new THREE.ShapeGeometry( shape );
https://jsfiddle.net/f2Lommf5/3775/
three.js R91
在这种情况下,如果您想要某种丝带,这里有一个粗略的概念:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-0.5, 4, 5);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var curve = new THREE.CatmullRomCurve3(
[
new THREE.Vector3(-2, 2, 0),
new THREE.Vector3(-1, 0.5, 0),
new THREE.Vector3(0, 1, 0),
new THREE.Vector3(1, 3, 0),
new THREE.Vector3(2, 1, 0)
]
);
var pointsCount = 50;
var pointsCount1 = pointsCount + 1;
var points = curve.getPoints(pointsCount);
var pts = curve.getPoints(pointsCount);
var width = 2;
var widthSteps = 1;
let pts2 = curve.getPoints(pointsCount);
pts2.forEach(p => {
p.z += width;
});
pts = pts.concat(pts2);
var ribbonGeom = new THREE.BufferGeometry().setFromPoints(pts);
var indices = [];
for (iy = 0; iy < widthSteps; iy++) { // the idea taken from PlaneBufferGeometry
for (ix = 0; ix < pointsCount; ix++) {
var a = ix + pointsCount1 * iy;
var b = ix + pointsCount1 * (iy + 1);
var c = (ix + 1) + pointsCount1 * (iy + 1);
var d = (ix + 1) + pointsCount1 * iy;
// faces
indices.push(a, b, d);
indices.push(b, c, d);
}
}
ribbonGeom.setIndex(indices);
ribbonGeom.computeVertexNormals();
var ribbon = new THREE.Mesh(ribbonGeom, new THREE.MeshNormalMaterial({
side: THREE.DoubleSide
}));
scene.add(ribbon);
var line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(points), new THREE.LineBasicMaterial({
color: "red",
depthTest: false
}));
scene.add(line);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>