zoukankan      html  css  js  c++  java
  • 计算点、线、面等元素之间的交点、交线、封闭区域面积和闭合集(待续)

    地理信息系统软件开发中经常需要求取点、线、面之间的交点、交线、封闭区域面积和闭合集等结果,采用以矢量点乘和叉乘为基础的求取算法符合实际工作中已给出点位置和法向量等条件的情况,效率较高。

    首先给出基本公式的推导。

    矢量的结合率和交换率:

    U+(V+W) = (U+V) + W;

    U+V=V+U;

    而设线段的起点和终点为P,Q;则中间任意一点R可以表示为:

    R = P + r(Q - P); (0<r<1)

    P0,P1P2三点构成的共面参数方程可表示为如下一种形式:

    P(s,t) = (1-s-t)P0+sP1+tP2,其中s,t为参数

    矢量的长度定义为:

    V = (a,b); |V| = sqrt(a*a + b*b); (即各轴数据平方和的开方)

    而向量的规范化是 U = V/|V|,使得向量的长度为单位1

    矢量的点乘定义:

    V–W = v1w1+v2w2V= (v1,v2) , W = (w1,w2);

    此定义可从二维空间类推到三维和其他高次空间。

    我们知道,二维平面上面一点Px,y)在坐标轴转动某角度α后,新坐标为P(xnew,ynew)

    P点距离原点为r,此点与原X轴夹角为δ,则

    x = rcosδ, y = rsinδ

    可求得新坐标为:xnew = rcos(δ-α)=rcosδcosα + rsinδsinα = xcosα + ysinα

    ynew =rsin(δ-α)=rsinδcosα rcosδsinα = ycosα xsinα

    下面推导广泛运用的一个公式:

    V–W = |V||W|cosϕϕ为两向量的交角

    若V = (v1,0),既此点落在X轴上,则V–W = v1w1 + 0w2 = v1w1

    因为V点落在轴上,则 |V| = v1,|W| cosϕ = w1;所以 V–W = |V||W|cosϕ

    若为一般情况,即V= (v1,v2),则我们可旋转原始坐标轴角度δ使得V点落在新X轴上,

    由于: (v1w1 + v2w2)/|V| = w1cosδ+ w2sinδ = W点在新坐标系下的X轴数值 = |W| cosϕ

    因此 v1w1 + v2w2 = |V||W|cosϕ

    在平时的运用中,计算cosϕ = V–W / |V||W| ,可对两向量的交角大小进行判断,若V–W0,则说明两向量互相垂直;若V–W大于0,则|ϕ|<90度,说明交角为锐角。

    设向量V(a,b),对其旋转90度后,得到U= (acos90 + bsin90, ycos90-xsin90) = (b,-a);可由此方法得到向量的垂直向量。

    V–W = |V||W|cosϕ公式的推导中可以类推|V||W|sinϕ等于什么呢?推导如下:

    |W|sinϕ = W点在新坐标系下的Y轴数值 = w2cosδ-w1sinδ= w2v1/|V|-w1v2/|V|=

    (v1w2-v2w1)/|V|,

    v1w2-v2w1 =  |V||W|sinϕϕ为两向量的交角

           在平时的运用中,可采用此公式计算三角形和四边形的面积。也能判断两向量的位置关系,如果计算v1w2-v2w1为0,则说明两向量交角为0度或180度,即共线。如果计算结果大于0,则说明两向量交角0度到180度之间。

    求取向量之间位置关系和三角形面积的参考代码:

    //    Input: three points P0, P1, and P2

    //    Return: >0 for P2 left of the line through P0 and P1

    //            =0 for P2 on the line

    //            <0 for P2 right of the line

    double CDEMAlgorithm::isLeft( Point P0, Point P1, Point P2 )

    {

        return ( (P1.x - P0.x) * (P2.y - P0.y)

            - (P2.x - P0.x) * (P1.y - P0.y) );       //使用右手法则确定叉乘的方向

    }

    double CDEMAlgorithm::orientation2D_Triangle( Point V0, Point V1, Point V2 )

    {

        return isLeft(V0, V1, V2);                        //判断位置关系

    }

    double CDEMAlgorithm::area2D_Triangle( Point V0, Point V1, Point V2 )

    {

        return isLeft(V0, V1, V2) / 2.0;                  //求三角形的面积

    }

    double CDEMAlgorithm::dist3D_Line_to_Line( Line L1, Line L2)
    {
     Vector   u = L1.P1 - L1.P0;
     Vector   v = L2.P1 - L2.P0;
     Vector   w = L1.P0 - L2.P0;
     double    a = Dot(u,u);        // always >= 0
     double    b = Dot(u,v);
     double    c = Dot(v,v);        // always >= 0
     double    d = Dot(u,w);
     double    e = Dot(v,w);
     double    D = a*c - b*b;       // always >= 0
     double    sc, tc;

     // compute the line parameters of the two closest points
     if (D < EPS) {         // 几乎平行
      sc = 0.0;
      tc = (b>c ? d/b : e/c);   // 
     }
     else {
      sc = (b*e - c*d) / D;
      tc = (a*e - b*d) / D;
     }

       //sc,tc分别指示了在两条 直线上的 比例参数
      Vector   dP = w + (sc * u) - (tc * v);  // = L1(sc) - L2(tc)

     return sqrt(Dot(dP,dP));   // return the closest distance

    }

    附图:

  • 相关阅读:
    Spring笔记②--各种属性注入
    Spring笔记①--helloworld
    Structs2笔记③--局部类型转换案例
    Struct2笔记②--完善登陆代码
    Structs2笔记①--structs的背景、structs2框架的意义、第一个helloworld
    软件项目的开发之svn的使用
    Java基础第一节.Java简介
    Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码
    Hibernate笔记③--集合映射、组合映射、联合主键、查询案例
    Hibernate笔记②--hibernate类生成表、id生成策略、级联设置、继承映射
  • 原文地址:https://www.cnblogs.com/wuhanhoutao/p/1093265.html
Copyright © 2011-2022 走看看