zoukankan      html  css  js  c++  java
  • 点是否在三角形内的判断

    1.利用三角形ABC面积,1/2*|A||B|Sin(a); 任意一点P,分别向三角形(A,B,C)三个顶点连线,形成三个三角形(PAB,PBC,PAC)。如果S(ABC)==S(PAB)+S(PBC)+S(PAC),则点在三角形内,反之,在三角形外

    2.判断点是否在三条边的同一层

    先说一下叉乘:

    设矢量P   =   (x1,y1)   ,Q   =   (x2,y2)
    则矢量叉积定义为:     P   ×   Q   =   x1*y2   –   x2*y1       得到的是一个标量
    显然有性质   P   ×   Q   =   –   (   Q   ×   P   )       P   ×   (   –   Q   )   =   –   (   P   ×   Q   )
    如不加说明,下面所有的点都看作矢量,点的乘法看作矢量叉积;
    叉乘的重要性质:
     若   P   ×   Q     >   0   ,     则P   在Q的顺时针方向
    &#61548; 若   P   ×   Q     <   0   ,     则P   在Q的逆时针方向
    &#61548; 若   P   ×   Q     =   0   ,     则P   与Q共线,但可能同向也可能反向

    我提出的算法中有一步要判断顺时针逆时针的方向,其实很简单。假设有两端连续的险段,其公共端点是P0,其他的两个端点是P1和P1,计算向量 <P0,P1> 和 <P0,P2> 的叉乘,如果若结果为正,则 <P0,P1> 在 <P0,P2> 的顺时针方向;若为0则 <P0,P1> <P0,P2> 共线(可能同向和反向);若为负则 <P0,P1> 在 <P0,P2> 的在逆时针方向。因此可以根据这个判断p0p1和p1p2在p1处是左转还是右转,只要求(p2-p0)*(p1-p0),若 <0则左转,> 0则右转,=0则共线。


    下面的简单的函数可以计算叉乘。


    #define   infinity   1e20
    #define   EP   1e-10

    struct   TPoint   {
            float   x,y;
    };

    struct   TLineSeg   {
            TPoint   a,b;
    };


    /********************************************************   *                                                                                                            
      *     返回(P1-P0)*(P2-P0)的叉积。                                                  
      *     若结果为正,则 <P0,P1> 在 <P0,P2> 的顺时针方向;                
      *     若为0则 <P0,P1> <P0,P2> 共线;                                                
      *     若为负则 <P0,P1> 在 <P0,P2> 的在逆时针方向;                          
      *     可以根据这个函数确定两条线段在交点处的转向,                  
      *     比如确定p0p1和p1p2在p1处是左转还是右转,只要求            
      *     (p2-p0)*(p1-p0),若 <0则左转,> 0则右转,=0则共线        
      *                                                                                                      
    \********************************************************/

    float   multiply(TPoint   p1,   TPoint   p2,   TPoint   p0)
    {
            return   (   (   p1.x   -   p0.x   )   *   (   p2.y   -   p0.y   )   -   (   p2.x   -   p0.x   )   *   (   p1.y   -   p0.y   )   );        
    }

    叉乘还有很多用途,举例如下:

    1。判断点在线段上
    设点为Q,线段为P1P2   ,判断点Q在该线段上的依据是:
    (   Q   –   P1   )   ×   (   P2   –   P1   )   =   0     且   Q   在以   P1,P2为对角顶点的矩形内

    //   判断点p是否在线段l上
    int   online(TLineSeg   l,TPoint   p)
    {
            return(   (multiply(l.b,p,l.a)==0)&&(   ((p.x-l.a.x)*(p.x-l.b.x) <0   )||(   (p.y-l.a.y)*(p.y-l.b.y) <0   ))   );
    }


    2。判断两线段是否相交
    我们分两步确定两条线段是否相交:
    1.快速排斥试验
    设以线段   P1P2   为对角线的矩形为R,   设以线段   Q1Q2   为对角线的矩形为T,如果R和T不相交,显然两线段不会相交;
    2.跨立试验
    如果两线段相交,则两线段必然相互跨立对方,如图1所示(可惜这里无法显示图:(     )。在图1中,P1P2跨立Q1Q2   ,则矢量   (   P1   –   Q1   )   和(   P2   –   Q1   )位于矢量(   Q2   –   Q1   )   的两侧,即
    (   P1   –   Q1   )   ×   (   Q2   –   Q1   )     *     (   P2   –   Q1   )   ×   (   Q2   –   Q1   )     <     0
    上式可改写成
    (   P1   –   Q1   )   ×   (   Q2   –   Q1   )     *     (   Q2   –   Q1   )   ×   (   P2   –   Q1   )     >     0
    当   (   P1   –   Q1   )   ×   (   Q2   –   Q1   )   =   0   时,说明   (   P1   –   Q1   )   和   (   Q2   –   Q1   )共线,但是因为已经通过快速排斥试验,所以   P1   一定在线段   Q1Q2上;同理,(   Q2   –   Q1   )   ×(   P2   –   Q1   )     =   0   说明   P2   一定在线段   Q1Q2上。
    所以判断P1P2跨立Q1Q2的依据是:
    (   P1   –   Q1   )   ×   (   Q2   –   Q1   )     *     (   Q2   –   Q1   )   ×   (   P2   –   Q1   )     ≥     0
    同理判断Q1Q2跨立P1P2的依据是:
    (   Q1   –   P1   )   ×   (   P2   –   P1   )     *     (   P2   –   P1   )   ×   (   Q2   –   P1   )     ≥     0
    至此已经完全解决判断线段是否相交的问题。


    //确定两条线段是否相交
    int   intersect(TLineSeg   u,TLineSeg   v)
    {
            return(   (max(u.a.x,u.b.x)> =min(v.a.x,v.b.x))&&
                            (max(v.a.x,v.b.x)> =min(u.a.x,u.b.x))&&
                            (max(u.a.y,u.b.y)> =min(v.a.y,v.b.y))&&
                            (max(v.a.y,v.b.y)> =min(u.a.y,u.b.y))&&
                            (multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)> =0)&&
                            (multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)> =0));
    }

  • 相关阅读:
    Json对象与Json字符串互转(4种转换方式)
    Web.config配置文件详解
    jQuery BlockUI Plugin Demo 6(Options)
    jQuery BlockUI Plugin Demo 5(Simple Modal Dialog Example)
    jQuery BlockUI Plugin Demo 4(Element Blocking Examples)
    jQuery BlockUI Plugin Demo 3(Page Blocking Examples)
    jQuery BlockUI Plugin Demo 2
    <configSections> 位置引起的错误
    关于jQuery的cookies插件2.2.0版设置过期时间的说明
    jQuery插件—获取URL参数
  • 原文地址:https://www.cnblogs.com/waterdragon/p/2661180.html
Copyright © 2011-2022 走看看