【问题标题】:Problem with bird's eye view or 2.5D rendering of MapMap 的鸟瞰图或 2.5D 渲染问题
【发布时间】:2010-09-12 01:26:13
【问题描述】:

我正在开发一个转弯导航软件,我正在使用以下解决方案将我的道路线变成 2.5D 或 3D 视图

Draw 2.5D or 3D Map with C# from lines

但是,对于视口内 0 高度或 x > 宽度,然后上述解决方案变得疯狂。谁能帮我弄清楚如何解决这个问题?

vvvv 3D算法vvvv

.

vvvv 没有 3D 算法 vvvv

更新:: 使用此代码后

double x = p->x();
double y = p->y();

double t = -0.5;
x = x - w / 2;
y = y - h / 2;
double a = h / (h + y* sin(t));
double u = a * x + w / 2;
double v = a * y * cos(t) + h / 2;

p->setX(u);
p->setY(v);
return p;

地图变成如下

我认为当 Y 计算超出负值时会出现问题。我正在使用 Qt 并且线上的裂缝似乎是 Qt 渲染器的错误,与我们最初的问题无关。

【问题讨论】:

    标签: map geometry navigation


    【解决方案1】:

    问题是您使用的转换没有将直线映射到直线。相反,直线通常是抛物线。您可以在示例图像中看到,在 2D 视图中从上到下的或多或少笔直的主要道路在 2.5D 视图中转换为弯曲的道路。如果您将示例中“发疯”的行分成更短的部分,您会看到同样的情况。

    从数学上讲,您可以通过返回您正在使用的转换来了解发生了什么:

    x_ = (x - w/2)*(t1+(y/h)*(t2-t1)) + w/2
    y_ = y
    

    如果我们将一条直线表示为x = ay+b,那么这条线上的一个点(ay+b,y) 映射为(ay+b - w/2)*(t1+(y/h)*(t2-t1)) + w/2,y)。这个表达式看起来很复杂,但你可以看到它的计算结果类似于(c*y^2+d*y+e,y),对于c,d,e 的合适值,它是一条抛物线。

    所以你最好的选择是放弃这个转换并切换到perspective transform

    在您最初的问题中,您提到渲染图像的非仿射变换太慢了。看来您现在已经切换到在渲染线条之前对其进行转换,这已经足够快了。您现在唯一需要做的就是更改转换。

    这是一个建议的变换。只需几个步骤,即可将您的 2D (x,y) 坐标转换为 2.5D (u,v) 坐标。我假设您使用的是 C#。

    t = 0.3 // tilt angle - try different values    
    X = x - w/2 ;
    Y = y - h/2 ;
    a = h/(h + Y*Math.Sin(t)) ;
    u = a*X + w/2 ;
    v = a*Y*Math.Cos(t) + h/2 ;
    

    这里有一个参数t,它定义了倾斜量,以弧度表示。我建议使用 0.3 左右的值,正负值。

    我已经用铅笔和纸解决了这个问题,但没有运行它,所以如果这不起作用,请告诉我 .. 总是有可能存在转录错误。

    更新:您要避免绘制任何具有点 (x,y) 的实体(线、多边形等),从而使 a 为非正数。更好的是,为避免溢出,您应该避免在a<epsilon 时绘制,其中epsilon 是一些小的正值,例如 0.05 或 0.1。

    【讨论】:

    • 是的,另外,不是画一条等宽的线,而是在源地图的坐标中找出对应的多边形(矩形)。使用变换映射这 4 个顶点以制作要绘制的多边形(而不是简单的线)。这将使更远的道路更小,就像他们应该做的那样。
    • @Tom,感谢您的意见。 @brainjam,您能否为我提供一个像 x = ****** 这样的等式或代码 sn-p 吗?我薄弱的数学使我无法从 wiki 文章中获得工作代码。非常感谢
    • @VOX,我添加了建议的转换。
    • @brainjam,请看我的更新。您的代码中的 v 计算似乎有问题。再次感谢。
    • @VOX,我今天忙于截止日期,所以这可能要等到明天。但基本上困难在于您使用的Yt 值导致a 变得非常大或为负数。基本上,您的倾斜坐标在“相机后面”。所以你必须检查这一点并避免绘制结果(u,v)。在图形中,这称为裁剪 (en.wikipedia.org/wiki/Clipping_(computer_graphics))。请对此进行一些阅读和调试,如果您明天仍有问题,请告诉我您在哪里。但这仍然是进步,对吧?
    【解决方案2】:

    等式的问题在于它允许投影的 x 值穿过中线 (w/2)。这在尝试对透视变换建模时是不可取的,因为线应该接近但不交叉消失点。此外,由于方程的编写方式,这种交叉发生在相机前面而不是后面,这会导致不必要的伪影。试试这样的:

    半宽 = w/2 dx = (x - halfW) dy = (h - y) // y 向下增加 // 调整这些常数以适应口味。 顶部 = 1.25 底部 = 0.75 lowerBound = 0.1 // 避免除以零和透视线穿过中线 x_ = (dx / max(lowerBound, (bottom + ((dy / h) * (top - bottom))))) + w/2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 2013-06-07
      相关资源
      最近更新 更多