Point64和PointD的核心数据结构有哪些特点?
摘要:layout: default title: 第2章:核心数据结构 - Point64、PointD 第2章:核心数据结构 - Point64、PointD 2.1 概述 在 Clipper2 中,所有几何运算的基础是点(Point)数据结
第2章:核心数据结构 - Point64、PointD
2.1 概述
在 Clipper2 中,所有几何运算的基础是点(Point)数据结构。与 Clipper1 不同,Clipper2 提供了两种点类型:
Point64:使用 64 位整数坐标
PointD:使用双精度浮点坐标
这两种类型定义在 Clipper.Core.cs 文件中,是整个库的基石。
2.2 Point64 结构
2.2.1 结构定义
public struct Point64
{
public long X;
public long Y;
#if USINGZ
public long Z;
#endif
}
设计特点:
值类型(struct):避免堆分配,提高性能
公共字段:直接暴露 X、Y 字段,避免属性访问开销
条件 Z 坐标:通过预处理器指令可选启用
2.2.2 构造函数
Point64 提供了多个构造函数以适应不同场景:
// 从另一个 Point64 复制
public Point64(Point64 pt)
{
X = pt.X;
Y = pt.Y;
#if USINGZ
Z = pt.Z;
#endif
}
// 从 Point64 复制并缩放
public Point64(Point64 pt, double scale)
{
X = (long) Math.Round(pt.X * scale, MidpointRounding.AwayFromZero);
Y = (long) Math.Round(pt.Y * scale, MidpointRounding.AwayFromZero);
#if USINGZ
Z = (long) Math.Round(pt.Z * scale, MidpointRounding.AwayFromZero);
#endif
}
// 从整数坐标创建
public Point64(long x, long y
#if USINGZ
, long z = 0
#endif
) {
X = x;
Y = y;
#if USINGZ
Z = z;
#endif
}
// 从浮点坐标创建(自动四舍五入)
public Point64(double x, double y
#if USINGZ
, double z = 0.0
#endif
) {
X = (long) Math.Round(x, MidpointRounding.AwayFromZero);
Y = (long) Math.Round(y, MidpointRounding.AwayFromZero);
#if USINGZ
Z = (long) Math.Round(z, MidpointRounding.AwayFromZero);
#endif
}
// 从 PointD 创建
public Point64(PointD pt)
{
X = (long) Math.Round(pt.x, MidpointRounding.AwayFromZero);
Y = (long) Math.Round(pt.y, MidpointRounding.AwayFromZero);
#if USINGZ
Z = pt.z;
#endif
}
// 从 PointD 创建并缩放
public Point64(PointD pt, double scale)
{
X = (long) Math.Round(pt.x * scale, MidpointRounding.AwayFromZero);
Y = (long) Math.Round(pt.y * scale, MidpointRounding.AwayFromZero);
#if USINGZ
Z = pt.z;
#endif
}
2.2.3 舍入策略
注意所有涉及浮点到整数转换的地方都使用了 MidpointRounding.AwayFromZero:
Math.Round(x, MidpointRounding.AwayFromZero)
这种舍入方式的特点:
0.5 向上舍入到 1
-0.5 向下舍入到 -1
即"四舍五入"的传统行为
与默认的 MidpointRounding.ToEven(银行家舍入)不同,确保了一致性。
