Map 鸟的问题';s视图或地图的2.5D渲染
我正在开发一个逐路段导航软件,我正在使用以下解决方案将我的道路线转换为2.5D或3D视图 但是,对于0Map 鸟的问题';s视图或地图的2.5D渲染,map,geometry,navigation,Map,Geometry,Navigation,我正在开发一个逐路段导航软件,我正在使用以下解决方案将我的道路线转换为2.5D或3D视图 但是,对于0
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左右的值,正负
我用铅笔和纸解决了这个问题,但没有运行它,所以让我知道我