three.js - align plane

wip

by mmalex

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="info" style="margin-left: 100px;">Place plane so that it goes along given line, and control direction by third point.</div>

CSS

body {
  overflow: hidden;
  margin: 0;
  padding: 0;
}

JavaScript

let renderer;
let camera;
let controls;

let scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(54, window.innerWidth / window.innerHeight, 0.1, 1000);

renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0xfefefe));
document.body.appendChild(renderer.domElement);

camera.position.x = 5;
camera.position.y = 2;
camera.position.z = 7.5;
camera.lookAt(0, 0, 0);

controls = new THREE.OrbitControls(camera);

// white spotlight shining from the side, casting a shadow
let spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
spotLight.position.set(9, 10, 1);
scene.add(spotLight);

let gridHelper = new THREE.GridHelper(4, 4);
scene.add(gridHelper);

//======== Alignment logic starts here ========

//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...