注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

季叔华

痛苦和无知是我生活的全部

 
 
 

日志

 
 

一些数学公式:点,向量,点在三角形,椭圆内  

2011-01-28 19:30:52|  分类: VC/MFC |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
typedef struct tagPOINT
{
    int x;
    int y;
} POINT;

/**
* p11p12 ×p21p22
*点的向量积
*/
int VectorMul(POINT p11, POINT p12, POINT p21, POINT p22)
{
    return ( (p12.x-p11.x)*(p22.y-p21.y) - (p22.x-p21.x)*(p12.y-p11.y) );
}

/**
* 判断两矩形区域是否相交
* 相切是返回 FALSE
*/
int MatrixIntersect(POINT p11, POINT p12, POINT p21, POINT p22)
{
    int maxX;
    int maxY;
    int minX;
    int minY;
    
    maxX = (p11.x > p12.x ? p11.x : p12.x);
    minX = (p11.x < p12.x ? p11.x : p12.x);
    maxY = (p11.y > p12.y ? p11.y : p12.y);
    minY = (p11.y < p12.y ? p11.y : p12.y);
    
    if(p21.x > minX && p21.x < maxX && p21.y > minY && p21.y < maxY
        || p22.x > minX && p22.x < maxX && p22.y > minY && p22.y < maxY)
    {
        return 1;
    }
    
    return 0;
}

/**
*:点是否在三角形内
* tr 为三角形的三个顶点
* p  为待测点
* 点在三角形边上也判断为 FALSE
*/
int IsPointInTriangle(POINT tr[], POINT p)
{
    int TMul1;   //注意取值范围
    int TMul2;
    int TMul3;
    
    TMul1 = VectorMul(tr[0], p, tr[1], p);
    TMul2 = VectorMul(tr[1], p, tr[2], p);
    TMul3 = VectorMul(tr[2], p, tr[0], p);
    
    if(TMul1 * TMul2 >= 0 || TMul1 * TMul3 >= 0 || TMul2 * TMul3 >= 0)
    {
        return 0;
    }

    return 1;
}

/**
* 判断两个三角形是否相交
* 相切返回 FALSE
* 判断两线段是否相交:
* 分两步确定两条线段是否相交:
* (1)快速排斥试验
*    设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如
*    果R和T不相交,显然两线段不会相交。
* (2)跨立试验
*    如果两线段相交,则两线段必然相互跨立对方。若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 IsTriangleIntersect(POINT tr1[], POINT tr2[])
{
    int i, j;
    
    for(i = 0; i < 3; i++) // tr1的每条线段
    {
        for(j = 0; j < 3; j++) // tr2的每条线段
        {
            // 快速排斥实验成立线段才有可能相交
            if(MatrixIntersect(tr1[i], tr1[(i + 1) % 3], tr2[j], tr2[(j + 1) % 3]))
            {
                // 跨立实验
                if(VectorMul(tr1[i], tr2[i], tr2[(i + 1) % 3], tr2[i])
                    * VectorMul(tr2[(i + 1) % 3], tr2[i], tr1[(i + 1) % 3], tr2[i]) > 0)
                {
                    return 1;
                }
                if(VectorMul(tr2[i], tr1[i], tr1[(i + 1) % 3], tr1[i])
                    * VectorMul(tr1[(i + 1) % 3], tr1[i], tr2[(i + 1) % 3], tr1[i]) > 0)
                {
                    return 1;
                }
            }
        }
    }
    
    return 0;
}

/*点是否在椭圆内
*/
int IsPointInElipse(POINT center, int XRadius, int YRadius, POINT p)
{
    int iRes;
    
    p.x -= center.x;
    p.y -= center.y;
    
    p.x *= p.x;
    p.y *= p.y;
    
    XRadius *= XRadius;
    YRadius *= YRadius;
    
    iRes = YRadius * p.x + XRadius * p.y - XRadius * YRadius;
    
    return (iRes < 0);
}
  评论这张
 
阅读(558)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018