mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-10 02:13:58 +01:00
81 lines
No EOL
2.1 KiB
JavaScript
81 lines
No EOL
2.1 KiB
JavaScript
import {Ref} from './ref'
|
|
import {SketchObject} from './sketch-object'
|
|
import {Segment} from './segment'
|
|
import {LUT} from '../../math/bezier-cubic'
|
|
import {ConvexHull2D} from '../../math/convex-hull'
|
|
|
|
import * as draw_utils from '../shapes/draw-utils'
|
|
import * as math from '../../math/math';
|
|
|
|
|
|
export class BezierCurve extends SketchObject {
|
|
|
|
constructor(a, b, cp1, cp2) {
|
|
super();
|
|
this.a = a;
|
|
this.b = b;
|
|
this.cp1 = cp1;
|
|
this.cp2 = cp2;
|
|
|
|
this.addChild(new Segment(a, cp1));
|
|
this.addChild(new Segment(b, cp2));
|
|
for (let c of this.children) {
|
|
c.role = 'construction';
|
|
}
|
|
}
|
|
|
|
visitParams(callback) {
|
|
this.a.visitParams(callback);
|
|
this.b.visitParams(callback);
|
|
this.cp1.visitParams(callback);
|
|
this.cp2.visitParams(callback);
|
|
}
|
|
|
|
normalDistance(aim, scale) {
|
|
this.hull = ConvexHull2D([this.a, this.b, this.cp1, this.cp2]);
|
|
this.hull = math.polygonOffset(this.hull, 1 + (0.3 / scale));
|
|
if (math.isPointInsidePolygon(aim, this.hull)) {
|
|
this.lut = LUT(this.a, this.b, this.cp1, this.cp2, scale);
|
|
return this.closestNormalDistance(aim, this.lut)
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
closestNormalDistance(aim, segments) {
|
|
let hero = -1;
|
|
for (let p = segments.length - 1, q = 0; q < segments.length; p = q ++) {
|
|
const dist = Math.min(Segment.calcNormalDistance(aim, segments[p], segments[q]));
|
|
if (dist != -1) {
|
|
hero = hero == -1 ? dist : Math.min(dist, hero);
|
|
}
|
|
}
|
|
return hero;
|
|
}
|
|
|
|
drawImpl(ctx, scale, viewer) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(this.a.x, this.a.y);
|
|
ctx.bezierCurveTo(this.cp1.x, this.cp1.y, this.cp2.x, this.cp2.y, this.b.x, this.b.y);
|
|
ctx.stroke();
|
|
|
|
//debug lut and hull
|
|
//this.drawLUTAndHull();
|
|
}
|
|
|
|
drawLUTAndHull() {
|
|
if (this.lut) {
|
|
for (let p of this.lut) {
|
|
draw_utils.DrawPoint(ctx, p.x, p.y, 3, scale);
|
|
}
|
|
|
|
ctx.moveTo(this.hull[0].x, this.hull[0].y);
|
|
for (let p of this.hull) {
|
|
ctx.lineTo(p.x, p.y);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
BezierCurve.prototype._class = 'TCAD.TWO.BezierCurve';
|
|
|
|
const RECOVER_LENGTH = 100; |