UNPKG

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
"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