@xtor/cga.js
Version:
Xtor Compute Geometry Algorithm Libary 计算几何算法库
111 lines (110 loc) • 4.94 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Polyline = void 0;
var extrude_1 = require("../../alg/extrude");
var Math_1 = require("../../math/Math");
var Vec3_1 = require("../../math/Vec3");
var ArrayEx_1 = require("../data/ArrayEx");
var Line_1 = require("./Line");
var Segment_1 = require("./Segment");
/**
* 线段正反原则:右手坐标系中,所在平面为XZ平面,把指向方向看着负Z轴,x正为正方向,x负为负方向
*/
var Polyline = /** @class */ (function (_super) {
__extends(Polyline, _super);
function Polyline(vs, normal) {
if (vs === void 0) { vs = []; }
if (normal === void 0) { normal = Vec3_1.Vec3.UnitY; }
var _this = _super.call(this) || this;
_this.normal = normal;
_this.isPolyline = true;
Object.setPrototypeOf(_this, Polyline.prototype);
_this.push.apply(_this, vs);
_this.isCoPlanar = true;
return _this;
}
/**
* 偏移
* @param {Number} distance 偏移距离
* @param {Vector3} normal 折线所在平面法线
*/
Polyline.prototype.offset = function (distance, normal, endtype, jointype) {
if (normal === void 0) { normal = Vec3_1.Vec3.UnitY; }
if (endtype === void 0) { endtype = extrude_1.EndType.Butt; }
if (jointype === void 0) { jointype = extrude_1.JoinType.Miter; }
var segs = [];
var _loop_1 = function (i) {
var seg = new Segment_1.Segment(this_1[i].clone(), this_1[i + 1].clone());
var segtangetvec = seg[1].clone().sub(seg[0]).normalize().applyAxisAngle(normal, Math.PI / 2).multiplyScalar(distance);
seg.forEach(function (e) { return e.add(segtangetvec); });
segs.push(seg);
};
var this_1 = this;
for (var i = 0; i < this.length - 1; i++) {
_loop_1(i);
}
for (var i = 0; i < segs.length - 1; i++) {
var segi = segs[i];
for (var j = i + 1; j < segs.length; j++) {
var segj = segs[j];
var disRes = segi.distanceSegment(segj);
if (disRes.distance < Math_1.gPrecision) {
//相交
segj[0].copy(disRes.closests[0]);
segi[1].copy(disRes.closests[0]);
}
else {
//判断是否在内
// var i_o = segi.direction.clone().cross(segj.p0.clone().sub(segi.p0)).dot(normal);
}
}
}
var offsetPts = [];
offsetPts.push(segs[0].p0);
for (var i = 0; i < segs.length; i++) {
var element = segs[i];
offsetPts.push(element.p1);
}
return new Polyline(offsetPts);
};
/**
* 圆角 将折线拐点圆角化
* @param {Number} useDistance 圆角段距离
* @param {Number} segments 分切割段数
*/
Polyline.prototype.corner = function (useDistance, normal) {
if (normal === void 0) { normal = this.normal; }
var polyline = new Polyline();
for (var i = 0; i < this.length - 2; i++) {
var p0 = this[i];
var p1 = this[i + 1];
var p2 = this[i + 2];
polyline.push(p0);
var fixedPoint0 = p0.distanceTo(p1) <= useDistance * 2 ? p0.clone().add(p1).multiplyScalar(0.5) : p0.clone().sub(p1).normalize().multiplyScalar(useDistance).add(p1);
var fixedPoint1 = p2.distanceTo(p1) <= useDistance * 2 ? p2.clone().add(p1).multiplyScalar(0.5) : p2.clone().sub(p1).normalize().multiplyScalar(useDistance).add(p1);
polyline.push(fixedPoint0);
var binormal0 = p1.clone().sub(p0).applyAxisAngle(normal, Math.PI / 2);
var binormal1 = p1.clone().sub(p0).applyAxisAngle(normal, Math.PI / 2);
//计算圆弧点
var line0 = new Line_1.Line(fixedPoint0, binormal0.add(fixedPoint0));
var line1 = new Line_1.Line(fixedPoint1, binormal1.add(fixedPoint1));
polyline.push(fixedPoint1);
}
return polyline;
};
return Polyline;
}(ArrayEx_1.ArrayEx));
exports.Polyline = Polyline;