圆实体 (CircleEnt)
大约 8 分钟
圆实体 (CircleEnt)
CircleEnt 表示 CAD 中的圆形实体,由圆心和半径完全确定。
在线示例
| 示例 | 描述 | 链接 |
|---|---|---|
| 创建圆 | CircleEnt 基本创建示例 | 在线演示{target="_blank"} |
| 圆属性 | 获取圆半径、面积、周长 | 在线演示{target="_blank"} |
| 圆变换 | 移动、缩放、镜像操作 | 在线演示{target="_blank"} |
概述
圆是最基本的曲线图形之一,广泛用于机械、建筑等领域的设计。CircleEnt 提供了完整的圆形操作功能,包括几何计算、变换和编辑。
构造函数
import { CircleEnt, Point2D } from 'vjcad';
// 简化写法(推荐)
const circle1 = new CircleEnt([50, 50], 25);
// Point2D 写法
const circle2 = new CircleEnt(new Point2D(50, 50), 25);
// 带颜色的构造
const circle3 = new CircleEnt([100, 100], 30, 3); // 颜色索引(3=绿色)简化写法
构造函数和 center 属性都支持 [x, y] 数组形式的坐标,避免每次都写 new Point2D(...)。
属性
基本属性
| 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|
center | Point2D | 读写 | 圆心坐标 |
radius | number | 读写 | 圆的半径 |
计算属性(只读)
| 属性 | 类型 | 说明 |
|---|---|---|
area | number | 圆的面积(πr²) |
circumference | number | 圆的周长(2πr) |
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 获取属性
console.log('圆心:', circle.center); // Point2D(50, 50)
console.log('半径:', circle.radius); // 25
console.log('面积:', circle.area); // 1963.49...
console.log('周长:', circle.circumference); // 157.08...
// 修改属性
circle.center = new Point2D(100, 100);
circle.radius = 50;
// 直接修改圆心坐标
circle.center.x = 75;
circle.center.y = 75;方法
几何计算
getDiameter() - 获取直径
const circle = new CircleEnt(new Point2D(50, 50), 25);
console.log('直径:', circle.getDiameter()); // 50setDiameter() - 通过直径设置半径
const circle = new CircleEnt(new Point2D(50, 50), 25);
circle.setDiameter(100);
console.log('新半径:', circle.radius); // 50setArea() - 通过面积设置半径
根据指定的面积反推并设置圆形的半径。使用公式:radius = √(area / π)
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 原始面积
console.log('原始面积:', circle.area); // 1963.49...
console.log('原始半径:', circle.radius); // 25
// 设置面积为 1000
circle.setArea(1000);
console.log('新半径:', circle.radius); // 17.84...
console.log('新面积:', circle.area); // 1000(验证)
// 实际应用:创建指定面积的圆
const targetArea = 500; // 目标面积 500 平方单位
const circle2 = new CircleEnt(new Point2D(100, 100), 1);
circle2.setArea(targetArea);
console.log('目标面积圆的半径:', circle2.radius.toFixed(2)); // 12.62getCircumference() - 获取周长(方法)
除了 circumference 属性外,还可以使用 getCircumference() 方法获取周长。
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 方式一:使用属性
console.log('周长:', circle.circumference); // 157.08...
// 方式二:使用方法
console.log('周长:', circle.getCircumference()); // 157.08...setCircumference() - 通过周长设置半径
根据指定的周长反推并设置圆形的半径。使用公式:radius = circumference / (2π)
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 原始周长
console.log('原始周长:', circle.circumference); // 157.08...
console.log('原始半径:', circle.radius); // 25
// 设置周长为 100
circle.setCircumference(100);
console.log('新半径:', circle.radius); // 15.91...
console.log('新周长:', circle.circumference); // 100(验证)
// 实际应用:创建指定周长的圆
const targetCircumference = 200; // 目标周长 200 单位
const circle2 = new CircleEnt(new Point2D(100, 100), 1);
circle2.setCircumference(targetCircumference);
console.log('目标周长圆的半径:', circle2.radius.toFixed(2)); // 31.83属性与方法的区别
circumference属性和getCircumference()方法功能相同,都返回周长- 属性语法更简洁:
circle.circumference - 方法语法与其他 setter 配对:
circle.getCircumference()/circle.setCircumference()
getQuadPoints() - 获取象限点
返回圆的四个象限点(右、上、左、下)。
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 获取标准象限点(无旋转)
const quadPoints = circle.getQuadPoints();
console.log('右:', quadPoints[0]); // Point2D(75, 50)
console.log('上:', quadPoints[1]); // Point2D(50, 75)
console.log('左:', quadPoints[2]); // Point2D(25, 50)
console.log('下:', quadPoints[3]); // Point2D(50, 25)
// 获取旋转后的象限点
const rotatedQuadPoints = circle.getQuadPoints(Math.PI / 4); // 旋转 45°几何变换
所有几何变换方法都支持 PointInput 类型参数,可以使用 [x, y] 数组或 Point2D 对象。
move() - 移动
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt([50, 50], 25);
// 简化写法(推荐)
circle.move([0, 0], [100, 100]);
console.log('新圆心:', circle.center); // Point2D(150, 150)
// 半径不变
console.log('半径:', circle.radius); // 25rotate() - 旋转
圆绕指定点旋转时,只有圆心位置改变,形状不变。
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt([100, 0], 25);
// 简化写法(推荐)
circle.rotate([0, 0], Math.PI / 2); // 绕原点旋转 90°
console.log('新圆心:', circle.center); // Point2D(0, 100)
console.log('半径:', circle.radius); // 25(不变)scale() - 缩放
缩放会同时改变圆心位置(相对于缩放中心)和半径。
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt([100, 100], 25);
// 简化写法(推荐)
circle.scale([0, 0], 2); // 以原点为中心放大 2 倍
console.log('新圆心:', circle.center); // Point2D(200, 200)
console.log('新半径:', circle.radius); // 50
// 以自身圆心为中心缩放
const circle2 = new CircleEnt([50, 50], 25);
circle2.scale(circle2.center, 2);
console.log('圆心:', circle2.center); // Point2D(50, 50)(不变)
console.log('半径:', circle2.radius); // 50mirror() - 镜像
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt([100, 50], 25);
// 简化写法(推荐)
circle.mirror([0, 0], [0, 100]); // 沿 Y 轴(X=0)镜像
console.log('新圆心:', circle.center); // Point2D(-100, 50)
console.log('半径:', circle.radius); // 25(不变)夹点编辑
gripEdit() 方法处理夹点拖动编辑。
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 夹点类型: "center" | "quad"
// 移动圆心
circle.gripEdit(new Point2D(100, 100), "center");
console.log('新圆心:', circle.center); // Point2D(100, 100)
// 通过象限点调整半径
circle.gripEdit(new Point2D(150, 100), "quad");
// 新半径 = 圆心到夹点的距离
console.log('新半径:', circle.radius); // 50边界框
import { CircleEnt, Point2D, CoordinateSystemType } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
// 获取 WCS 边界框
const bbox = circle.boundingBox();
console.log('最小点:', bbox.pt1); // Point2D(25, 25)
console.log('最大点:', bbox.pt2); // Point2D(75, 75)
// 边界框是正方形,边长 = 直径
console.log('宽度:', bbox.width); // 50
console.log('高度:', bbox.height); // 50克隆
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
circle.setDefaults();
circle.color = 1;
// 创建深拷贝
const circleCopy = circle.clone();
// 修改副本
circleCopy.radius = 50;
circleCopy.color = 3;
console.log(circle.radius); // 25
console.log(circleCopy.radius); // 50序列化
import { CircleEnt, Point2D } from 'vjcad';
const circle = new CircleEnt(new Point2D(50, 50), 25);
circle.setDefaults();
// 导出
const dbData = circle.toDb();
console.log(dbData);
// {
// type: "CIRCLE",
// layerId: "0",
// color: 256,
// center: [50, 50], // 坐标格式: [x, y] 或 [x, y, z]
// radius: 25
// }
// 导入
const newCircle = new CircleEnt(new Point2D(0, 0), 1);
newCircle.fromDb(dbData);完整示例
通过几何属性创建圆
import { Engine, CircleEnt, Point2D } from 'vjcad';
// 通过面积创建圆
function createCircleByArea(center: Point2D, area: number): CircleEnt {
const circle = new CircleEnt(center, 1); // 先用默认半径创建
circle.setArea(area); // 再设置目标面积
circle.setDefaults();
return circle;
}
// 通过周长创建圆
function createCircleByCircumference(center: Point2D, circumference: number): CircleEnt {
const circle = new CircleEnt(center, 1);
circle.setCircumference(circumference);
circle.setDefaults();
return circle;
}
// 通过直径创建圆
function createCircleByDiameter(center: Point2D, diameter: number): CircleEnt {
const circle = new CircleEnt(center, 1);
circle.setDiameter(diameter);
circle.setDefaults();
return circle;
}
// 使用示例
const c1 = createCircleByArea(new Point2D(0, 0), 1000);
const c2 = createCircleByCircumference(new Point2D(100, 0), 200);
const c3 = createCircleByDiameter(new Point2D(200, 0), 50);
Engine.addEntities([c1, c2, c3]);
// 输出圆的信息
console.log('面积圆:', c1.radius.toFixed(2), '半径,', c1.area.toFixed(2), '面积');
console.log('周长圆:', c2.radius.toFixed(2), '半径,', c2.circumference.toFixed(2), '周长');
console.log('直径圆:', c3.radius.toFixed(2), '半径,', c3.getDiameter().toFixed(2), '直径');绘制同心圆
import { Engine, CircleEnt, Point2D } from 'vjcad';
function drawConcentricCircles(center: Point2D, radii: number[]) {
const circles: CircleEnt[] = [];
for (const radius of radii) {
const circle = new CircleEnt(center.clone(), radius);
circle.setDefaults();
circles.push(circle);
}
Engine.addEntities(circles);
}
// 绘制同心圆
drawConcentricCircles(new Point2D(100, 100), [20, 40, 60, 80, 100]);绘制圆形阵列
import { Engine, CircleEnt, Point2D } from 'vjcad';
function drawCircleArray(
center: Point2D,
radius: number,
count: number,
distance: number
) {
const circles: CircleEnt[] = [];
const angleStep = (2 * Math.PI) / count;
for (let i = 0; i < count; i++) {
const angle = i * angleStep;
const circleCenter = new Point2D(
center.x + distance * Math.cos(angle),
center.y + distance * Math.sin(angle)
);
const circle = new CircleEnt(circleCenter, radius);
circle.setDefaults();
circles.push(circle);
}
Engine.addEntities(circles);
}
// 绘制 8 个圆组成的圆形阵列
drawCircleArray(new Point2D(200, 200), 15, 8, 80);交互式绘制圆
import {
Engine,
CircleEnt,
Point2D,
PointInputOptions,
RealInputOptions,
InputStatusEnum
} from 'vjcad';
async function drawCircleCommand() {
// 获取圆心
const opt1 = new PointInputOptions("指定圆心:");
const result1 = await Engine.getPoint(opt1);
if (result1.status !== InputStatusEnum.OK) return;
const center = result1.value as Point2D;
// 获取半径
const opt2 = new RealInputOptions("指定半径:");
opt2.defaultValue = 25;
const result2 = await Engine.getReal(opt2);
if (result2.status !== InputStatusEnum.OK) return;
const radius = result2.value as number;
// 创建圆
const circle = new CircleEnt(center, radius);
circle.setDefaults();
Engine.addEntities(circle);
Engine.writeMessage(`圆已创建,面积: ${circle.area.toFixed(2)}`);
}通过三点绘制圆
import { Engine, CircleEnt, Point2D } from 'vjcad';
function circleFrom3Points(p1: Point2D, p2: Point2D, p3: Point2D): CircleEnt | null {
// 计算外接圆
const ax = p1.x, ay = p1.y;
const bx = p2.x, by = p2.y;
const cx = p3.x, cy = p3.y;
const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));
if (Math.abs(d) < 1e-10) {
// 三点共线,无法创建圆
return null;
}
const ux = ((ax * ax + ay * ay) * (by - cy) +
(bx * bx + by * by) * (cy - ay) +
(cx * cx + cy * cy) * (ay - by)) / d;
const uy = ((ax * ax + ay * ay) * (cx - bx) +
(bx * bx + by * by) * (ax - cx) +
(cx * cx + cy * cy) * (bx - ax)) / d;
const center = new Point2D(ux, uy);
const radius = Math.sqrt((ax - ux) * (ax - ux) + (ay - uy) * (ay - uy));
const circle = new CircleEnt(center, radius);
circle.setDefaults();
return circle;
}
// 使用示例
const circle = circleFrom3Points(
new Point2D(0, 0),
new Point2D(100, 0),
new Point2D(50, 50)
);
if (circle) {
Engine.addEntities(circle);
}常见问题
Q: 如何判断点是否在圆内?
import { CircleEnt, Point2D } from 'vjcad';
function isPointInCircle(circle: CircleEnt, point: Point2D): boolean {
const dx = point.x - circle.center.x;
const dy = point.y - circle.center.y;
const distanceSquared = dx * dx + dy * dy;
return distanceSquared <= circle.radius * circle.radius;
}
function isPointOnCircle(circle: CircleEnt, point: Point2D, tolerance: number = 0.001): boolean {
const dx = point.x - circle.center.x;
const dy = point.y - circle.center.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return Math.abs(distance - circle.radius) < tolerance;
}Q: 如何获取圆上指定角度的点?
import { CircleEnt, Point2D } from 'vjcad';
function getPointOnCircle(circle: CircleEnt, angle: number): Point2D {
return new Point2D(
circle.center.x + circle.radius * Math.cos(angle),
circle.center.y + circle.radius * Math.sin(angle)
);
}
// 获取 45° 位置的点
const circle = new CircleEnt(new Point2D(50, 50), 25);
const point = getPointOnCircle(circle, Math.PI / 4);Q: 如何计算两圆的交点?
import { CircleEnt, Point2D } from 'vjcad';
function circleCircleIntersection(c1: CircleEnt, c2: CircleEnt): Point2D[] {
const dx = c2.center.x - c1.center.x;
const dy = c2.center.y - c1.center.y;
const d = Math.sqrt(dx * dx + dy * dy);
// 检查是否相交
if (d > c1.radius + c2.radius || d < Math.abs(c1.radius - c2.radius)) {
return []; // 不相交
}
const a = (c1.radius * c1.radius - c2.radius * c2.radius + d * d) / (2 * d);
const h = Math.sqrt(c1.radius * c1.radius - a * a);
const px = c1.center.x + a * dx / d;
const py = c1.center.y + a * dy / d;
const p1 = new Point2D(px + h * dy / d, py - h * dx / d);
const p2 = new Point2D(px - h * dy / d, py + h * dx / d);
if (Math.abs(h) < 1e-10) {
return [p1]; // 相切,只有一个交点
}
return [p1, p2];
}下一步
- 圆弧实体 (ArcEnt) - 圆弧实体详解
- 椭圆实体 (EllipseEnt) - 椭圆实体详解
- 多段线实体 (PolylineEnt) - 多段线实体详解