Note
算法是这样:
1.初始化
先计算出两条经线上所有截面圆上的点的纬度。
纬度的计算如下:
设这个球的球心坐标centroIn<xIn, yIn, zIn>,外边那个球心坐标centroEx<xEx, yEx, zEx>
那么指向外面球心坐标的向量就是centroVec = centroEx - centroIn
设球顶点为A(Azimuth),centroIn(C)与球面交点为O,截面圆上任意一点为P,根据球面余弦,有
cos∠PCO = cos∠PCA cos∠OCA + sin∠PCA sin∠OCA cos∠PAO
其中,
cos∠PCO = (RadiusEx^2- RadiusIn^2- ||centroVec||^2) / (2 RadiusIn ||centroVec||) (余弦定理)
cos∠OCA = (zEx-zIn)/||centroVec||
sin∠OCA = (1-%^2)^(1/2) 手工忽略non-trivial解,否则这个方程就四个解了,但有两个是没用的
cos∠PAO = cos(arccos(||Most[centroVec]||/||centroVec||)-Longi)
最后得到的解便是∠PCA关于P所在的精度Longi的函数。这个值一个是进入被截区域的纬度,一个是离开时的纬度。那么很自然的,如果两个区间有重叠,那么就需要合并成一个区间,取最早进入和最晚离开的纬度。
2. 开始画
两条经线同时增加纬度向下找,如果小于进入被截区域的纬度就记录下来,如果大于被截区域的纬度就把被截区域的纬度记录下来并且不再记录。用一个布尔标记来记录要不要记录纬度
如果两条纬线同时找到了进入被截区域的纬度,那么沿一条正序一条逆序的顺序围成一个convex hull,再调用绘图的subroutine,按GL_QUAD_STRIP画出来。此时迭代子还在继续运动,直到两条经线都找到离开被截区域的纬度,才把两个布尔标记都放下来,继续记录。
直到纬度到了Pi,进入下一次迭代。下一次迭代覆盖上上一条经线的纬度记录,然后按照一开始的方法重复进行。
========================================================
算法设计完之后就是数据结构了。
用来存储经线上点的结构最好是数组。因为有一个glVertex3fv()可以直接用数组,效率肯定比自己一个一个找要高。
这样每画一个stack就需要四条数组,其中两条是二维的,用来记录进入被截区域纬度和离开被截区域纬度,它们是在绘图之前就计算好的。
1.初始化
先计算出两条经线上所有截面圆上的点的纬度。
纬度的计算如下:
设这个球的球心坐标centroIn<xIn, yIn, zIn>,外边那个球心坐标centroEx<xEx, yEx, zEx>
那么指向外面球心坐标的向量就是centroVec = centroEx - centroIn
设球顶点为A(Azimuth),centroIn(C)与球面交点为O,截面圆上任意一点为P,根据球面余弦,有
cos∠PCO = cos∠PCA cos∠OCA + sin∠PCA sin∠OCA cos∠PAO
其中,
cos∠PCO = (RadiusEx^2- RadiusIn^2- ||centroVec||^2) / (2 RadiusIn ||centroVec||) (余弦定理)
cos∠OCA = (zEx-zIn)/||centroVec||
sin∠OCA = (1-%^2)^(1/2) 手工忽略non-trivial解,否则这个方程就四个解了,但有两个是没用的
cos∠PAO = cos(arccos(||Most[centroVec]||/||centroVec||)-Longi)
最后得到的解便是∠PCA关于P所在的精度Longi的函数。这个值一个是进入被截区域的纬度,一个是离开时的纬度。那么很自然的,如果两个区间有重叠,那么就需要合并成一个区间,取最早进入和最晚离开的纬度。
2. 开始画
两条经线同时增加纬度向下找,如果小于进入被截区域的纬度就记录下来,如果大于被截区域的纬度就把被截区域的纬度记录下来并且不再记录。用一个布尔标记来记录要不要记录纬度
如果两条纬线同时找到了进入被截区域的纬度,那么沿一条正序一条逆序的顺序围成一个convex hull,再调用绘图的subroutine,按GL_QUAD_STRIP画出来。此时迭代子还在继续运动,直到两条经线都找到离开被截区域的纬度,才把两个布尔标记都放下来,继续记录。
直到纬度到了Pi,进入下一次迭代。下一次迭代覆盖上上一条经线的纬度记录,然后按照一开始的方法重复进行。
========================================================
算法设计完之后就是数据结构了。
用来存储经线上点的结构最好是数组。因为有一个glVertex3fv()可以直接用数组,效率肯定比自己一个一个找要高。
这样每画一个stack就需要四条数组,其中两条是二维的,用来记录进入被截区域纬度和离开被截区域纬度,它们是在绘图之前就计算好的。