你好我有一个我认为很难解决的问题,我到处寻找解决方案,但我没有找到任何东西。
我想从点列表中绘制轮廓。
我的问题是:
- 我有一个来自文本文件的 Points3D 列表,它们没有任何顺序,就像随机点一样。当然,我将它们添加到列表中。我使用小的 3D 椭圆在 3D 空间中绘制这些点。到目前为止,一切都很好。
- 现在我想绘制一条穿过列表中所有点的 3D 样条线。所以我创建了 Spline3D 类,它使用三次插值来确定文本文件中给定点之间曲线点的位置。在我的样条曲线中,我计算说像 400 个新点,然后我在每对点之间绘制小的 3D 圆柱体:点 i 和点 i+1 在它们之间有小圆柱体+圆柱体正确旋转,所以一切看起来都像真正的样条曲线(在理论)。
主要问题是点是无序的,所以如果我只是这样做,我会得到这样的样条曲线:
http://img5.imageshack.us/img5/4659/2b61.jpg
在空间中绘制的原始点如下所示:
http://img194.imageshack.us/img194/9016/hv8e.jpg
http://img5.imageshack.us/img5/659/nsz1.jpg
所以我发现我有两个解决方案
将点按某种顺序排列,然后将它们添加到 Spline3D 并计算样条。
以其他方式计算样条曲线,这可能以某种方式导致顺序点,所以基本上它仍然引导我到 1。
所以我尝试了一些重新排序的方法。
1. a) 点的最近邻
int firstIndex = (new Random().Next(pointsCopy.Count));//0;//pointsCopy.Count / 2;//(new Random().Next(pointsCopy.Count));
NPoint3D point = pointsCopy[firstIndex];
pointsCopy.Remove(point);
spline3D.addPoint(point.ToPoint3D());
NPoint3D closestPoint = new NPoint3D();
double distance;
double nDistance;
Point3D secondPoint = new Point3D();
bool isSecondPoint = true;
while (pointsCopy.Count != 0)
{
distance = double.MaxValue;
for (int i = 0; i < pointsCopy.Count; i++)
{
nDistance = point.distanceToPoint(pointsCopy[i]);
if (nDistance < distance)
{
distance = nDistance;
closestPoint = pointsCopy[i];
}
}
if (isSecondPoint)
{
isSecondPoint = false;
secondPoint = closestPoint.ToPoint3D();
}
spline3D.addPoint(closestPoint.ToPoint3D());
point = closestPoint;
pointsCopy.Remove(closestPoint);
}
spline3D.addPoint(points[firstIndex].ToPoint3D()); //first point is also last point
这是我的第一个想法,我认为这将成为我问题的最终解决方案。我从点列表中随机选择一个点,该点成为样条曲线的第一个点。然后我找到最接近前一点的点,我将他添加到样条曲线并从列表中删除,依此类推......
http://img18.imageshack.us/img18/3650/mik0.jpg
http://img706.imageshack.us/img706/3834/u97b.jpg
可悲的是,有时(尤其是靠近我的个人资料的边缘)指向下方比指向近处更近,因此样条曲线变得弯曲。
2. b) TSP
distanceMatrix = new TSP.DistanceMatrix(pointsCopy, NPoint3D.distanceBetweenTwoPoints);
int[] indexes = TSP.Algorithms.TSPgreedySearch(distanceMatrix);
for (int i = 0; i < indexes.Length; i++)
spline3D.addPoint(pointsCopy[indexes[i]].ToPoint3D());
spline3D.addPoint(pointsCopy[indexes[0]].ToPoint3D());
基本上我使用旅行商问题算法来确定通过所有点的最短样条(最短路径)。可悲的是,这个问题是 NP-Hard,所以为了获得良好的性能,我使用了一些启发式方法。
http://img198.imageshack.us/img198/714/xiqy.jpg
http://img839.imageshack.us/img839/9530/exnu.jpg
样条曲线看起来比 1.a 中的要好,但仍然不够。
3. c) 一些使用两条样条的奇怪方法
我的一些朋友告诉我,我应该将轮廓分成两部分(上部分和下部分),然后计算并绘制两条样条线。可悲的是我不知道该怎么做,我的意思是我不知道如何确定点应该在上部还是下部。请帮我。
那么我该如何解决这个问题呢?有任何想法吗?