UNPKG

@xtor/cga.js

Version:

Xtor Compute Geometry Algorithm Libary 计算几何算法库

78 lines (67 loc) 2.7 kB
import { Vec3, v3 } from '../../math/Vec3'; import { angle, pointsCollinear } from '../../alg/common'; import { Line } from './Line'; export class Circle { startAngle: number = 0; endAngle: number = Math.PI * 2; radiusSqr: number = 0; /** * 圆圈 * @param {Vec3} center 中心点 * @param {Vec3} normal 法线 * @param {Number} radius 半径 */ constructor(public center: Vec3 = new Vec3(), public radius: number = 0, public normal: Vec3 = Vec3.UnitY) { } area() { return Math.PI * this.radius * this.radius; } /** * 两个点 * @param fixp0 * @param fixp1 * @param movep * @param normal */ arc1(fixp0: Vec3, fixp1: Vec3, movep: Vec3, normal?: Vec3) { this.setFrom3Points(fixp0, fixp1, movep); this.startAngle = 0 this.endAngle = angle(fixp0.clone().sub(this.center).normalize(), fixp1.clone().sub(this.center).normalize(), this.normal || normal) } /** * 全两个点确定半径,后面点确定 弧度 ,只需要检测鼠标移动时鼠标是否跨过第一条半径即可确定顺逆时针 * @param fixp0 * @param fixp1 * @param movep */ arc2(center: Vec3, fixp1: Vec3, movep: Vec3, ccw: boolean = false, normal?: Vec3) { this.radius = fixp1.distanceTo(center); this.center.copy(center); const v2 = movep.clone().sub(center); const v1 = fixp1.clone().sub(center); const jd = angle(v1, v2) } setFrom3Points(p0: Vec3, p1: Vec3, p2: Vec3, normal?: Vec3) { // if (pointsCollinear(p0, p1, p2)) // throw ("calcCircleFromThreePoint:三点共线或者距离太近"); const d1 = p1.clone().sub(p0) const d2 = p2.clone().sub(p0) const d1center = p1.clone().add(p0).multiplyScalar(0.5) const d2center = p2.clone().add(p0).multiplyScalar(0.5) normal = normal || d1.clone().cross(d2).normalize(); d1.applyAxisAngle(normal, Math.PI / 2); d2.applyAxisAngle(normal, Math.PI / 2); const line1 = new Line(d1center, d1center.clone().add(d1)); const line2 = new Line(d2center, d2center.clone().add(d2)); const center = line1.distanceLine(line2).closests![0]; const radiusSqr = p0.distanceToSquared(center) this.center = center; this.radiusSqr = radiusSqr; this.radius = Math.sqrt(radiusSqr); this.normal = normal; return this; } } export function circle(center?: Vec3, radius?: number, normal?: Vec3) { return new Circle(center, radius, normal); }