Selection Detection
Selection Detection
This chapter introduces functions in WebCAD for selection-rectangle intersection detection. These functions are used to implement both Window and Cross selection.
Overview
Selection-detection functions determine whether an entity intersects a selection rectangle or is contained within it. Two selection modes are supported:
- Window: an entity must be completely inside the selection rectangle to be selected
- Cross: an entity is selected if it intersects the rectangle or is contained within it
import {
findIntersections,
checkPolylineIntersection,
checkHatchIntersection,
checkPatternHatchIntersection,
checkTextBoundsIntersection,
checkGroupIntersection,
check3DBoundingBoxIntersection,
calculateBoundingBoxFromPoints
} from 'vjcad';findIntersections() - Entity Intersection Calculation
Calculates all intersections between a target entity and other entities, returning an array of SnapPoint objects used for snapping.
function findIntersections(
targetEntity: EntityBase,
otherEntities: EntityBase[]
): SnapPoint[]Supported Entity Types
LINEARCCIRCLERAYXLINE
Example
import { findIntersections, LineEnt, CircleEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 50), new Point2D(100, 50));
const circle = new CircleEnt(new Point2D(50, 50), 30);
const intersections = findIntersections(line, [circle]);
for (const snapPoint of intersections) {
console.log('Intersection type:', snapPoint.type); // "Int"
console.log('Intersection point:', snapPoint.point); // DCS coordinate
}Features
- Returned coordinates are in device coordinate system (
DCS) - Avoids duplicate calculations through ID comparison
- Supports self-intersection checks when ID is
0
checkPolylineIntersection() - Polyline Intersection Detection
Checks whether a polyline intersects the selection boundary.
function checkPolylineIntersection(
polylineEntity: PolylineEnt,
selectionBounds: BoundingBox,
selectionMode: string // "Window" | "Cross"
): booleanExample
import { checkPolylineIntersection, PolylineEnt, BoundingBox, Point2D } from 'vjcad';
const pline = new PolylineEnt();
// ... configure polyline
const selectionBox = new BoundingBox(
new Point2D(0, 0),
new Point2D(100, 100)
);
// Window selection mode
const inWindow = checkPolylineIntersection(pline, selectionBox, 'Window');
// Cross selection mode
const crosses = checkPolylineIntersection(pline, selectionBox, 'Cross');Algorithm
- Iterate through all geometry segments of the polyline, including lines and arcs
- Collect the bounding box of each segment
- Merge the bounding boxes
- Window mode: check whether the merged bounding box is fully inside the selection box
- Cross mode: check whether any segment intersects the selection box boundary
checkHatchIntersection() - Hatch Intersection Detection
Checks whether a hatch entity intersects the selection boundary.
function checkHatchIntersection(
hatchEntity: HatchEnt,
selectionBounds: BoundingBox,
selectionMode: string,
corner1: Point2D,
corner2: Point2D,
corner3: Point2D,
corner4: Point2D
): booleanParameters
| Parameter | Description |
|---|---|
hatchEntity | Hatch entity |
selectionBounds | Selection bounding box |
selectionMode | "Window" or "Cross" |
corner1-4 | Four corner points of the selection box, used for precise intersection testing |
Example
import { checkHatchIntersection, HatchEnt, BoundingBox, Point2D } from 'vjcad';
const hatch = new HatchEnt();
// ... configure hatch
const bounds = new BoundingBox(new Point2D(0, 0), new Point2D(100, 100));
const c1 = new Point2D(0, 0);
const c2 = new Point2D(100, 0);
const c3 = new Point2D(100, 100);
const c4 = new Point2D(0, 100);
const isSelected = checkHatchIntersection(
hatch, bounds, 'Cross',
c1, c2, c3, c4
);Algorithm
- Get all loops of the hatch
- Collect the bulge points of each loop
- Convert them to
DCS - Window mode: check whether all points are inside the selection box
- Cross mode: check whether any loop edge intersects the selection box edge
checkPatternHatchIntersection() - Pattern Hatch Intersection Detection
Checks whether a pattern hatch, rather than a solid hatch, intersects the selection boundary.
function checkPatternHatchIntersection(
hatchEntity: HatchEnt,
selectionBounds: BoundingBox,
selectionMode: string,
corner1: Point2D,
corner2: Point2D,
corner3: Point2D,
corner4: Point2D
): booleanDifference from checkHatchIntersection()
- Uses
getPatternEnts()to obtain pattern line segments - Checks whether each pattern line intersects the selection rectangle
- Suitable for non-solid hatch patterns such as ANSI or ISO patterns
Example
const hatch = new HatchEnt();
hatch.patternName = 'ANSI31'; // Pattern hatch
const isSelected = checkPatternHatchIntersection(
hatch, bounds, 'Cross',
c1, c2, c3, c4
);checkTextBoundsIntersection() - Text Intersection Detection
Checks whether a text entity (TextEnt or MTextEnt) intersects the selection boundary.
function checkTextBoundsIntersection(
entity: MTextEnt | TextEnt,
selectionBounds: BoundingBox,
selectionMode: string
): booleanExample
import { checkTextBoundsIntersection, TextEnt, BoundingBox, Point2D } from 'vjcad';
const text = new TextEnt();
text.position = new Point2D(50, 50);
text.textString = 'Hello';
const bounds = new BoundingBox(new Point2D(0, 0), new Point2D(100, 100));
const isSelected = checkTextBoundsIntersection(text, bounds, 'Window');Algorithm
- Get the inner corner points of the text with
getInnerCornerPoints() - Convert them to
DCS - Use quadrilateral-rectangle intersection testing
- Window mode: all corner points must lie inside the selection box
- Cross mode: any text corner is inside the box, or any box corner is inside the text area, or the edges intersect
checkGroupIntersection() - Group Intersection Detection
Checks whether a group entity intersects the selection boundary.
function checkGroupIntersection(
groupEntity: GroupEnt,
selectionBounds: BoundingBox,
selectionMode: string,
corner1: Point2D,
corner2: Point2D,
corner3: Point2D,
corner4: Point2D
): booleanExample
import { checkGroupIntersection, GroupEnt, BoundingBox, Point2D } from 'vjcad';
const group = new GroupEnt();
// ... add child entities
const bounds = new BoundingBox(new Point2D(0, 0), new Point2D(100, 100));
const isSelected = checkGroupIntersection(
group, bounds, 'Cross',
c1, c2, c3, c4
);Algorithm
- Get all child entities in the group
- Window mode: all child entities must be inside the selection box
- Cross mode: any child entity intersecting the selection box is enough
- Supports recursive detection of nested groups
Supported Child Entity Types
LINEARCCIRCLEPLINEHATCHTEXT/MTEXTGROUPCUSTOM
check3DBoundingBoxIntersection() - 3D Bounding Box Intersection
Checks whether a 3D bounding box intersects a window in special scenarios.
function check3DBoundingBoxIntersection(
boundingBoxMin: BoundingBox,
boundingBoxMax: BoundingBox,
corner1: Point2D,
corner2: Point2D,
corner3: Point2D,
corner4: Point2D,
corner5: Point2D,
corner6: Point2D,
corner7: Point2D,
corner8: Point2D
): booleancalculateBoundingBoxFromPoints() - Bounding Box from Points
Calculates the minimal enclosing bounding box from an array of points.
function calculateBoundingBoxFromPoints(points: Point2D[]): BoundingBoxExample
import { calculateBoundingBoxFromPoints, Point2D } from 'vjcad';
const points = [
new Point2D(10, 20),
new Point2D(50, 80),
new Point2D(30, 10),
new Point2D(90, 50)
];
const bbox = calculateBoundingBoxFromPoints(points);
console.log(bbox.minX); // 10
console.log(bbox.maxX); // 90
console.log(bbox.minY); // 10
console.log(bbox.maxY); // 80Special Cases
- Empty array returns an origin box
(0, 0) - (0, 0) - A single point returns the bounding box of that point
Line and Arc Intersection Helpers
findLineArcIntersections()
Calculates intersections between a line and an arc:
function findLineArcIntersections(
lineEntity: EntityBase,
arcEntity: EntityBase
): SnapPoint[]findLineCircleIntersections()
Calculates intersections between a line and a circle:
function findLineCircleIntersections(
lineEntity: EntityBase,
circleEntity: EntityBase
): SnapPoint[]Usage Examples
Implement a Selection Command
import {
checkPolylineIntersection,
checkHatchIntersection,
checkTextBoundsIntersection,
checkGroupIntersection,
BoundingBox,
Point2D,
Engine
} from 'vjcad';
function selectEntitiesInBox(
selectionBox: BoundingBox,
mode: 'Window' | 'Cross'
): EntityBase[] {
const entities = Engine.currentSpace.items;
const selected: EntityBase[] = [];
// Compute selection-box corners
const c1 = selectionBox.BL;
const c2 = selectionBox.BR;
const c3 = selectionBox.TR;
const c4 = selectionBox.TL;
for (const entity of entities) {
let isSelected = false;
switch (entity.type) {
case 'PLINE':
case 'LWPOLYLINE':
isSelected = checkPolylineIntersection(entity, selectionBox, mode);
break;
case 'HATCH':
isSelected = checkHatchIntersection(
entity, selectionBox, mode,
c1, c2, c3, c4
);
break;
case 'TEXT':
case 'MTEXT':
isSelected = checkTextBoundsIntersection(entity, selectionBox, mode);
break;
case 'GROUP':
isSelected = checkGroupIntersection(
entity, selectionBox, mode,
c1, c2, c3, c4
);
break;
default:
// Other entities use bounding-box detection
const bbox = entity.boundingBox();
if (mode === 'Window') {
isSelected = boxContains(selectionBox, bbox);
} else {
isSelected = boxesIntersect(selectionBox, bbox);
}
}
if (isSelected) {
selected.push(entity);
}
}
return selected;
}Highlight Intersections
import { findIntersections, Engine } from 'vjcad';
function highlightIntersections(entity: EntityBase) {
const allEntities = Engine.currentSpace.items;
const otherEntities = allEntities.filter(e => e !== entity);
const intersections = findIntersections(entity, otherEntities);
for (const snapPoint of intersections) {
// Show marker at intersection
drawMarker(snapPoint.point);
}
}Coordinate System Notes
Selection-detection functions usually work in the device coordinate system (DCS):
- Convert world coordinates to device coordinates
- Perform intersection tests in
DCS - Returned results are also in
DCS
// WCS to DCS
const dcsPoint = Engine.trans.WcsToDcs(wcsPoint);
// DCS to WCS
const wcsPoint = Engine.trans.DcsToWcs(dcsPoint);Next Steps
- Bounding Box -
BoundingBoxoperations - Intersection Calculation - intersection functions
- Entity System -
EntityBasebase class