有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c#检查位置是否在矩形周界内的有效方法?

我将首先介绍这个问题:我正在开发一个应用程序,其中我必须显示一个地图字段,并覆盖标记和线。然而,在BlacBerry OS 5.0中,API中唯一可用的MapField并没有提供覆盖内容的方法,只在某个位置显示地图。它还提供了将屏幕坐标(像素)转换为WGS84坐标的方法。这些方法的计算成本可能很高

所以为了绘制我自己的项目,我需要扩展这个类并重写它的paint()方法。扩展类还将包含一组位置。这就是重写方法的样子(我将在这里使用Java):

        public void paint (Graphics g) {
            super.paint(g); //draws the map

            //TODO
            //Draw placemarks. The placemarks are basically holder objects
            //(for latitude and longitude) stored in a collection in this class.
        }

然而,要在屏幕上绘制这些对象,我们应该首先将placemark位置(lat,long)转换为屏幕坐标(x,y,以像素为单位)。这无法提前完成,因为地图不是静态的,所以它可以滚动并缩小。这就是为什么在每个绘制循环中,我们至少应该绘制可见的对象。尽管如此,我的问题是:

给定一个矩形周长,其中角点是地理位置(地图当前显示部分的四个变换角),是否有快速方法在集合中的每个地点标记上循环,并确定它们是否可见

我不需要这个测试是100%准确的,我不介意屏幕外的几个位置被涂上。但由于placemark集合可以包含许多元素(<;100),并且每次重新绘制屏幕时都会调用paint方法,因此在不检查集合中的每个位置是否可见的情况下尝试绘制,可能会影响性能,并在用户与地图交互时引入延迟

在您尝试提供一个简单的答案之前,请注意这不是一个简单的几何问题:我们使用的是地理坐标,而不是整数屏幕坐标。世界的终点不是经度+180,也不是纬度+90。这个函数应该在极点和ecuator中起作用,所以当我们有一条过渡线(从-180到+180,或从-90到+90,或两条线)与矩形相交时,我需要它也起作用。由于逻辑可能变得复杂,我想知道是否有一个现有的算法或开源库已经完成并测试过,而不是实现我自己的算法或开源库

我还可以首先将集合中的每个位置转换为屏幕坐标,然后轻松检查仅由正屏幕坐标组成的矩形(从x=0,y=0开始),但由于转换函数可能很昂贵,我认为在每次刷新中只变换4个点(可见的地图角点)比不确定数量的Placemark更好

任何其他方法或想法也将不胜感激

提前谢谢


共 (3) 个答案

  1. # 1 楼答案

    这只是一个简单的想法:取“矩形”的两个相对的角,例如左上角和右下角。通过以下方式将两个角点变换为笛卡尔空间坐标(x,y,z)

    x = cos[long] cos[lat]
    y = sin[long] cos[lat]
    z = sin[lat] 
    

    两个(x,y,z)坐标都是单位向量(假设球体的中心位于(0,0,0),向量是从那里到曲面的箭头)。找到地图区域的“中间”作为两个角向量的赋范平均值(作为向量相加,然后除以和向量的长度,以确保有一个新的单位向量)。当你有中间(xMiddle,yMiddle,zMiddle)时,对于每个转换成笛卡尔(x,y,z)的地标坐标,使用(xMiddle,yMiddle,zMiddle)的点积作为与中间的接近程度的度量

    现在包括每一个点积为(xMiddle,yMiddle,zMiddle)大于左上角点积为(xMiddle,yMiddle,zMiddle)的地点标记

    这会让你在一个以“中间”为中心的圆盘内找到所有的位置标记

  2. # 2 楼答案

    在地图坐标空间中,至少可以通过简单的复选框排除大量候选对象。这里可能有三个主要案例。要么有一个极点在矩形中,要么没有。如果极点不可见,要么矩形穿过+/-180度线,要么没有。不可能有任何+/-90线,因为这将把北极和南极放在一起,而你没有使用4D地图,是吗?;-)

    案例1,一根杆子是可见的: 如果是北极,找出哪个角的纬度最小。任何比这更小的纬度都有可能出现在屏幕外。如果是南极,只需颠倒逻辑,即使用最大纬度,排除任何纬度更大的项目。 我知道,极点在一个角落,赤道在另一个角落,意味着你仍然包括整个半球。但至少你可以省钱地排除另一半

    情况2,无杆,未穿过+/-180经度线: 找到最小/最大经度和纬度值,并将其用于简单的复选框。盒子外的任何东西都在屏幕外

    情况3,无杆,但穿过+/-180经度线: 和上面的纬度相同。对于经度,分别找出距离+180和-180最远的经度。排除纬度超出最小/最大值或位于两个最远经度之间的任何项目

    案例2和案例3应该能够排除足够多的候选人,以便对其他人进行暴力检查。案例1可能需要进一步的后处理,但如果你想要复杂的东西,恐怕这部分对我来说太复杂了。 我想如果磁极离屏幕中心更远的话,你可以找到离磁极最近的离屏幕点。然后以某种方式构建一个三角形形状,其中一个角位于该点,并在不接触屏幕矩形的情况下使其尽可能大

  3. # 3 楼答案

    我想你只需要把你的直肠肌周长转换成地理坐标。 而不是试图将地理坐标转换为屏幕坐标

    很抱歉,答案很幼稚——但你问的是逻辑。 所以我想象的合乎逻辑的东西是一个在空间上滑动的窗口,这意味着你需要把这个窗口的地理坐标作为你的参考点

    处理完这些“3d”信息后,就可以开始渲染视图了