WPF 积分优化
WPF Points optimization
我的问题的答案可能很明显,我只是想确认一下。
我有一条包含大量点的曲线,需要对其进行优化。
在该曲线上,我可能必须执行以下各种操作:
1. 添加 canvas
2. 继续 canvas
3. 拉伸 canvas
4. canvas 平底锅
5. canvas 缩放
为此,我有一条原始折线,用于存储所有原始点。
然后我有第二条折线,用于存储优化的点集。
首先,我的优化似乎微不足道:
1. 点是双变量,但最终在屏幕上是整数。因此,如果 point1 和 points2 CONVERTED TO INTEGER 相同,我将丢弃 point2。
2. 如果一个段的开始和结束都在 canvas 之外(例如,为了平移或缩放)我丢弃这两个点。
我为所有积分都这样做。
这是非常有效的,因为具有 100 万点的示例螺旋可以减少到大约 4000 点!!
之后我总是显示优化曲线。
关于对曲线进行的各种操作。
- 继续 canvas ---> 不需要重做优化(我不能将它移到 canvas 之外)。我移动次曲线
- stretch on canvas ---> 不需要重做优化。我拉伸次曲线
- canvas pan ---> 需要重做优化,某些点可能会从 canvas.
中删除
- canvas zoom ---> 需要重做优化,某些点可能会从 canvas.
中删除
都对吗?
感谢您的帮助
帕特里克
您可以使用 Douglas-Ramer-Peucker algorithm 来减少折线中的点数:
public static IList<Point> ReducePoints(IList<Point> points, double tolerance)
{
var indexes = new List<int>(2);
indexes.Add(0);
indexes.Add(points.Count - 1);
ReducePoints(points, tolerance, indexes, 0, points.Count - 1);
return indexes.OrderBy(i => i).Select(i => points[i]).ToList();
}
private static void ReducePoints(
IList<Point> points, double tolerance, List<int> indexes, int first, int last)
{
if (first + 1 < last)
{
var dx = points[first].X - points[last].X;
var dy = points[first].Y - points[last].Y;
var length = Math.Sqrt(dx * dx + dy * dy);
var maxDistance = 0d;
var farthest = 0;
for (var index = first + 1; index < last; index++)
{
var dxi = points[first].X - points[index].X;
var dyi = points[first].Y - points[index].Y;
// perpendicular distance from line segment first to last
var distance = Math.Abs(dx * dyi - dxi * dy) / length;
if (distance > maxDistance)
{
maxDistance = distance;
farthest = index;
}
}
if (maxDistance > tolerance)
{
indexes.Add(farthest);
ReducePoints(points, tolerance, indexes, first, farthest);
ReducePoints(points, tolerance, indexes, farthest, last);
}
}
}
我的问题的答案可能很明显,我只是想确认一下。 我有一条包含大量点的曲线,需要对其进行优化。 在该曲线上,我可能必须执行以下各种操作: 1. 添加 canvas 2. 继续 canvas 3. 拉伸 canvas 4. canvas 平底锅 5. canvas 缩放
为此,我有一条原始折线,用于存储所有原始点。 然后我有第二条折线,用于存储优化的点集。
首先,我的优化似乎微不足道: 1. 点是双变量,但最终在屏幕上是整数。因此,如果 point1 和 points2 CONVERTED TO INTEGER 相同,我将丢弃 point2。 2. 如果一个段的开始和结束都在 canvas 之外(例如,为了平移或缩放)我丢弃这两个点。
我为所有积分都这样做。 这是非常有效的,因为具有 100 万点的示例螺旋可以减少到大约 4000 点!!
之后我总是显示优化曲线。
关于对曲线进行的各种操作。
- 继续 canvas ---> 不需要重做优化(我不能将它移到 canvas 之外)。我移动次曲线
- stretch on canvas ---> 不需要重做优化。我拉伸次曲线
- canvas pan ---> 需要重做优化,某些点可能会从 canvas. 中删除
- canvas zoom ---> 需要重做优化,某些点可能会从 canvas. 中删除
都对吗?
感谢您的帮助 帕特里克
您可以使用 Douglas-Ramer-Peucker algorithm 来减少折线中的点数:
public static IList<Point> ReducePoints(IList<Point> points, double tolerance)
{
var indexes = new List<int>(2);
indexes.Add(0);
indexes.Add(points.Count - 1);
ReducePoints(points, tolerance, indexes, 0, points.Count - 1);
return indexes.OrderBy(i => i).Select(i => points[i]).ToList();
}
private static void ReducePoints(
IList<Point> points, double tolerance, List<int> indexes, int first, int last)
{
if (first + 1 < last)
{
var dx = points[first].X - points[last].X;
var dy = points[first].Y - points[last].Y;
var length = Math.Sqrt(dx * dx + dy * dy);
var maxDistance = 0d;
var farthest = 0;
for (var index = first + 1; index < last; index++)
{
var dxi = points[first].X - points[index].X;
var dyi = points[first].Y - points[index].Y;
// perpendicular distance from line segment first to last
var distance = Math.Abs(dx * dyi - dxi * dy) / length;
if (distance > maxDistance)
{
maxDistance = distance;
farthest = index;
}
}
if (maxDistance > tolerance)
{
indexes.Add(farthest);
ReducePoints(points, tolerance, indexes, first, farthest);
ReducePoints(points, tolerance, indexes, farthest, last);
}
}
}