矢量图形是计算机图形学中用点、直线或者多边形等基于数学方程的几何图元表示图像。我们来讨论一下在手机上实现矢量图形的方法。
以一幅北京市区域地图为例,将其显示在手机上,并实现平移、缩放、旋转等功能。在Gis系统中,由于地球为球状天体,需将地球坐标经过投影转换成地图坐标,再经过转换成设备屏幕坐标来显示。一般而言,地图坐标系,x轴向右,y轴向上;屏幕坐标系x轴向右,y轴向下。如下图
要将地图准确显示在屏幕上,我们需要做一个转换。首先,找到地图上某点,将其与屏幕上某点对应起来。这里为简单起见,最初我们将地图中心点与显示窗口中心点对应起来。假设显示窗口中心点坐标为(m_wScreen/2,m_hScreen/2),地图中心点坐标为(m_pt2DMapCenter.x,m_pt2DMapCenter.y),缩放比例为m_dScale。其中m_pt2DMapCenter是这样来定义的:
typedef struct
{
double x;
double y;
}POINT2D;
POINT2D m_pt2DMapCenter;
好了,参照上面的坐标系图,我们可以得到一个由地图坐标到屏幕坐标的转换函数
void MapToClient(POINT &ptDst, const POINT2D &ptSrc)
{
double x,y;
x = ptSrc.x - m_pt2DMapCenter.x;
y = ptSrc.y - m_pt2DMapCenter.y;
ptDst.x = (int)(x*m_dScale) + m_wScreen/2;
ptDst.y = m_hScreen/2 - int(y*m_dScale);
}
看一下地图适配窗口的情形
再看一下缩小显示的情形
平移的功能,只要调整m_pt2DMapCenter的位置即可
有了思路,旋转的函数也出来了,以逆时针为旋转方向,注意m_AngleRatio为弧度而非角度
void MapToClient(POINT &ptDst, const POINT2D &ptSrc)
{
double x,y;
x = (ptSrc.x - m_pt2DMapCenter.x)*cos(m_AngleRatio) - (ptSrc.y - m_pt2DMapCenter.y)*sin(m_AngleRatio);
y = (ptSrc.x - m_pt2DMapCenter.x)*sin(m_AngleRatio) + (ptSrc.y - m_pt2DMapCenter.y)*cos(m_AngleRatio);
ptDst.x = (int)(x*m_dScale) + m_wScreen/2;
ptDst.y = m_hScreen/2 - int(y*m_dScale);
}
以下为旋转30度角的情形
笔者还研究出一种2D投影的方法,该方法取决于观察点的位置(x,y,z)和俯视角度,实现稍复杂,在此略过不表,有兴趣的同学可以探讨。以下为投影后的显示