complete offset tool

This commit is contained in:
Val Erastov 2017-01-05 00:35:24 -08:00
parent 14b06223b8
commit a5407d10b8
4 changed files with 43 additions and 44 deletions

View file

@ -127,6 +127,10 @@ export class Arc extends SketchObject {
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.b, this.c, this.r));
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.a, this.c, this.r));
}
copy() {
return new Arc(this.a.copy(), this.b.copy(), this.c.copy());
}
}
Arc.prototype._class = 'TCAD.TWO.Arc';

View file

@ -71,6 +71,10 @@ export class Segment extends SketchObject {
ctx.stroke();
// ctx.restore();
}
copy() {
return new Segment(this.a.copy(), this.b.copy());
}
}
Segment.prototype._class = 'TCAD.TWO.Segment';

View file

@ -85,5 +85,9 @@ export class SketchObject extends Shape {
this.drawImpl(ctx, scale, viewer);
if (this.marked != null) ctx.restore();
}
copy() {
throw 'method not implemented';
}
}

View file

@ -3,7 +3,6 @@ import {Constraints} from '../parametric'
import * as math from '../../math/math';
import Vector from '../../math/vector';
import {swap} from '../../utils/utils'
import ClipperLib from '../../../lib/clipper'
import {EndPoint} from '../shapes/point'
import {Arc} from '../shapes/arc'
@ -16,7 +15,7 @@ export class OffsetTool extends LoopPickTool {
onMousedown(e) {
const loopPoints = this.pickedLoop.points;
const loopEdges = this.pickedLoop.edges;
const length = loopPoints.length;
const length = loopEdges.length;
for (let obj of loopEdges) {
if (!SUPPORTED_OBJECTS.has(obj._class)) {
@ -29,58 +28,46 @@ export class OffsetTool extends LoopPickTool {
return;
}
const edges = [];
const startPoint = findLowestPoint(loopPoints);
const start = loopPoints.indexOf(startPoint);
if (start == -1) {
return;
}
const edges = loopEdges.map(e => e.copy());
const lowestPoint = findLowestPoint(loopPoints);
const low = loopPoints.indexOf(lowestPoint);
function pos(i) {
return (i + start) % length;
}
const inverse = this.twoConnectedArcs() || !math.isCCW([loopPoints[pos(0)], loopPoints[pos(1)], loopPoints[pos(length - 1)]]);
if (inverse) {
delta *= -1;
return (i + low) % length;
}
const mainInverse = !this.twoConnectedArcs() && math.isCCW([loopPoints[pos(0)], loopPoints[pos(1)], loopPoints[pos(length - 1)]]);
const pm = this.viewer.parametricManager;
const offsetConstant = createOffsetConstant(pm, delta);
for (let i = 0; i < length; ++i) {
let a = loopPoints[pos(i)];
let b = loopPoints[pos(i + 1)];
const normal = new Vector(-(b.y - a.y), (b.x - a.x))._normalize();
const offVector = normal._multiply(delta);
const origEdge = loopEdges[pos(i)];
const aOffX = a.x + offVector.x;
const aOffY = a.y + offVector.y;
const bOffX = b.x + offVector.x;
const bOffY = b.y + offVector.y;
if (origEdge._class == 'TCAD.TWO.Segment') {
const segment = this.viewer.addSegment(aOffX, aOffY,
bOffX, bOffY, this.viewer.activeLayer);
pm._add(new Constraints.Parallel(origEdge, segment));
pm._add(new Constraints.P2LDistanceSigned(a, segment.b, segment.a, offsetConstant));
edges.push(segment);
} else if (origEdge._class == 'TCAD.TWO.Arc') {
const connectionEdge = new SimpleEdge(new EndPoint(aOffX, aOffY), new EndPoint(bOffX, bOffY));
edges.push(connectionEdge);
const arcEdge = inverse ? connectionEdge.reverse() : connectionEdge;
const arc = new Arc(
arcEdge.a,
arcEdge.b,
new EndPoint(origEdge.c.x + offVector.x, origEdge.c.y + offVector.y)
);
arc.stabilize(this.viewer);
pm._linkObjects([arc.c, origEdge.c]);
pm._add(new Constraints.RadiusOffset(inverse?arc:origEdge, inverse?origEdge:arc, offsetConstant));
this.viewer.activeLayer.add(arc);
const edge = edges[i];
const origEdge = loopEdges[i];
const edgeInverse = loopPoints[i] != origEdge.a;
const inverse = mainInverse != edgeInverse;
this.viewer.activeLayer.add(edge);
if (edge._class == 'TCAD.TWO.Segment') {
pm._add(new Constraints.Parallel(origEdge, edge));
pm._add(new Constraints.P2LDistanceSigned(origEdge.a, inverse?edge.b:edge.a, inverse?edge.a:edge.b, offsetConstant));
} else if (edge._class == 'TCAD.TWO.Arc') {
edge.stabilize(this.viewer);
pm._linkObjects([edge.c, origEdge.c]);
pm._add(new Constraints.RadiusOffset(inverse?origEdge:edge, inverse?edge:origEdge, offsetConstant));
}
}
for (let i = 0; i < edges.length; i++) {
pm._linkObjects([edges[i].b, edges[(i + 1) % edges.length].a]);
const next = ((i + 1) % edges.length);
if (loopEdges[i].a.linked.indexOf(loopEdges[next].a) != -1) {
pm._linkObjects([edges[i].a, edges[next].a]);
} else if (loopEdges[i].a.linked.indexOf(loopEdges[next].b) != -1) {
pm._linkObjects([edges[i].a, edges[next].b]);
} else if (loopEdges[i].b.linked.indexOf(loopEdges[next].a) != -1) {
pm._linkObjects([edges[i].b, edges[next].a]);
} else if (loopEdges[i].b.linked.indexOf(loopEdges[next].b) != -1) {
pm._linkObjects([edges[i].b, edges[next].b]);
}
}
pm.solve(undefined, undefined, loopEdges);
pm.refresh();