基于坐标系在立方体中均匀采样点[C#、Unity实现]
立方体均匀网格点生成(C#/Unity实现)
需求说明
已知3D坐标系下的立方体完整信息(顶点、边长等),需要高效生成n³个均匀分布的点,每条边包含n个点(包含顶点),类似网格分布。优先支持任意朝向的立方体,其次支持任意位置的轴对齐立方体,使用Unity Vector3实现。
示例参考
/* 输入顶点: (0, 0, 0) (1, 0, 0) (1, 1, 0) (1, 1, 1) (0, 1, 1) (0, 0, 1) (0, 1, 0) (1, 0, 1) 生成点数:n = 3(每条边含3个点,共27个) 输出部分点示例: (0, 0, 0) (1, 0, 0) (1, 1, 0) (1, 1, 1) (0, 1, 1) (0, 0, 1) (0, 1, 0) (1, 0, 1) (0, 0.5, 0) (0.5, 0, 0) (0, 0, 0.5) (0.5, 0.5, 0) (0.5, 0, 0.5) (0.5, 0.5, 0.5) (0, 0.5, 0.5) (1, 0.5, 0) ... 其余点省略 */
方案1:任意朝向立方体实现
核心思路是从立方体顶点中提取基准原点与三个正交边向量,通过三元线性插值生成均匀网格点。
代码实现
using UnityEngine; using System.Collections.Generic; public class CubePointGenerator { /// <summary> /// 生成任意朝向立方体的均匀网格点 /// </summary> /// <param name="cubeVertices">立方体的8个顶点</param> /// <param name="pointsPerEdge">每条边的点数(含顶点)</param> /// <returns>所有网格点的列表</returns> public static List<Vector3> GenerateArbitraryOrientationPoints(List<Vector3> cubeVertices, int pointsPerEdge) { // 提取立方体基准点与三个正交边向量 Vector3 origin = cubeVertices[0]; Vector3 edge1 = Vector3.zero; Vector3 edge2 = Vector3.zero; Vector3 edge3 = Vector3.zero; float edgeLength = -1; foreach (var vertex in cubeVertices) { float dist = Vector3.Distance(origin, vertex); if (dist > 0.001f) { if (edgeLength < 0) { edgeLength = dist; edge1 = vertex - origin; } else if (Mathf.Abs(dist - edgeLength) < 0.001f) { if (Mathf.Abs(Vector3.Dot(edge1, vertex - origin)) < 0.001f) { edge2 = vertex - origin; } else { edge3 = vertex - origin; } } } } // 生成网格点 List<Vector3> points = new List<Vector3>(); float step = 1f / (pointsPerEdge - 1); for (int i = 0; i < pointsPerEdge; i++) { float t1 = i * step; for (int j = 0; j < pointsPerEdge; j++) { float t2 = j * step; for (int k = 0; k < pointsPerEdge; k++) { float t3 = k * step; Vector3 point = origin + t1 * edge1 + t2 * edge2 + t3 * edge3; points.Add(point); } } } return points; } }
说明
- 自动从8个顶点中识别正交边向量,无需手动指定朝向
- 用
0.001f做精度判断,避免浮点误差干扰 - 线性插值保证点在立方体内部均匀分布
方案2:轴对齐立方体实现
针对各边平行于XYZ轴的立方体,直接通过最小/最大顶点计算范围生成网格点,实现更简洁高效。
代码实现
using UnityEngine; using System.Collections.Generic; public class AxisAlignedCubeGenerator { /// <summary> /// 生成轴对齐立方体的均匀网格点 /// </summary> /// <param name="minVertex">立方体最小顶点(x/y/z均最小)</param> /// <param name="maxVertex">立方体最大顶点(x/y/z均最大)</param> /// <param name="pointsPerEdge">每条边的点数(含顶点)</param> /// <returns>所有网格点的列表</returns> public static List<Vector3> GenerateAxisAlignedPoints(Vector3 minVertex, Vector3 maxVertex, int pointsPerEdge) { List<Vector3> points = new List<Vector3>(); float stepX = (maxVertex.x - minVertex.x) / (pointsPerEdge - 1); float stepY = (maxVertex.y - minVertex.y) / (pointsPerEdge - 1); float stepZ = (maxVertex.z - minVertex.z) / (pointsPerEdge - 1); for (int i = 0; i < pointsPerEdge; i++) { float x = minVertex.x + i * stepX; for (int j = 0; j < pointsPerEdge; j++) { float y = minVertex.y + j * stepY; for (int k = 0; k < pointsPerEdge; k++) { float z = minVertex.z + k * stepZ; points.Add(new Vector3(x, y, z)); } } } return points; } // 重载:从8个顶点自动提取最小/最大顶点 public static List<Vector3> GenerateAxisAlignedPoints(List<Vector3> cubeVertices, int pointsPerEdge) { Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var v in cubeVertices) { min = Vector3.Min(min, v); max = Vector3.Max(max, v); } return GenerateAxisAlignedPoints(min, max, pointsPerEdge); } }
使用示例
// 任意朝向立方体调用示例 List<Vector3> cubeVertices = new List<Vector3> { new Vector3(0,0,0), new Vector3(1,0,0), new Vector3(1,1,0), new Vector3(1,1,1), new Vector3(0,1,1), new Vector3(0,0,1), new Vector3(0,1,0), new Vector3(1,0,1) }; List<Vector3> arbitraryPoints = CubePointGenerator.GenerateArbitraryOrientationPoints(cubeVertices, 3); // 轴对齐立方体调用示例 List<Vector3> axisAlignedPoints = AxisAlignedCubeGenerator.GenerateAxisAlignedPoints(cubeVertices, 3);
内容的提问来源于stack exchange,提问作者Codeman
相关产品推荐
相关产品推荐

