# 3D数字孪生 **Repository Path**: Zero_0002/3d-digital-twin ## Basic Information - **Project Name**: 3D数字孪生 - **Description**: 3D数字孪生项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2025-05-30 - **Last Updated**: 2025-12-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1. **超椭圆(Superellipse)** 或称为 **Lamé曲线** ------ ## 1. 原始代码分析 ```csharp section.Add(new Point( x * Math.Sign(Math.Cos(t)) * Math.Pow(Math.Abs(Math.Cos(t)), 2 / n), -y * Math.Sign(Math.Sin(t)) * Math.Pow(Math.Abs(Math.Sin(t)), 2 / n))); ``` 这里构造的是超椭圆轮廓上的一个点 `Point(x, y)`,用于加入到 `section` 点集当中。我们来把它结构化地拆解。 ------ ## 2. 背后的数学公式(超椭圆方程) 超椭圆的参数方程(Lamé 曲线)为: ![image-20250805085114712](C:\Users\32371\AppData\Roaming\Typora\typora-user-images\image-20250805085114712.png) 对应你的代码中: | 数学符号 | 代码变量 | | -------- | --------------- | | aa | `x` | | bb | `y` | | nn | `n`(控制形状) | | tt | `t`(当前角度) | ------ ## 3. 每个部分的作用 ### 🔸 `Math.Sign(...)` 返回输入值的符号(正号 +1,负号 -1): - 用来保持余弦或正弦原来的符号(因为 `Math.Pow(..., fractional)` 不能处理负数) 例如: ```csharp Math.Sign(Math.Cos(t)) * Math.Pow(Math.Abs(Math.Cos(t)), 2 / n) ``` 就是为了实现: sgn(cos⁡t)⋅∣cos⁡t∣2/n\text{sgn}(\cos t) \cdot |\cos t|^{2/n} ------ ### 🔸 `Math.Pow(Math.Abs(...), 2 / n)` - 控制角度的非线性缩放 - `n` 越大,图形越接近矩形 - `n` 越小(但 > 0),图形越接近星形或花瓣形状 | n 值 | 图形趋势 | | ----- | ---------- | | n = 2 | 标准椭圆 | | n > 2 | 图形变“方” | | n < 2 | 图形变“尖” | ------ ### 🔸 负号: `-y * ...` 这是为了坐标系转换,一般在 **图形坐标系中 Y轴是向下的**(比如 Windows GUI 系统、Canvas等),所以需要翻转一下。 ------ ## 4. 可视化说明 | n 值 | 图形描述 | | ---- | ---------------------- | | 2 | 椭圆(标准) | | 4 | 近似正方形,边有弧度 | | 1.5 | 有点像星形,边缘更尖 | | ∞ | 完全是正方形(理论上) | ------ ## ✅ 5. 总结这段代码的作用 这段代码的作用是: > 🔷 根据当前角度 `t`,计算出一个超椭圆上的点,并将它添加到 `section` 点集中,用于构造整个轮廓。 你可以在循环中多次使用这个公式,变化 `t` 从 `0` 到 `2π`,就能画出一个完整的超椭圆。 ------ ## ✅ 补充:如何完整生成超椭圆轮廓? ```csharp List section = new List(); int segments = 100; double a = 100; // x 半轴 double b = 60; // y 半轴 double n = 4; // 控制形状 for (int i = 0; i < segments; i++) { double t = 2 * Math.PI * i / segments; double px = a * Math.Sign(Math.Cos(t)) * Math.Pow(Math.Abs(Math.Cos(t)), 2 / n); double py = -b * Math.Sign(Math.Sin(t)) * Math.Pow(Math.Abs(Math.Sin(t)), 2 / n); section.Add(new Point(px, py)); } ``` # 2. 椭圆 计算椭圆上点的 x,yx, y 坐标,通常是根据参数 tt (角度或弧度)来用**参数方程(parametric equation)**表示的。以下是标准椭圆的公式解析。 ------ ## 一、椭圆的标准参数方程(以中心为原点) 设椭圆的长轴为 aa,短轴为 bb,角度参数 t∈[0,2π]t \in [0, 2\pi],那么椭圆上的点的坐标公式是: ![image-20250805091044911](C:\Users\32371\AppData\Roaming\Typora\typora-user-images\image-20250805091044911.png) > ✅ 这适用于椭圆**中心在原点 (0,0)**,长轴水平朝向的情形。 ------ ## 二、带中心点偏移(中心在 (cx,cy)(cx, cy)) ![image-20250805091053252](C:\Users\32371\AppData\Roaming\Typora\typora-user-images\image-20250805091053252.png) ------ ## 三、旋转后的椭圆(绕原点旋转角度 θ\theta) 如果椭圆还绕原点**顺时针旋转了角度** θ\theta,则公式为: ![image-20250805091104718](C:\Users\32371\AppData\Roaming\Typora\typora-user-images\image-20250805091104718.png) > ✅ 非常适用于椭圆有旋转角度时,例如图像分析或几何建模场景。 ------ ## 示例(C#代码) ```csharp // 生成一个椭圆上的点 Point GetEllipsePoint(double a, double b, double t) { double x = a * Math.Cos(t); double y = b * Math.Sin(t); return new Point(x, y); } ``` 或者加上偏移: ```csharp Point GetEllipsePoint(double a, double b, double t, double cx, double cy) { double x = cx + a * Math.Cos(t); double y = cy + b * Math.Sin(t); return new Point(x, y); } ``` ------ ## 常用角度 t 的对应点(标准椭圆) | t (角度) | x=acos⁡(t)x = a \cos(t) | y=bsin⁡(t)y = b \sin(t) | | ------------- | ---------------------- | ---------------------- | | 0∘0^\circ | aa | 00 | | 90∘90^\circ | 00 | bb | | 180∘180^\circ | −a-a | 00 | | 270∘270^\circ | 00 | −b-b | ------ ## 椭圆的非参数形式(隐式方程) 如果你不使用角度,而是要判断某个 (x,y)(x, y) 是否在椭圆上,可以使用椭圆的标准方程: ![image-20250805102850337](C:\Users\32371\AppData\Roaming\Typora\typora-user-images\image-20250805102850337.png) - 如果 < 1,点在椭圆内部; - 如果 = 1,点在椭圆上; - 如果 > 1,点在椭圆外部