Map 鸟的问题';s视图或地图的2.5D渲染

Map 鸟的问题';s视图或地图的2.5D渲染,map,geometry,navigation,Map,Geometry,Navigation,我正在开发一个逐路段导航软件,我正在使用以下解决方案将我的道路线转换为2.5D或3D视图 但是,对于0

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

但是,对于0高度或x>宽度,然后上述解决方案变得疯狂。有人能帮我找出解决这个问题的办法吗

带3D算法的VVVVV

无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渲染器的线条上的裂缝似乎有问题,与我们最初的问题无关。

该公式的问题是它允许投影的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 半宽=宽/2 dx=(x-halfW) dy=(h-y)//y向下增加 //根据口味调整这些常数。 顶部=1.25 底部=0.75 lowerBound=0.1//避免被零除和穿过中线的透视线 x=(dx/max(下边界,(底部+((dy/h)*(顶部-底部‘‘‘)’))+w/2
该公式的问题在于,它允许投影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 半宽=宽/2 dx=(x-halfW) dy=(h-y)//y向下增加 //根据口味调整这些常数。 顶部=1.25 底部=0.75 lowerBound=0.1//避免被零除和穿过中线的透视线 x=(dx/max(下边界,(底部+((dy/h)*(顶部-底部‘‘‘)’))+w/2
问题是您正在使用的转换没有将直线映射到直线。相反,直线通常是抛物线。您可以在示例图像中看到,在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
,这是一条抛物线

因此,您最好的选择是放弃此转换并切换到

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

这里有一个建议的转换。这需要几个步骤,将2D(x,y)坐标转换为2.5D(u,v)坐标。我想你用的是C

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

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


更新:您希望避免绘制任何具有点
(x,y)
的实体(直线、多边形等),从而使
a
为非正。更好的是,为了避免溢出,您应该避免在
a时绘制。问题是您使用的转换没有将直线映射到直线。相反,直线通常是抛物线。您可以在示例图像中看到,在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
,这是一条抛物线

因此,您最好的选择是放弃此转换并切换到

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

这里有一个建议的转换。这需要几个步骤,将2D(x,y)坐标转换为2.5D(u,v)坐标。我想你用的是C

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

我用铅笔和纸解决了这个问题,但没有运行它,所以让我知道我