gs-json
Version:
gs-JSON is a domain agnostic unifying 3D file format for geometric and semantic modelling (hence the 'gs').
211 lines (204 loc) • 7.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getRenderXYZs = getRenderXYZs;
exports.circleLength = circleLength;
exports.circleEvaluate = circleEvaluate;
exports.circleEvaluateTangent = circleEvaluateTangent;
exports.circleEvaluatePoint = circleEvaluatePoint;
exports.circleGetRenderXYZs = circleGetRenderXYZs;
var _three = require("three");
var three = _interopRequireWildcard(_three);
var _threex = require("../threex/threex");
var threex = _interopRequireWildcard(_threex);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
/**
* Calculate a set of xyz position on the circle/arc ir ellipse/arc. The number of points = length / resolution.
* With resolution from 0.0001 to 0.5, 0.0001 being a higher resolution than 0.5
*/
function getRenderXYZs(obj, resolution) {
switch (obj.getObjType()) {
case 3 /* circle */:
return circleGetRenderXYZs(obj, resolution);
default:
throw new Error("Invalid object type.");
}
}
/**
* Calculate the length of the circle or arc.
*/
function circleLength(circle) {
var rad = circle.getRadius();
var angles = circle.getAngles();
// if circle is closed, then return 2PI * rad
if (angles === null) {
return 2 * Math.PI * rad;
}
// set arc start and arc end angles, in radians
var ang_start = angles[0] * (Math.PI / 180);
var ang_end = angles[1] * (Math.PI / 180);
// calculate the angle of the arc
var arc_angle = void 0;
if (ang_start < ang_end) {
arc_angle = ang_end - ang_start;
} else {
arc_angle = Math.PI * 2 - ang_start + ang_end;
}
// calculate the length, 2PI * rad * (arc_angle/2PI)
return rad * arc_angle;
}
/**
* Calculate the xyz position at parameter t on the circle or arc. The t parameter range is from 0 to 1.
*/
function circleEvaluate(circle, t) {
var rad = circle.getRadius();
var angles = circle.getAngles();
// set arc start and arc end angles, in radians
var ang_start = void 0;
var ang_end = void 0;
if (angles === null) {
ang_start = 0;
ang_end = Math.PI * 2;
} else {
ang_start = angles[0] * (Math.PI / 180);
ang_end = angles[1] * (Math.PI / 180);
}
// calculate the angle of the arc
var arc_angle = void 0;
if (ang_start < ang_end) {
arc_angle = ang_end - ang_start;
} else {
arc_angle = Math.PI * 2 - ang_start + ang_end;
}
// create matrix to map from XY plane into the 3D plane for circle
var matrix_inv = threex.matrixInv(threex.xformMatrixFromXYZs(circle.getOrigin().getPosition(), circle.getAxes()));
// calculate the point
var alpha = ang_start + t * arc_angle;
var point = new three.Vector3(rad * Math.cos(alpha), rad * Math.sin(alpha), 0);
point.applyMatrix4(matrix_inv);
// return the points
return point.toArray();
}
/**
* Calculate the xyz tangent at parameter t on the circle or arc. The t parameter range is from 0 to 1.
*/
function circleEvaluateTangent(circle, t) {
var point_xyz = circleEvaluate(circle, t);
if (point_xyz === null) {
return null;
}
var origin_xyz = circle.getOrigin().getPosition();
var normal_xyz = circle.getNormal();
var vec_xyz = threex.subXYZs(point_xyz, origin_xyz);
return threex.crossXYZs(vec_xyz, normal_xyz, true);
}
/**
* Project a point on a circle, and calculate the parameter t.
*/
function circleEvaluatePoint(circle, point) {
var angles = circle.getAngles();
// create matrix to map from the 3D plane for circle into the XY plane
var matrix = threex.xformMatrixFromXYZs(circle.getOrigin().getPosition(), circle.getAxes());
// map the point onto the XY plane
var xyz_2d = threex.multXYZMatrix(point.getPosition(), matrix);
// calculate the angle between the point vector and the x axis, in radians
var point_angle = Math.atan2(xyz_2d[1], xyz_2d[0]);
if (point_angle < 0) {
point_angle += 2 * Math.PI;
}
// calculate t for a closed circle
if (angles === null) {
return point_angle / (2 * Math.PI);
}
// convert angles to radians
var ang_start = angles[0] * (Math.PI / 180);
var ang_end = angles[1] * (Math.PI / 180);
// calculate t for an arc
if (ang_start < ang_end) {
// calc arc angle
var arc_angle = ang_end - ang_start;
// the point is on the arc
if (point_angle >= ang_start && point_angle <= ang_end) {
return (point_angle - ang_start) / arc_angle;
}
// the point is not on the arc, so it must be at an end point
else {
var rotated = point_angle - (ang_start + arc_angle / 2);
if (rotated < 0) {
rotated = rotated + Math.PI * 2;
}
if (rotated > Math.PI) {
return 0;
} else {
return 1;
}
}
} else {
// calc arc angle
var arc_angle_lower = Math.PI * 2 - ang_start;
var arc_angle_upper = ang_end;
var _arc_angle = arc_angle_lower + arc_angle_upper;
// the point is on the outer arc, below the x axis
if (point_angle >= ang_start) {
return (point_angle - ang_start) / _arc_angle;
}
// the point is on the outer arc, above the x axis
else if (point_angle <= ang_end) {
return (arc_angle_lower + point_angle) / _arc_angle;
}
// the point is not on the outside arc, so it must be at an end point
else {
var _rotated = point_angle + (_arc_angle / 2 - ang_end);
if (_rotated > Math.PI) {
return 0;
} else {
return 1;
}
}
}
}
/**
* Calculate a set of xyz position on the circle or arc. The number of points = length / resolution.
* With resolution from 0.0001 to 0.5, 0.0001 being a higher resolution than 0.5
*/
function circleGetRenderXYZs(circle, resolution) {
var rad = circle.getRadius();
var angles = circle.getAngles();
// calculat the angles
var ang_start = void 0;
var ang_end = void 0;
if (angles === null) {
ang_start = 0;
ang_end = Math.PI * 2;
} else {
ang_start = angles[0] * (Math.PI / 180);
ang_end = angles[1] * (Math.PI / 180);
}
// calculate the angle of the arc
var arc_angle = void 0;
if (ang_start < ang_end) {
arc_angle = ang_end - ang_start;
} else {
arc_angle = Math.PI * 2 - ang_start + ang_end;
}
// calculate number of points
var num_points = Math.floor(arc_angle / (Math.PI / 36));
if (num_points < 3) {
num_points = 3;
}
// create matrix to map from XY plane into the 3D plane for circle
var matrix_inv = threex.matrixInv(threex.xformMatrixFromXYZs(circle.getOrigin().getPosition(), circle.getAxes()));
// main loop to create points
var xyz_points = [];
for (var i = 0; i < num_points; i++) {
var t = i / (num_points - 1);
var alpha = ang_start + t * arc_angle;
var point = new three.Vector3(rad * Math.cos(alpha), rad * Math.sin(alpha), 0);
point.applyMatrix4(matrix_inv);
xyz_points.push(point.toArray());
}
// return the points
return xyz_points;
}
//# sourceMappingURL=circles.js.map