我一直在谷歌搜索这个问题,但我找不到多少。
基本上,我只想要一个具有四边形的球体 - 即网格中没有三角剖分。事实上,如果有可能,我希望它只有垂直线,但我认为这是不可能的,但我绝对不希望对角线。
我看到了EdgesHelper
,但我并没有认为这就是我想要创建的球体。
我不认为这是重复的,但如果是,请指出我正确的地方;感谢。
答案 0 :(得分:3)
我从头开始使用THREE.CircleGeometry()
制作了这样的可自定义解决方案(尽管没有缓冲):
function createSphereOfQuadsWireframe(radius, widthSegments, heightSegments, color, showWidthSegments, showHeightSegments) {
var sphereObj = new THREE.Group();
if (showWidthSegments) {
// width segments
var arcGeom = createArc(radius, heightSegments, false); // as the amount of width segments may be odd, it's better to use half-circles, that's why the third parameter is `false`
var widthSector = Math.PI * 2 / widthSegments;
for (var ws = 0; ws < widthSegments; ws++) {
var arcGeomTmp = arcGeom.clone();
arcGeomTmp.rotateY(widthSector * ws);
var arcLine = new THREE.Line(arcGeomTmp, new THREE.LineBasicMaterial({
color: color
}));
sphereObj.add(arcLine);
}
}
if (showHeightSegments) {
//height segments
var heightSector = Math.PI / heightSegments;
for (var hs = 1; hs < heightSegments; hs++) {
var hRadius = Math.sin(hs * heightSector) * radius;
var height = Math.cos(hs * heightSector) * radius;
var arcHeightGeom = createArc(hRadius, widthSegments, true);
arcHeightGeom.rotateX(Math.PI / 2);
arcHeightGeom.translate(0, height, 0);
var arcHeightLine = new THREE.Line(arcHeightGeom, new THREE.LineBasicMaterial({
color: color
}));
sphereObj.add(arcHeightLine);
}
}
return sphereObj;
}
function createArc(radius, segments, full) {
var geom = new THREE.CircleGeometry(radius, segments, Math.PI / 2, full ? Math.PI * 2 : Math.PI);
geom.vertices.shift();
if (full) geom.vertices.push(geom.vertices[0].clone());
return geom;
}
它的用法是这样的:
var fullSphere = createSphereOfQuadsWireframe(20, 32, 16, "yellow", true, true);
scene.add(fullSphere);
var widthOnlySphere = createSphereOfQuadsWireframe(20, 32, 16, "pink", true, false);
widthOnlySphere.position.set(-50, 0, 0);
scene.add(widthOnlySphere);
var heightOnlySphere = createSphereOfQuadsWireframe(20, 32, 16, "aqua", false, true);
heightOnlySphere.position.set(50, 0, 0);
scene.add(heightOnlySphere);
jsfiddle示例
答案 1 :(得分:1)
请参阅one of capybara
's authors,了解我最终是如何创建自己的四元组的。具有phi-和θ-开始和长度值的球体,以便您可以创建部分球体。感谢囚犯849,他回答了上/下。
body {
overflow: hidden;
margin: 0;
}
&#13;
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
&#13;
function createQuadSphere(r, widthSegments, heightSegments, atts, phiStart, phiLen, thetaStart, thetaLen) {
var sphere = new THREE.Group(),
material = new THREE.LineBasicMaterial(atts);
if (phiStart === undefined) {
phiStart = Math.PI / 2;
}
if (phiLen === undefined) {
phiLen = 2 * Math.PI;
}
if (thetaStart === undefined) {
thetaStart = 0;
}
if (thetaLen === undefined) {
thetaLen = Math.PI;
}
/* width segments (longitude) */
for (var phiDelta = phiLen / widthSegments, phi = phiStart, arc = createVerticalArc(r, heightSegments, thetaStart + Math.PI / 2, thetaLen); phi <= phiStart + phiLen + phiDelta; phi += phiDelta) {
var arcTmpGeometry = arc.clone();
arcTmpGeometry.rotateY(phi);
var arcLine = new THREE.Line(arcTmpGeometry, material);
sphere.add(arcLine);
}
/* height segments (latitude) */
for (var thetaDelta = thetaLen / heightSegments, theta = thetaStart; theta < thetaStart + thetaLen - thetaDelta; theta += thetaDelta) {
if (theta === 0) {
continue;
}
var arcR = r * Math.sin(theta),
arcH = r * Math.cos(theta),
arcTmpGeometry = createHorizontalArc(arcR, widthSegments, phiStart, phiLen);
arcTmpGeometry.rotateX(Math.PI / 2);
arcTmpGeometry.rotateY(Math.PI / 2);
arcTmpGeometry.translate(0, arcH, 0);
var arcLine = new THREE.Line(arcTmpGeometry, material);
sphere.add(arcLine);
}
return sphere;
}
function createVerticalArc(r, segments, thetaStart, thetaLen) {
var geometry = new THREE.CircleGeometry(r, segments, thetaStart, thetaLen);
geometry.vertices.shift();
return geometry;
}
function createHorizontalArc(r, segments, phiStart, phiLen) {
var geometry = new THREE.CircleGeometry(r, segments, phiStart, phiLen);
geometry.vertices.shift();
if (phiLen >= 2 * Math.PI) {
geometry.vertices.push(geometry.vertices[0].clone());
}
return geometry;
}
&#13;
代码:
var radius = 20, widthSegments = 32, heightSegments = 16,
atts = {color: "red"},
phiStart = Math.PI / 2, phiLen = Math.PI,
thetaStart = 0, thetaLen = Math.PI;
var sphere = createQuadSphere(radius, widthSegments / 2,
heightSegments, atts, phiStart, phiLen,
thetaStart, thetaLen);
scene.add(sphere);
使用方法:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-80, 80, -350);
var renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.style.backgroundColor = "#bbbbbb"
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var r = 20,
verticalLines = 32,
/* must be divisible by 4! */
horizontalLines = 32; /* must be divisible by 2! */
var tubeArc = createTubeArc(50, horizontalLines, 5, 8, 0, 2 * Math.PI, 'round', {
'color': 'red'
})
scene.add(tubeArc);
var tubeArc1 = createTubeArc(50, horizontalLines, 5, 8, Math.PI, Math.PI, 'round', {
'color': 'yellow'
})
tubeArc1.position.x += 50;
scene.add(tubeArc1);
var tubeArc2 = createTubeArc(50, horizontalLines, 5, 8, 0, Math.PI, 'round', {
'color': 'blue'
})
tubeArc2.position.x -= 50;
scene.add(tubeArc2);
function createTubeArc(radius, segments, cylinderRadius, cylinderSegments, thetaStart, thetaLen, capStyle, atts) {
var tubeArc = new THREE.Group();
if (capStyle !== "round" && capStyle !== "open" && capStyle !== "flat") {
capStyle = "round";
}
// TODO: implement round :D (when you think you might need something ...)
var material = new THREE.MeshBasicMaterial(atts);
for (var thetaDelta = thetaLen / segments, theta = thetaStart + thetaDelta / 2, cylinderHeight = Math.sqrt(2 * radius * radius - 2 * radius * radius * Math.cos(thetaDelta)) + Math.sqrt(2 * cylinderRadius * cylinderRadius - 2 * cylinderRadius * cylinderRadius * Math.cos(thetaDelta)); theta < thetaStart + thetaLen + thetaDelta / 2; theta += thetaDelta) {
var ptX = radius * Math.cos(theta),
ptY = radius * Math.sin(theta),
cylinderTmpGeometry = new THREE.CylinderGeometry(cylinderRadius, cylinderRadius, cylinderHeight, cylinderSegments, 1, (capStyle === "open"), 0, 2 * Math.PI),
cylinder = new THREE.Mesh(cylinderTmpGeometry, material);
cylinder.rotateZ(theta);
cylinder.position.x = ptX;
cylinder.position.y = ptY;
if (capStyle === "open") {
cylinder.material.side = THREE.DoubleSide;
}
tubeArc.add(cylinder);
}
return tubeArc;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
我认为球体可能在x-z平面(phi)中旋转180度,但是我在工作的漫长的一天中感到厌倦,它满足了我的需求:)
这个可怕的地方,但我也做了厚度的弧..因为我必须为我的项目:https://jsfiddle.net/dylnmc/3o9gae9r/
body {
overflow: hidden;
margin: 0;
}
&#13;
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
&#13;
{{1}}&#13;