@xtor/cga.js
Version:
Xtor Compute Geometry Algorithm Libary 计算几何算法库
78 lines (67 loc) • 2.7 kB
text/typescript
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);
}