2026-06-26 17:48:24 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* geometry.ts Tests – Pure transformation functions (move, rotate, scale, mirror)
|
|
|
|
|
|
*/
|
|
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
|
|
|
|
import {
|
|
|
|
|
|
moveElement,
|
|
|
|
|
|
rotateElement,
|
|
|
|
|
|
scaleElement,
|
|
|
|
|
|
mirrorElement,
|
|
|
|
|
|
offsetElement,
|
|
|
|
|
|
getElementBBox,
|
|
|
|
|
|
distance,
|
2026-08-26 13:47:25 +02:00
|
|
|
|
lineCircleIntersections,
|
|
|
|
|
|
circleCircleIntersections,
|
|
|
|
|
|
lineArcIntersection,
|
2026-06-26 17:48:24 +02:00
|
|
|
|
angleBetween,
|
|
|
|
|
|
} from '../src/tools/modification/geometry';
|
|
|
|
|
|
import type { CADElement } from '../src/types/cad.types';
|
|
|
|
|
|
|
|
|
|
|
|
function makeLine(id: string, x1: number, y1: number, x2: number, y2: number): CADElement {
|
|
|
|
|
|
return {
|
|
|
|
|
|
id,
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
layerId: 'layer-1',
|
|
|
|
|
|
x: (x1 + x2) / 2,
|
|
|
|
|
|
y: (y1 + y2) / 2,
|
|
|
|
|
|
width: Math.abs(x2 - x1),
|
|
|
|
|
|
height: Math.abs(y2 - y1),
|
|
|
|
|
|
properties: { x1, y1, x2, y2 },
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function makeRect(id: string, cx: number, cy: number, w: number, h: number): CADElement {
|
|
|
|
|
|
return {
|
|
|
|
|
|
id,
|
|
|
|
|
|
type: 'rect',
|
|
|
|
|
|
layerId: 'layer-1',
|
|
|
|
|
|
x: cx,
|
|
|
|
|
|
y: cy,
|
|
|
|
|
|
width: w,
|
|
|
|
|
|
height: h,
|
|
|
|
|
|
properties: {},
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function makeCircle(id: string, cx: number, cy: number, r: number): CADElement {
|
|
|
|
|
|
return {
|
|
|
|
|
|
id,
|
|
|
|
|
|
type: 'circle',
|
|
|
|
|
|
layerId: 'layer-1',
|
|
|
|
|
|
x: cx,
|
|
|
|
|
|
y: cy,
|
|
|
|
|
|
width: r * 2,
|
|
|
|
|
|
height: r * 2,
|
|
|
|
|
|
properties: { radius: r },
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function makePolyline(id: string, points: Array<{x:number;y:number}>): CADElement {
|
|
|
|
|
|
const xs = points.map(p => p.x);
|
|
|
|
|
|
const ys = points.map(p => p.y);
|
|
|
|
|
|
return {
|
|
|
|
|
|
id,
|
|
|
|
|
|
type: 'polyline',
|
|
|
|
|
|
layerId: 'layer-1',
|
|
|
|
|
|
x: (Math.min(...xs) + Math.max(...xs)) / 2,
|
|
|
|
|
|
y: (Math.min(...ys) + Math.max(...ys)) / 2,
|
|
|
|
|
|
width: Math.max(...xs) - Math.min(...xs),
|
|
|
|
|
|
height: Math.max(...ys) - Math.min(...ys),
|
|
|
|
|
|
properties: { points },
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – moveElement', () => {
|
|
|
|
|
|
it('should shift x and y by dx, dy', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
const moved = moveElement(el, 50, 30);
|
|
|
|
|
|
expect(moved.x).toBe(150);
|
|
|
|
|
|
expect(moved.y).toBe(130);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should shift line endpoint properties', () => {
|
|
|
|
|
|
const el = makeLine('l1', 0, 0, 100, 0);
|
|
|
|
|
|
const moved = moveElement(el, 50, 30);
|
|
|
|
|
|
expect(moved.properties.x1).toBe(50);
|
|
|
|
|
|
expect(moved.properties.y1).toBe(30);
|
|
|
|
|
|
expect(moved.properties.x2).toBe(150);
|
|
|
|
|
|
expect(moved.properties.y2).toBe(30);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should shift polyline points', () => {
|
|
|
|
|
|
const el = makePolyline('p1', [{ x: 0, y: 0 }, { x: 100, y: 50 }]);
|
|
|
|
|
|
const moved = moveElement(el, 10, 20);
|
|
|
|
|
|
expect(moved.properties.points![0].x).toBe(10);
|
|
|
|
|
|
expect(moved.properties.points![0].y).toBe(20);
|
|
|
|
|
|
expect(moved.properties.points![1].x).toBe(110);
|
|
|
|
|
|
expect(moved.properties.points![1].y).toBe(70);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should not modify the original element (immutability)', () => {
|
|
|
|
|
|
const el = makeLine('l1', 0, 0, 100, 0);
|
|
|
|
|
|
const original = JSON.parse(JSON.stringify(el));
|
|
|
|
|
|
moveElement(el, 50, 50);
|
|
|
|
|
|
expect(el).toEqual(original);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – rotateElement', () => {
|
|
|
|
|
|
it('should rotate element position around center', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 0, 40, 40);
|
|
|
|
|
|
const rotated = rotateElement(el, 0, 0, 90);
|
|
|
|
|
|
expect(rotated.x).toBeCloseTo(0, 0);
|
|
|
|
|
|
expect(rotated.y).toBeCloseTo(100, 0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should rotate line endpoints around center', () => {
|
|
|
|
|
|
const el = makeLine('l1', 100, 0, 200, 0);
|
|
|
|
|
|
const rotated = rotateElement(el, 0, 0, 90);
|
|
|
|
|
|
expect(rotated.properties.x1).toBeCloseTo(0, 0);
|
|
|
|
|
|
expect(rotated.properties.y1).toBeCloseTo(100, 0);
|
|
|
|
|
|
expect(rotated.properties.x2).toBeCloseTo(0, 0);
|
|
|
|
|
|
expect(rotated.properties.y2).toBeCloseTo(200, 0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should rotate 180 degrees correctly', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 0, 40, 40);
|
|
|
|
|
|
const rotated = rotateElement(el, 0, 0, 180);
|
|
|
|
|
|
expect(rotated.x).toBeCloseTo(-100, 0);
|
|
|
|
|
|
expect(rotated.y).toBeCloseTo(0, 0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should rotate 360 degrees back to original position', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 0, 40, 40);
|
|
|
|
|
|
const rotated = rotateElement(el, 0, 0, 360);
|
|
|
|
|
|
expect(rotated.x).toBeCloseTo(100, 5);
|
|
|
|
|
|
expect(rotated.y).toBeCloseTo(0, 5);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should swap width/height for 90-degree rotation on rect', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 80, 40);
|
|
|
|
|
|
const rotated = rotateElement(el, 100, 100, 90);
|
|
|
|
|
|
expect(rotated.width).toBe(40);
|
|
|
|
|
|
expect(rotated.height).toBe(80);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should add rotation to properties.rotation', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
el.properties.rotation = 30;
|
|
|
|
|
|
const rotated = rotateElement(el, 100, 100, 45);
|
|
|
|
|
|
expect(rotated.properties.rotation).toBe(75);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should not modify the original element', () => {
|
|
|
|
|
|
const el = makeLine('l1', 100, 0, 200, 0);
|
|
|
|
|
|
const original = JSON.parse(JSON.stringify(el));
|
|
|
|
|
|
rotateElement(el, 0, 0, 90);
|
|
|
|
|
|
expect(el).toEqual(original);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – scaleElement', () => {
|
|
|
|
|
|
it('should scale element position and dimensions', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
const scaled = scaleElement(el, 100, 100, 2, 2);
|
|
|
|
|
|
expect(scaled.x).toBe(100);
|
|
|
|
|
|
expect(scaled.y).toBe(100);
|
|
|
|
|
|
expect(scaled.width).toBe(80);
|
|
|
|
|
|
expect(scaled.height).toBe(80);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should scale element away from center', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 0, 40, 40);
|
|
|
|
|
|
const scaled = scaleElement(el, 0, 0, 2, 2);
|
|
|
|
|
|
expect(scaled.x).toBe(200);
|
|
|
|
|
|
expect(scaled.y).toBe(0);
|
|
|
|
|
|
expect(scaled.width).toBe(80);
|
|
|
|
|
|
expect(scaled.height).toBe(80);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should scale line endpoints', () => {
|
|
|
|
|
|
const el = makeLine('l1', 100, 0, 200, 0);
|
|
|
|
|
|
const scaled = scaleElement(el, 0, 0, 2, 2);
|
|
|
|
|
|
expect(scaled.properties.x1).toBe(200);
|
|
|
|
|
|
expect(scaled.properties.x2).toBe(400);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should scale circle radius', () => {
|
|
|
|
|
|
const el = makeCircle('c1', 100, 100, 40);
|
|
|
|
|
|
const scaled = scaleElement(el, 100, 100, 2, 2);
|
|
|
|
|
|
expect(scaled.properties.radius).toBe(80);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should not modify the original element', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
const original = JSON.parse(JSON.stringify(el));
|
|
|
|
|
|
scaleElement(el, 100, 100, 2, 2);
|
|
|
|
|
|
expect(el).toEqual(original);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – mirrorElement', () => {
|
|
|
|
|
|
it('should mirror across a vertical line', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 0, 40, 40);
|
|
|
|
|
|
const mirrored = mirrorElement(el, 200, 0, 200, 100);
|
|
|
|
|
|
expect(mirrored.x).toBe(300);
|
|
|
|
|
|
expect(mirrored.y).toBe(0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should mirror across a horizontal line', () => {
|
|
|
|
|
|
const el = makeRect('r1', 0, 100, 40, 40);
|
|
|
|
|
|
const mirrored = mirrorElement(el, 0, 200, 100, 200);
|
|
|
|
|
|
expect(mirrored.x).toBe(0);
|
|
|
|
|
|
expect(mirrored.y).toBe(300);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should mirror line endpoints', () => {
|
|
|
|
|
|
const el = makeLine('l1', 0, 0, 100, 0);
|
|
|
|
|
|
const mirrored = mirrorElement(el, 50, 0, 50, 100);
|
|
|
|
|
|
expect(mirrored.properties.x1).toBe(100);
|
|
|
|
|
|
expect(mirrored.properties.x2).toBe(0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should return element unchanged for zero-length mirror axis', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
const mirrored = mirrorElement(el, 50, 50, 50, 50);
|
|
|
|
|
|
expect(mirrored.x).toBe(100);
|
|
|
|
|
|
expect(mirrored.y).toBe(100);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should not modify the original element', () => {
|
|
|
|
|
|
const el = makeLine('l1', 0, 0, 100, 0);
|
|
|
|
|
|
const original = JSON.parse(JSON.stringify(el));
|
|
|
|
|
|
mirrorElement(el, 50, 0, 50, 100);
|
|
|
|
|
|
expect(el).toEqual(original);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – offsetElement', () => {
|
|
|
|
|
|
it('should offset a line perpendicularly', () => {
|
|
|
|
|
|
const el = makeLine('l1', 0, 0, 100, 0);
|
|
|
|
|
|
const offset = offsetElement(el, 10);
|
|
|
|
|
|
expect(offset.properties.y1).toBe(10);
|
|
|
|
|
|
expect(offset.properties.y2).toBe(10);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should offset a circle radius', () => {
|
|
|
|
|
|
const el = makeCircle('c1', 100, 100, 40);
|
|
|
|
|
|
const offset = offsetElement(el, 10);
|
|
|
|
|
|
expect(offset.properties.radius).toBe(50);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should return element for unknown type', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 40);
|
|
|
|
|
|
const offset = offsetElement(el, 10);
|
|
|
|
|
|
expect(offset.x).toBe(100);
|
|
|
|
|
|
expect(offset.y).toBe(100);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – getElementBBox', () => {
|
|
|
|
|
|
it('should return bbox for rect element', () => {
|
|
|
|
|
|
const el = makeRect('r1', 100, 100, 40, 60);
|
|
|
|
|
|
const bb = getElementBBox(el);
|
|
|
|
|
|
expect(bb.minX).toBe(80);
|
|
|
|
|
|
expect(bb.minY).toBe(70);
|
|
|
|
|
|
expect(bb.maxX).toBe(120);
|
|
|
|
|
|
expect(bb.maxY).toBe(130);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should return bbox for polyline element from points', () => {
|
|
|
|
|
|
const el = makePolyline('p1', [{ x: 10, y: 20 }, { x: 100, y: 80 }]);
|
|
|
|
|
|
const bb = getElementBBox(el);
|
|
|
|
|
|
expect(bb.minX).toBe(10);
|
|
|
|
|
|
expect(bb.minY).toBe(20);
|
|
|
|
|
|
expect(bb.maxX).toBe(100);
|
|
|
|
|
|
expect(bb.maxY).toBe(80);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – distance', () => {
|
|
|
|
|
|
it('should calculate distance between two points', () => {
|
|
|
|
|
|
expect(distance({ x: 0, y: 0 }, { x: 3, y: 4 })).toBe(5);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should return 0 for same point', () => {
|
|
|
|
|
|
expect(distance({ x: 5, y: 5 }, { x: 5, y: 5 })).toBe(0);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – angleBetween', () => {
|
|
|
|
|
|
it('should calculate angle between two points in degrees', () => {
|
|
|
|
|
|
expect(angleBetween({ x: 0, y: 0 }, { x: 100, y: 0 })).toBe(0);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should calculate 90-degree angle', () => {
|
|
|
|
|
|
expect(angleBetween({ x: 0, y: 0 }, { x: 0, y: 100 })).toBe(90);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
2026-08-26 13:47:25 +02:00
|
|
|
|
|
|
|
|
|
|
describe('geometry – lineCircleIntersections', () => {
|
|
|
|
|
|
const p1 = { x: 0, y: 0 };
|
|
|
|
|
|
const p2 = { x: 200, y: 0 };
|
|
|
|
|
|
const c = { x: 100, y: 0 };
|
|
|
|
|
|
|
|
|
|
|
|
it('findet zwei Schnittpunkte bei Sekante', () => {
|
|
|
|
|
|
const pts = lineCircleIntersections(p1, p2, c, 40);
|
|
|
|
|
|
expect(pts.length).toBe(2);
|
|
|
|
|
|
const xs = pts.map((p) => Math.round(p.x)).sort((a, b) => a - b);
|
|
|
|
|
|
expect(xs).toEqual([60, 140]);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('findet genau einen Punkt bei Tangente', () => {
|
|
|
|
|
|
// Strecke entlang y=40 tangiert Kreis (100,0,r=40)
|
|
|
|
|
|
const pts = lineCircleIntersections({ x: 50, y: 40 }, { x: 150, y: 40 }, { x: 100, y: 0 }, 40);
|
|
|
|
|
|
expect(pts.length).toBe(1);
|
|
|
|
|
|
expect(pts[0].x).toBeCloseTo(100);
|
|
|
|
|
|
expect(pts[0].y).toBeCloseTo(40);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('liefert leeres Array ohne Schnitt (Diskriminante < 0)', () => {
|
|
|
|
|
|
expect(lineCircleIntersections(p1, p2, { x: 100, y: 500 }, 10)).toEqual([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('respektiert Segmentgrenzen t∈[0,1] (Verlaengerung schneidet nicht)', () => {
|
|
|
|
|
|
// Kreis liegt hinter dem Endpunkt der Strecke
|
|
|
|
|
|
expect(lineCircleIntersections({ x: 0, y: 0 }, { x: 50, y: 0 }, { x: 100, y: 0 }, 30)).toEqual([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – circleCircleIntersections', () => {
|
|
|
|
|
|
it('findet zwei Punkte bei Ueberlappung', () => {
|
|
|
|
|
|
const pts = circleCircleIntersections({ x: 0, y: 0 }, 50, { x: 80, y: 0 }, 50);
|
|
|
|
|
|
expect(pts.length).toBe(2);
|
|
|
|
|
|
for (const pt of pts) {
|
|
|
|
|
|
expect(pt.x).toBeCloseTo(40); // Symmetrieachse
|
|
|
|
|
|
expect(Math.abs(pt.y)).toBeCloseTo(30); // Höhe via Satz des Pythagoras
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('liefert einen Punkt bei Tangenz', () => {
|
|
|
|
|
|
const pts = circleCircleIntersections({ x: 0, y: 0 }, 50, { x: 100, y: 0 }, 50);
|
|
|
|
|
|
expect(pts.length).toBe(1);
|
|
|
|
|
|
expect(pts[0]).toEqual({ x: 50, y: 0 });
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('liefert leer bei getrennten Kreisen und identischen Zentren', () => {
|
|
|
|
|
|
expect(circleCircleIntersections({ x: 0, y: 0 }, 20, { x: 500, y: 0 }, 20)).toEqual([]);
|
|
|
|
|
|
expect(circleCircleIntersections({ x: 0, y: 0 }, 20, { x: 0, y: 0 }, 20)).toEqual([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('geometry – lineArcIntersection', () => {
|
|
|
|
|
|
function makeArc(id: string, cx: number, cy: number, r: number, startDeg: number, endDeg: number): CADElement {
|
|
|
|
|
|
return {
|
|
|
|
|
|
id,
|
|
|
|
|
|
type: 'arc',
|
|
|
|
|
|
layerId: 'layer-1',
|
|
|
|
|
|
x: cx,
|
|
|
|
|
|
y: cy,
|
|
|
|
|
|
width: r * 2,
|
|
|
|
|
|
height: r * 2,
|
|
|
|
|
|
properties: { radius: r, startAngle: startDeg, endAngle: endDeg },
|
|
|
|
|
|
} as unknown as CADElement;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
it('schneidet Strecke mit Halbkreis (0°..180°)', () => {
|
|
|
|
|
|
const arc = makeArc('a1', 100, 0, 40, 0, 180); // obere Hälfte (CCW von 3Uhr)
|
|
|
|
|
|
const pts = lineArcIntersection({ x: 60, y: 0 }, { x: 140, y: 40 }, arc);
|
|
|
|
|
|
// Linie von (60,0) nach (140,40): schneidet Bogen einmal oben
|
|
|
|
|
|
expect(pts.length).toBeGreaterThanOrEqual(1);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('filtert Treffer außerhalb des Winkelbereichs heraus', () => {
|
|
|
|
|
|
const arc = makeArc('a2', 100, 0, 40, 180, 360); // untere Hälfte
|
|
|
|
|
|
// Strecke verläuft komplett oberhalb der Mittellinie → Schnitte lägen nur
|
|
|
|
|
|
// im oberen Halbkreis (Winkel < 180°), der nicht Teil des Bogens ist.
|
|
|
|
|
|
const pts = lineArcIntersection({ x: 60, y: 20 }, { x: 140, y: 40 }, arc);
|
|
|
|
|
|
expect(pts).toEqual([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('liefert leer bei fehlendem Radius (ungueltiges Element)', () => {
|
|
|
|
|
|
const bad = { id: 'x', type: 'arc', layerId: 'l', x: 0, y: 0, width: 0, height: 0, properties: {} } as unknown as CADElement;
|
|
|
|
|
|
expect(lineArcIntersection({ x: -10, y: -10 }, { x: 10, y: 10 }, bad)).toEqual([]);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|