Threejs - Child Rotate Maintain

by black strings

HTML

<script src="https://rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>

CSS

/* fix mouse click offset errors when doing drags */
body {
  margin: 0;
}

JavaScript

// a class encapsulting a math line and a actual line.
class Line {
	constructor(p1,p2){
    
    this.start = p1;
    this.end = p2;
    
  	this.line3 = new THREE.Line3(p1, p2);
    console.log(this.line3);
    
    var lineGeo = new THREE.Geometry();
    lineGeo.vertices.push(this.line3.start, this.line3.end);
    var mat = new THREE.LineBasicMaterial({color:0xff0000});
    this.mesh = new THREE.Line(lineGeo, mat);
    
    var normal = this.getVectorNormal();
    
    console.log(normal);
    
  }
  
  getVectorNormal(){
  	var normal = new THREE.Vector3();
    normal.subVectors(this.end.clone(), this.start.clone());
    var angle = THREE.Math.degToRad(90);
    normal.applyAxisAngle(new THREE.Vector3(0,0,1), angle);
    
    this.zeroOutNearZeroValues(normal);
    
    return normal;
  }
  
  zeroOutNearZeroValues(vec){
  	 var x = parseInt(vec.x.toFixed(3));
     var y = parseInt(vec.y.toFixed(3));
     var z = parseInt(vec.z.toFixed(3));
     vec.x = x === 0 ? 0 : vec.x;
     vec.y = y === 0 ? 0 : vec.y;
     vec.z = z === 0 ? 0 : vec.z;
  }
  
  getDirection(){
  	var direction = new THREE.Vector3();
    direction.subVectors(p2.clone(),p1.clone());
    return direction;
  }
  
  /// a real math lin3, while you can move it, it's not easily resetable
  // once moved, the new cordinates are its starting position
  // to reset, you'll have to create a new properties like a position to offset from
  setPosition(x=0,y=0,z=0){
  	this.line3.applyMatrix4(new THREE.Matrix4().makeTranslation(x,y,z));
    this.mesh.geometry.verticesNeedUpdate = true;
  }

}

class Utils {
	static createArc(rad = 5, seg = 36, thetaStart = 0, thetaEnd = 360){
  	var radius = rad;
    var segments = seg;
    var pointGeo = new THREE.Geometry();
    var thetaStart = THREE.Math.degToRad(thetaStart);
    var thetaLength = THREE.Math.degToRad(thetaEnd);

    // don't include center
    // pointGeo.vertices.push(new THREE.Vector3(0,0,0));
    for(var i=0; i<=segments; i++){

      var...