Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

THREE.JS Place a plane along given line and an vector

I have an arbitrary line ins 3D space and perpendicular vector to it, so both could form a plane. See illustration.

enter image description here

The task is to place existed plane along this line, so plane's face would be seen (rendered), see the second illustration.

enter image description here

Need a guide on how to do it. Thanks in advance.

like image 867
VVK Avatar asked Oct 24 '25 02:10

VVK


1 Answers

You may find working example here: https://jsfiddle.net/Gangula/0s6nqL43/1/

The key point of the solution is to rotate plane by .lookAt having specifically defined vector .up, see how it works on my drawing.

place plane along given line and an vector

// 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);
like image 82
Alex Khoroshylov Avatar answered Oct 26 '25 19:10

Alex Khoroshylov