Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connector function #9

Open
Daubsy opened this issue Jan 20, 2015 · 2 comments
Open

connector function #9

Daubsy opened this issue Jan 20, 2015 · 2 comments

Comments

@Daubsy
Copy link

Daubsy commented Jan 20, 2015

Hi, great library! Im trying to implement a connector function like the one found in the OpenJSCAD csg.js library (OpenJSCAD.org/csg.js). Its more complex than I thought, and I am having trouble porting to JSModeler. It would be a very handy function to have for building assemblies. Any ideas?

// # class Connector
// A connector allows to attach two objects at predefined positions
// For example a servo motor and a servo horn:
// Both can have a Connector called 'shaft'
// The horn can be moved and rotated such that the two connectors match
// and the horn is attached to the servo motor at the proper position.
// Connectors are stored in the properties of a CSG solid so they are
// ge the same transformations applied as the solid
CSG.Connector = function(point, axisvector, normalvector) {
this.point = new CSG.Vector3D(point);
this.axisvector = new CSG.Vector3D(axisvector).unit();
this.normalvector = new CSG.Vector3D(normalvector).unit();
};

CSG.Connector.prototype = {
normalized: function() {
    var axisvector = this.axisvector.unit();
    // make the normal vector truly normal:
    var n = this.normalvector.cross(axisvector).unit();
    var normalvector = axisvector.cross(n);
    return new CSG.Connector(this.point, axisvector, normalvector);
},

transform: function(matrix4x4) {
    var point = this.point.multiply4x4(matrix4x4);
    var axisvector = this.point.plus(this.axisvector).multiply4x4(matrix4x4).minus(point);
    var normalvector = this.point.plus(this.normalvector).multiply4x4(matrix4x4).minus(point);
    return new CSG.Connector(point, axisvector, normalvector);
},

// Get the transformation matrix to connect this Connector to another connector
//   other: a CSG.Connector to which this connector should be connected
//   mirror: false: the 'axis' vectors of the connectors should point in the same direction
//           true: the 'axis' vectors of the connectors should point in opposite direction
//   normalrotation: degrees of rotation between the 'normal' vectors of the two
//                   connectors
getTransformationTo: function(other, mirror, normalrotation) {
    mirror = mirror ? true : false;
    normalrotation = normalrotation ? Number(normalrotation) : 0;
    var us = this.normalized();
    other = other.normalized();
    // shift to the origin:
    var transformation = CSG.Matrix4x4.translation(this.point.negated());
    // construct the plane crossing through the origin and the two axes:
    var axesplane = CSG.Plane.anyPlaneFromVector3Ds(
    new CSG.Vector3D(0, 0, 0), us.axisvector, other.axisvector);
    var axesbasis = new CSG.OrthoNormalBasis(axesplane);
    var angle1 = axesbasis.to2D(us.axisvector).angle();
    var angle2 = axesbasis.to2D(other.axisvector).angle();
    var rotation = 180.0 * (angle2 - angle1) / Math.PI;
    if(mirror) rotation += 180.0;
    transformation = transformation.multiply(axesbasis.getProjectionMatrix());
    transformation = transformation.multiply(CSG.Matrix4x4.rotationZ(rotation));
    transformation = transformation.multiply(axesbasis.getInverseProjectionMatrix());
    var usAxesAligned = us.transform(transformation);
    // Now we have done the transformation for aligning the axes.
    // We still need to align the normals:
    var normalsplane = CSG.Plane.fromNormalAndPoint(other.axisvector, new CSG.Vector3D(0, 0, 0));
    var normalsbasis = new CSG.OrthoNormalBasis(normalsplane);
    angle1 = normalsbasis.to2D(usAxesAligned.normalvector).angle();
    angle2 = normalsbasis.to2D(other.normalvector).angle();
    rotation = 180.0 * (angle2 - angle1) / Math.PI;
    rotation += normalrotation;
    transformation = transformation.multiply(normalsbasis.getProjectionMatrix());
    transformation = transformation.multiply(CSG.Matrix4x4.rotationZ(rotation));
    transformation = transformation.multiply(normalsbasis.getInverseProjectionMatrix());
    // and translate to the destination point:
    transformation = transformation.multiply(CSG.Matrix4x4.translation(other.point));
    var usAligned = us.transform(transformation);
    return transformation;
},

axisLine: function() {
    return new CSG.Line3D(this.point, this.axisvector);
},

// creates a new Connector, with the connection point moved in the direction of the axisvector
extend: function(distance) {
    var newpoint = this.point.plus(this.axisvector.unit().times(distance));
    return new CSG.Connector(newpoint, this.axisvector, this.normalvector);
}

};

@kovacsv
Copy link
Owner

kovacsv commented Jan 23, 2015

Hi Daubster!

Sorry for the late answer. It sound a good idea. I can imagine this in JSModeler like this:

  • Every Body has its own connector list. Primitive generators should fill this list automatically, and should be possible to add new ones from outside.
  • The ConnectTo function should transform the Body depending on two connectors.

The only tricky part is calculating the transformation between two connectors, but as I see the code, every operation is available in JSModeler.

@Daubsy
Copy link
Author

Daubsy commented Feb 21, 2015

Cool. Im still trying to understand and navigate my away around all the geometry functions. On a related topic, Im also trying to figure out the best way I can offset an array of coordinates toward a single apex coordinate (0, 0, apex). So, all vectors converge at the apex point. Ive tried combining JSM.CoordOffset with JSM.CoordMultiply, but it seems there should be an easier, more precise way of doing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants