交点计算函数
大约 6 分钟
交点计算函数
本章详细介绍 IntersectionCalculator 模块中的交点计算函数,包括算法原理和使用示例。
概述
IntersectionCalculator 提供了一系列底层交点计算函数,与 GeometryCalculator 的静态方法配合使用。这些函数支持更灵活的接口参数,包括轻量级几何对象。
import {
getArcLineIntersectionsEx,
getCircleLineIntersectionsAdvanced,
getCircleCircleIntersections,
getComplexLineIntersection,
getLineEntityIntersections
} from 'vjcad';直线相关交点
getComplexLineIntersection() - 复杂直线交点
根据不同的交点类型计算两条直线的交点,支持线段、延伸线、无限直线等多种模式。
function getComplexLineIntersection(
firstLine: LineEnt | ILineGeometry,
secondLine: LineEnt | ILineGeometry,
intersectionType: number
): Point2D | undefined参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
firstLine | LineEnt | ILineGeometry | 第一条直线 |
secondLine | LineEnt | ILineGeometry | 第二条直线 |
intersectionType | number | 交点类型(见下表) |
交点类型:
| 值 | 说明 |
|---|---|
| 0 | 线段与线段相交(两端点都在对方线段两侧) |
| 1 | 第一条线段延伸与第二条线段相交 |
| 2 | 第一条线段与第二条线段延伸相交 |
| 3 | 无限直线相交(忽略端点限制) |
示例:
import { getComplexLineIntersection, LineEnt, Point2D } from 'vjcad';
const line1 = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
const line2 = new LineEnt(new Point2D(0, 100), new Point2D(100, 0));
// 类型 0:线段相交
const intersection = getComplexLineIntersection(line1, line2, 0);
// intersection = Point2D(50, 50)
// 类型 3:无限直线相交(即使线段不相交也能找到延长线交点)
const line3 = new LineEnt(new Point2D(0, 0), new Point2D(10, 10));
const line4 = new LineEnt(new Point2D(100, 0), new Point2D(100, 10));
const extIntersection = getComplexLineIntersection(line3, line4, 3);
// extIntersection = Point2D(100, 100)算法原理:
- 检查两直线是否平行(通过标准化角度比较)
- 处理特殊情况:垂直线、水平线
- 计算一般情况下的交点(使用斜率-截距公式)
- 根据交点类型验证交点是否有效
getLineLineIntersections()
线段与射线/构造线的交点计算:
import { getLineLineIntersections, LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
const ray = { basePoint: new Point2D(50, 0), farPoint: new Point2D(50, 100) };
const intersections = getLineLineIntersections(line, ray);
// 返回 Point2D[]getLineExtLineExtIntersections()
两条延伸线(无限直线)的交点:
import { getLineExtLineExtIntersections, LineEnt, Point2D } from 'vjcad';
const line1 = new LineEnt(new Point2D(0, 0), new Point2D(10, 10));
const ray = { basePoint: new Point2D(100, 0), farPoint: new Point2D(100, 10) };
const intersections = getLineExtLineExtIntersections(line1, ray);圆与直线交点
getCircleLineIntersectionsAdvanced() - 高级版本
精确计算圆与直线的交点,处理所有边界情况(相切、相离、相交)。
function getCircleLineIntersectionsAdvanced(
circleEntity: CircleEnt | ICircleGeometry,
lineEntity: LineEnt | ILineGeometry
): Point2D[]算法原理:
- 将直线旋转到水平位置(简化计算)
- 计算直线到圆心的距离
- 使用反正弦函数计算交点角度
- 旋转回原坐标系
- 验证交点是否在线段范围内
示例:
import { getCircleLineIntersectionsAdvanced, CircleEnt, LineEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 30);
const line = new LineEnt(new Point2D(0, 50), new Point2D(100, 50));
const intersections = getCircleLineIntersectionsAdvanced(circle, line);
// intersections = [Point2D(20, 50), Point2D(80, 50)]getCircleLineIntersectionsSimple() - 简化版本
计算圆与无限直线的交点(不考虑线段端点限制):
import { getCircleLineIntersectionsSimple, CircleEnt, LineEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 30);
const line = new LineEnt(new Point2D(0, 50), new Point2D(10, 50));
// 即使线段很短,也能计算圆与延长线的交点
const intersections = getCircleLineIntersectionsSimple(circle, line);getLineCircleIntersections()
直线与圆的交点(考虑射线方向):
import { getLineCircleIntersections, 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 = getLineCircleIntersections(line, circle);圆与圆交点
getCircleCircleIntersections()
计算两个圆的交点。使用海伦公式计算三角形面积来确定交点位置。
function getCircleCircleIntersections(
firstCircle: CircleEnt | ICircleGeometry,
secondCircle: CircleEnt | ICircleGeometry
): Point2D[]位置关系:
| 情况 | 交点数量 |
|---|---|
| 两圆相离(d > r1 + r2) | 0 |
| 两圆外切(d = r1 + r2) | 1 |
| 两圆相交( | r1 - r2 |
| 两圆内切(d = | r1 - r2 |
| 两圆内含(d < | r1 - r2 |
| 同心圆(d = 0) | 0 |
算法原理:
- 计算两圆心距离 d
- 判断位置关系
- 使用海伦公式计算以两圆心和交点构成的三角形面积
- 通过三角形高度计算交点坐标
- 旋转到原坐标系
示例:
import { getCircleCircleIntersections, CircleEnt, Point2D } from 'vjcad';
const circle1 = new CircleEnt(new Point2D(0, 0), 50);
const circle2 = new CircleEnt(new Point2D(60, 0), 50);
const intersections = getCircleCircleIntersections(circle1, circle2);
// 返回两个交点
console.log(intersections.length); // 2圆弧相关交点
getArcLineIntersectionsEx()
计算圆弧与直线的交点,并过滤出在圆弧角度范围内的交点。
function getArcLineIntersectionsEx(
arcEntity: ArcEnt | IArcGeometry,
lineEntity: LineEnt | ILineGeometry
): Point2D[]算法原理:
- 先计算圆弧所在圆与直线的交点
- 对每个交点计算相对于圆心的角度
- 检查角度是否在圆弧的角度范围内
- 只返回在圆弧上的交点
示例:
import { getArcLineIntersectionsEx, ArcEnt, LineEnt, Point2D } from 'vjcad';
// 创建上半圆弧
const arc = new ArcEnt(new Point2D(50, 50), 30, 0, Math.PI);
const line = new LineEnt(new Point2D(0, 50), new Point2D(100, 50));
const intersections = getArcLineIntersectionsEx(arc, line);
// 只返回在圆弧上的交点(可能是 2 个、1 个或 0 个)getCircleArcIntersectionsFiltered()
计算圆与圆弧的交点(过滤角度范围):
import { getCircleArcIntersectionsFiltered, CircleEnt, ArcEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(0, 0), 50);
const arc = new ArcEnt(new Point2D(60, 0), 50, Math.PI / 2, Math.PI);
const intersections = getCircleArcIntersectionsFiltered(circle, arc);getArcCircleIntersections()
圆弧与圆的交点:
import { getArcCircleIntersections, ArcEnt, CircleEnt, Point2D } from 'vjcad';
const arc = new ArcEnt(new Point2D(0, 0), 50, 0, Math.PI);
const circle = new CircleEnt(new Point2D(60, 0), 50);
const intersections = getArcCircleIntersections(arc, circle);实体集合交点
这些函数计算单个几何实体与实体集合的交点,用于修剪、延伸等命令。
getLineEntityIntersections()
计算直线与实体集合中所有实体的交点:
function getLineEntityIntersections(
lineEntity: LineEnt | ILineGeometry,
entityCollection: IEntityCollection
): Point2D[]示例:
import { getLineEntityIntersections, LineEnt, PolylineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 50), new Point2D(200, 50));
const pline = new PolylineEnt();
// ... 设置多段线
const intersections = getLineEntityIntersections(line, pline);
// 返回直线与多段线所有线段/圆弧的交点getArcEntityIntersections()
计算圆弧与实体集合的交点:
import { getArcEntityIntersections, ArcEnt, PolylineEnt, Point2D } from 'vjcad';
const arc = new ArcEnt(new Point2D(50, 50), 30, 0, Math.PI);
const intersections = getArcEntityIntersections(arc, pline);getCircleEntityIntersections()
计算圆与实体集合的交点(完整版):
import { getCircleEntityIntersections, CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 30);
// 支持圆弧、圆、直线、射线
const intersections = getCircleEntityIntersections(circle, entityCollection);getCircleEntityIntersectionsSimple()
计算圆与实体集合的交点(简化版,只支持圆弧和直线):
import { getCircleEntityIntersectionsSimple } from 'vjcad';
const intersections = getCircleEntityIntersectionsSimple(circle, pline);扩展实体交点
getLineExtendedEntityIntersections()
计算直线与扩展实体集合的交点(支持圆弧、圆、直线、射线):
import { getLineExtendedEntityIntersections } from 'vjcad';
// entityCollection.getEnts_Ext() 返回扩展实体数组
const intersections = getLineExtendedEntityIntersections(line, entityCollection);getLineExtExtendedEntityIntersections()
计算直线延伸与扩展实体集合的交点:
import { getLineExtExtendedEntityIntersections } from 'vjcad';
const intersections = getLineExtExtendedEntityIntersections(line, entityCollection);getExtendedEntityPolylineIntersections()
计算扩展实体集合与多段线的交点:
import { getExtendedEntityPolylineIntersections, PolylineEnt } from 'vjcad';
const pline = new PolylineEnt();
// ...
const intersections = getExtendedEntityPolylineIntersections(entityCollection, pline);辅助函数
getLineIntersections()
计算直线与实体数组的交点并生成线段:
import { getLineIntersections, LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
const entities = [arc1, circle1, line2];
// 返回交点形成的线段数组(GLine 轻量级对象)
const segments = getLineIntersections(line, entities);接口定义
ILineGeometry
interface ILineGeometry {
startPoint: Point2D;
endPoint: Point2D;
angle: number;
}IArcGeometry
interface IArcGeometry {
center: Point2D;
radius: number;
startAng: number;
endAng: number;
innerAng?: number;
}ICircleGeometry
interface ICircleGeometry {
center: Point2D;
radius: number;
}IEntityCollection
interface IEntityCollection {
subGeometries?: SubGeometry[];
subEnts?: (LineEnt | ArcEnt | CircleEnt | EllipseEnt)[];
getSubEnts?: () => (LineEnt | ArcEnt | CircleEnt | EllipseEnt)[];
getEnts_Ext?: () => (LineEnt | ArcEnt | CircleEnt | RayEnt)[];
}使用建议
- 选择合适的函数:根据是否需要考虑端点限制选择
Advanced或Simple版本 - 使用轻量级接口:如果不需要完整实体功能,可以传入符合接口的普通对象
- 处理空结果:所有函数返回数组,可能为空,使用前检查长度
- 去重处理:多段线交点可能有重复,必要时使用
removeDuplicatePoints