use*_*890 6 c# gpu gpgpu opencl coordinate-transformation
我有一个使用WinForms的遗留地图查看器应用程序.它是sloooooow.(速度过去是可以接受的,但谷歌地图,谷歌地球出现了,用户被宠坏了.现在我被允许更快:)
在完成所有明显的速度改进(缓存,并行执行,不绘制不需要绘制的内容等)之后,我的探查器向我显示真正的窒息点是将点从地图空间转换为屏幕空间时的坐标转换.通常,转换代码如下所示:
public Point MapToScreen(PointF input)
{
// Note that North is negative!
var result = new Point(
(int)((input.X - this.currentView.X) * this.Scale),
(int)((input.Y - this.currentView.Y) * this.Scale));
return result;
}
Run Code Online (Sandbox Code Playgroud)
真正的实现比较棘手.纬度/长度表示为整数.为了避免失去精确度,它们乘以2 ^ 20(~1百万).这是一个坐标的表示方式.
public struct Position
{
public const int PrecisionCompensationPower = 20;
public const int PrecisionCompensationScale = 1048576; // 2^20
public readonly int LatitudeInt; // North is negative!
public readonly int LongitudeInt;
}
Run Code Online (Sandbox Code Playgroud)
重要的是,可能的比例因子也明确地绑定到2的幂.这允许我们用比特移位替换乘法.所以真正的算法看起来像这样:
public Point MapToScreen(Position input)
{
Point result = new Point();
result.X = (input.LongitudeInt - this.UpperLeftPosition.LongitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
result.Y = (input.LatitudeInt - this.UpperLeftPosition.LatitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
return result;
}
Run Code Online (Sandbox Code Playgroud)
(UpperLeftPosition表示地图空间中屏幕的左上角.) 我现在正在考虑将此计算卸载到GPU.谁能告诉我一个如何做到这一点的例子?
我们使用.NET4.0,但代码最好也应该在Windows XP上运行.此外,GPL下的库我们无法使用.
现在一年后这个问题又出现了,我们找到了一个非常平庸的答案。我觉得自己有点愚蠢,没有早点意识到这一点。我们通过普通的 WinForms GDI 将地理元素绘制为位图。GDI 是硬件加速的。我们所要做的不是自己进行转换,而是设置 System.Drawing.Graphics 对象的比例参数:Graphics.TranslateTransform(...) 和 Graphics.ScaleTransform(...) 我们甚至不需要技巧随着位移位。
:)