mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 03:38:11 +08:00
Handle intersections between two bezier curves (#735)
* Refactor intersections function * Implement intersect for quadratic and cubic bezier curves * Return t value instead of point * Change project return the t value * Add error threshold for curve intersection * Refactor to use if let statements and improve comments * Refactor intersection helper to return vector, other minor name/text changes * Rename function * Minor change * Minor fixes * Add missing test tag * Address comments * Adjust comment * Change function call * Edit comments
This commit is contained in:
committed by
Keavon Chambers
parent
8c1e6455eb
commit
c00f520351
@@ -269,7 +269,8 @@ export default defineComponent({
|
||||
callback: (canvas: HTMLCanvasElement, bezier: WasmBezierInstance, options: Record<string, number>, mouseLocation?: Point): void => {
|
||||
if (mouseLocation != null) {
|
||||
const context = getContextFromCanvas(canvas);
|
||||
const closestPoint = JSON.parse(bezier.project(mouseLocation.x, mouseLocation.y));
|
||||
const t = bezier.project(mouseLocation.x, mouseLocation.y);
|
||||
const closestPoint = JSON.parse(bezier.evaluate(t));
|
||||
drawLine(context, mouseLocation, closestPoint, COLORS.NON_INTERACTIVE.STROKE_1);
|
||||
}
|
||||
},
|
||||
@@ -376,7 +377,7 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Intersect Line Segment",
|
||||
name: "Intersect (Line Segment)",
|
||||
callback: (canvas: HTMLCanvasElement, bezier: WasmBezierInstance): void => {
|
||||
const context = getContextFromCanvas(canvas);
|
||||
const line = [
|
||||
@@ -385,12 +386,44 @@ export default defineComponent({
|
||||
];
|
||||
const mappedLine = line.map((p) => [p.x, p.y]);
|
||||
drawLine(context, line[0], line[1], COLORS.NON_INTERACTIVE.STROKE_1);
|
||||
const intersections: Point[] = bezier.intersect_line_segment(mappedLine).map((p) => JSON.parse(p));
|
||||
intersections.forEach((p: Point) => {
|
||||
const intersections: Float64Array = bezier.intersect_line_segment(mappedLine);
|
||||
intersections.forEach((t: number) => {
|
||||
const p = JSON.parse(bezier.evaluate(t));
|
||||
drawPoint(context, p, 3, COLORS.NON_INTERACTIVE.STROKE_2);
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Intersect (Cubic Segment)",
|
||||
callback: (canvas: HTMLCanvasElement, bezier: WasmBezierInstance, options: Record<string, number>): void => {
|
||||
const context = getContextFromCanvas(canvas);
|
||||
const points = [
|
||||
{ x: 40, y: 20 },
|
||||
{ x: 100, y: 40 },
|
||||
{ x: 40, y: 120 },
|
||||
{ x: 175, y: 140 },
|
||||
];
|
||||
const mappedPoints = points.map((p) => [p.x, p.y]);
|
||||
drawCurve(context, points, COLORS.NON_INTERACTIVE.STROKE_1, 1);
|
||||
const intersections: Float64Array = bezier.intersect_cubic_segment(mappedPoints, options.error);
|
||||
intersections.forEach((t: number) => {
|
||||
const p = JSON.parse(bezier.evaluate(t));
|
||||
drawPoint(context, p, 3, COLORS.NON_INTERACTIVE.STROKE_2);
|
||||
});
|
||||
},
|
||||
template: markRaw(SliderExample),
|
||||
templateOptions: {
|
||||
sliders: [
|
||||
{
|
||||
variable: "error",
|
||||
min: 0.1,
|
||||
max: 2,
|
||||
step: 0.1,
|
||||
default: 0.5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Reduce",
|
||||
callback: (canvas: HTMLCanvasElement, bezier: WasmBezierInstance): void => {
|
||||
|
||||
@@ -59,9 +59,9 @@ export const drawText = (ctx: CanvasRenderingContext2D, text: string, x: number,
|
||||
ctx.fillText(text, x, y);
|
||||
};
|
||||
|
||||
export const drawCurve = (ctx: CanvasRenderingContext2D, points: Point[], strokeColor = COLORS.INTERACTIVE.STROKE_1): void => {
|
||||
export const drawCurve = (ctx: CanvasRenderingContext2D, points: Point[], strokeColor = COLORS.INTERACTIVE.STROKE_1, lineWidth = 2): void => {
|
||||
ctx.strokeStyle = strokeColor;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(points[0].x, points[0].y);
|
||||
|
||||
Reference in New Issue
Block a user