答案 0 :(得分:4)
您可以在此处找到有效的示例:https://jsfiddle.net/mmalex/ert1Lwy9/
解决方案的关键是通过.lookAt旋转平面,并明确定义矢量.up,看看它如何在我的图形上工作。
// line is defined by p0-p1
var p0 = new THREE.Vector3(-1, 2, 1);
var p1 = new THREE.Vector3(2, -1, -1);
// any random point outside the line will define plane orientation
var p2 = p1.clone().add(new THREE.Vector3(0.4, 0.8, 0.53));
var material2 = new THREE.LineBasicMaterial({
color: 0x0000ff
});
// draw the line for visual reference
var geometry = new THREE.Geometry();
geometry.vertices.push(
p0,
p1,
p2
);
var line = new THREE.Line(geometry, material2);
scene.add(line);
// get direction of line p0-p1
var direction = p1.clone().sub(p0).normalize();
// project p2 on line p0-p1
var line0 = new THREE.Line3(p0, p1);
var proj = new THREE.Vector3();
line0.closestPointToPoint(p2, true, proj);
// get plane side direction
var localUp = p2.clone().sub(proj).normalize();
// draw the projection, just nice to have
var axesHelper = new THREE.AxesHelper(0.1);
axesHelper.position.copy(proj);
scene.add(axesHelper);
// calc plane normal vector (how we want plane to direct)
var n = new THREE.Vector3();
n.crossVectors(proj.clone().sub(p0), proj.clone().sub(p2));
// preparation is complete, create a plane now
const planeL = 2.15;
const planeW = 1.75;
var geometry = new THREE.PlaneGeometry(planeL, planeW, 32);
var material3 = new THREE.MeshBasicMaterial({
color: 0xa9cc00,
side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material3);
// now align the plane to the p0-p1 in direction p2
plane.position.copy(p0); //put plane by its center on p0
plane.up.copy(localUp); //adjust .up for future .lookAt call
plane.lookAt(p0.clone().add(n)); //rotate plane
// now just offset plane by half width and half height
plane.position.add(localUp.clone().multiplyScalar(planeW / 2));
plane.position.add(direction.clone().multiplyScalar(planeL / 2));
// done!
scene.add(plane);
答案 1 :(得分:0)
var camera, scene, renderer, controls;
var labelX, labelY, labelY;
var loader = new THREE.FontLoader();
loader.load("https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/fonts/helvetiker_regular.typeface.json", function (font_) {
init(font_);
});
function init(font_) {
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(256, 512, 512);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xDEDEDE, 1.0 );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = true;
controls.dampingFactor = 0.25;
controls.mouseButtons = {
LEFT: THREE.MOUSE.LEFT,
MIDDLE: THREE.MOUSE.MIDDLE,
RIGHT: THREE.MOUSE.RIGHT
};
var material = new THREE.LineBasicMaterial( { color: 0x000000 } );
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-196, 0, 0));
geometry.vertices.push(new THREE.Vector3(196, 0, 0));
var xLine = new THREE.Line(geometry, material);
scene.add(xLine);
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, -196, 0));
geometry.vertices.push(new THREE.Vector3(0, 196, 0));
var yLine = new THREE.Line(geometry, material);
scene.add(yLine);
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 0, -196));
geometry.vertices.push(new THREE.Vector3(0, 0, 196));
var zLine = new THREE.Line(geometry, material);
scene.add(zLine);
var textMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
var textX = new THREE.TextGeometry("label_x", {
font: font_,
size: 6,
height: 0.1,
curveSegments: 12,
bevelEnabled: false,
});
labelX = new THREE.Mesh(textX, textMaterial);
labelX.position.set(180, 0, -6);
labelX.geometry.center();
labelX.rotateX(-Math.PI/2)
scene.add(labelX);
var textY = new THREE.TextGeometry("label_y", {
font: font_,
size: 6,
height: 0.1,
curveSegments: 12,
bevelEnabled: false,
});
labelY = new THREE.Mesh(textY, textMaterial);
labelY.position.set(6, 180, 0);
labelY.geometry.center();
labelY.rotateZ(Math.PI/2)
scene.add(labelY);
var textZ = new THREE.TextGeometry("label_z", {
font: font_,
size: 6,
height: 0.1,
curveSegments: 12,
bevelEnabled: false,
});
labelZ = new THREE.Mesh(textZ, textMaterial);
labelZ.position.set(-6, 0, -180);
labelZ.geometry.center();
labelZ.rotateY(Math.PI/2)
labelZ.rotateX(-Math.PI/2)
scene.add(labelZ);
window.addEventListener( 'resize', onWindowResize, false );
animate();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
if(camera.position.y < 0){
labelX.rotation.set(Math.PI/2, 0, 0);
labelZ.rotation.set(0, Math.PI/2, 0);
labelZ.rotateX(Math.PI/2);
}else{
labelX.rotation.set(-Math.PI/2, 0, 0);
labelZ.rotation.set(0, Math.PI/2, 0);
labelZ.rotateX(-Math.PI/2);
}
if(camera.position.z < 0){
labelY.rotation.set(0, -Math.PI, -Math.PI/2);
}else{
labelY.rotation.set(0, 0, Math.PI/2);
}
controls.update();
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
实际上,我正在尝试这样做。