鸟瞰图或2.5D渲染地图的问题

时间:2010-09-05 19:51:02

标签: map geometry navigation

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

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

然而,上述解决方案对于视口内的线路是非常好的,其中0 <0。 x&lt;宽度和0 < y&lt;身高。然而,有些线可能具有y 高度或x>宽度然后上面的解决方案疯了。谁能帮我弄清楚如何解决这个问题?

vvvv使用3D算法vvvv

alt text

vvvv没有3D算法vvvv

alt text

更新:: 使用此代码后

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;

地图变得如下 alt text

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

2 个答案:

答案 0 :(得分:4)

问题是您正在使用的变换不会将直线映射到直线。相反,直线通常是抛物线。您可以在示例图像中看到,在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。

答案 1 :(得分:0)

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

halfW = w/2
dx = (x - halfW)
dy = (h - y) // y increases downwards
// tune these constants to taste.
top = 1.25
bottom = 0.75
lowerBound = 0.1 // Avoids divide by zero and perspective lines crossing midline
x_ = (dx / max(lowerBound, (bottom + ((dy / h) * (top - bottom))))) + w/2