【发布时间】:2014-01-17 15:44:45
【问题描述】:
首先是想法目标: 我有一个方法可以获取两个点和多个点来创建并返回一个点列表,其中包含要在点之间创建的新点数。
第一个问题是,例如第一次 pt1 是 181,172 而 pt4 是 180,171 但结果我看到里面有 20 个点,但第一个是:
180,171 最后一个是 181,172 我需要保持原样。 给定的两个点应该首先在相同的索引上:181,172,然后最后在索引 02 180,171 上
第二个问题是它只做一次只返回20分。 这就是我使用该方法的方式:
for (int i = 0; i < clouds.Count - 1; i += 2)
{
extendedPoints = DistributePoints(new PointF(clouds[i].X, clouds[i].Y), new PointF(clouds[i + 1].X, clouds[i + 1].Y), 20);
}
clouds = extendedPoints;
return clouds;
云现在只包含 20 个点,但在原始云中包含 37 个点,并且 DistributePoints 方法应该每次从云中获取两个点,并在两个点之间添加新的 20 个点。
方法:
public static List<PointF> DistributePoints(PointF pt1, PointF pt4, int number_of_points)
{
List<PointF> result = new List<PointF>();
float x_min = Math.Min(pt1.X, pt4.X), x_max = Math.Max(pt1.X, pt4.X);
float y_min = Math.Min(pt1.Y, pt4.Y), y_max = Math.Max(pt1.Y, pt4.Y);
if (number_of_points < 2) throw new ArgumentException("Need Two Points At Least");
for (int i = 0; i < number_of_points; i++)
{
float scale = (float)i / (number_of_points - 1);
float x = x_min + (x_max - x_min) * scale, y = y_min + (y_max - y_min) * scale;
result.Add(new PointF(x, y));
}
return result;
}
但由于某种原因,它在我不想要的图片框点的某处添加了更多的 20 点。
我得到的结果是: 我用黑色标记了我不需要的点:
我该如何解决?
我认为问题出在这里:
for (int i = 0; i < clouds.Count - 1; i += 2)
{
extendedPoints.AddRange(DistributePoints(new PointF(clouds[i].X, clouds[i].Y), new PointF(clouds[i + 1].X, clouds[i + 1].Y), 20));
}
clouds = extendedPoints;
如果云包含 37 个点(索引),我将它发送到方法 20 次,最后云应该包含 740 个点(索引)。 但由于某种原因,云只包含 360 个点(索引)。
37 * 20 = 740 那为什么云到底只有360个点呢?
所以我有这个问题,最终云只包含 360 个点,而我还有另一个问题,它在我不希望它出现的某个地方绘制了 20 个点。奇怪。
编辑**
我认为这段代码部分有问题:
for (int i = 0; i < clouds.Count - 1; i += 1)
{
extendedPoints.AddRange(DistributePoints(new PointF(clouds[i].X, clouds[i].Y), new PointF(clouds[i + 1].X, clouds[i + 1].Y), 20));
}
clouds = extendedPoints;
如果我在 FOR += 1 中进行操作,那么最终云以 720 点结束,但随后我看到在其他一些位置以线条格式绘制了两组 20 点。
如果我在 FOR += 2 中进行操作,那么最终云以 360 个点结束,但随后我看到一组 20 个点以线条格式绘制在其他位置。
如果我在 FOR += 3 中进行操作,那么最终云只以 240 点结束,但这次没有在其他位置绘制这 20 点。但是 240 分是不对的,我认为应该以 740 或 777 分结束。
编辑**
ja72 这就是我现在用你的代码得到的:
这就是我在绘画事件中绘制点的方式:
public static void Paint(Graphics e, double currentFactor, float kilometers)
{
float distance = kilometers / (float)1.09;//289617486; // One pixel distance is 1.09 kilometer.
Pen p;
p = new Pen(Brushes.Green);
if (points == null)
{
return;
}
foreach (PointF pt in clouds)
{
e.FillEllipse(Brushes.Red, (pt.X - distance) * (float)currentFactor, pt.Y * (float)currentFactor, 4f, 4f);
}
在这种情况下:km = 0.0 和 currentFactor = 1.0 也许这里的绘画事件有问题,但我不这么认为。
【问题讨论】:
-
您是否尝试过在调试模式下运行它并确保是这种方法是罪魁祸首?从外观上看,您正在修改类的一个字段 (
extendedPoints);是否有可能多次调用此方法或其他地方正在修改extendedPoints集合?如果可能,我建议更新该方法以使其没有副作用,也就是说,它已经返回了一个列表。在方法中构建一个 new 列表并返回它或让它返回void,因此很明显它正在改变状态:同时这样做只会产生混乱和像这样的错误。 -
我注意到你的“用法”;我敢打赌这是根本问题。看起来您每次迭代都使用相同的
List<PointF>。尝试让它与新列表一起使用,或先清除集合。 -
你使用的是
DistributePoints()还是ExtendPoints()? -
请注意,最小/最大的东西可能会导致插值中间点的顺序错误,或者更糟。只需使用简单的线性插值:
x = x1 + f * (x2 - x1)其中f的范围从第一个点的 0 到最后一个点的 1(在您的情况下,d除以点数)。无论 x1 > x2 是否,这个公式都有效。 -
Dvnrrs 试过了,但我可能不太明白。你能告诉我在更改后如何查看我的代码吗?