我在对话框中放置了几个Picture控件。我想获得这些Picture控件相对于对话框的位置,用来判断点是否在某个Picture控件内。
还有一个问题,我想在这些Picture控件内显示为图,但又不想创建太多的CDC对象,我只想创建一个CPaintDC 对象,就可以在这些不同的Picture内绘图,该怎么办?

解决方案 »

  1.   

    判断点是否在多边形内的算法如下。
    以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,
    考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多
    边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的
    交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
    但是有些特殊情况要加以考虑。如果L和多边形的顶点相交,有些情况下交点只能计算一个
    ,有些情况下交点不应被计算(你自己画个图就明白了);如果L和多边形的一条边重合,
    这条边应该被忽略不计。为了统一起见,我们在计算射线L和多边形的交点的时候,1。对于
    多边形的水平边不作考虑;2。对于多边形的顶点和L相交的情况,如果该顶点是其所属的边
    上纵坐标较大的顶点,则计数,否则忽略;3。对于P在多边形边上的情形,直接可判断P属
    于多边行。由此得出算法的伪代码如下:1. count ← 0;
    2. 以P为端点,作从右向左的射线L;  
    3, for 多边形的每条边s
    4.   do if P在边s上  
    5.          then return true;
    6.      if s不是水平的
    7.          then if s的一个端点在L上且该端点是s两端点中纵坐标较大的端点
    9.                  then count ← count+1
    10.              else if s和L相交
    11.                 then count ← count+1;
    12. if count mod 2 = 1 
    13.   then return true
    14.   else return false;
    其中做射线L的方法是:设P'的纵坐标和P相同,横坐标为正无穷大(很大的一个正数),则
    P和P'就确定了射线L。这个算法的复杂度为O(n)。其中判断点是否在线段上的算法如下:设点为Q,线段为P1 P2 ,判断点Q在该线段上的依据是:
    ( Q - P1 ) × ( P2 - P1 ) = 0  且 Q 在以 P1,P2为对角顶点的矩形内,其中矢量叉积
    定义为:P × Q = x1*y2 - x2*y1 得到的是一个标量。矢量减法就是x,y坐标分别相减,得
    到的还是一个矢量。判断线段是否相交的算法如下。我们分两步确定两条线段是否相交:
    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
    至此已经完全解决判断线段是否相交的问题。
      

  2.   

    首先取Picture的指针pWnd=GetDlgItem(ID_YOUPICTURE) 然后 pWnd->GetClientDC 
    pDc->GetClientRect( MyCient)  
    用Myclient.IsPtInRect()
      

  3.   

    首先取Picture的指针pWnd=GetDlgItem(ID_YOUPICTURE) 然后 pWnd->GetClientDC 
    pDc->GetClientRect( MyCient)  
    用Myclient.IsPtInRect(point)
      

  4.   

    判断点在矩形内的方法。
    先初始化CRgn为一个矩形区域。m_RectRgn.CreateRectRgn(参数自己查)
    再用m_RectRgn.PtInRegion(point)判断
      

  5.   

    /* 判断线段是否在简单多边形内(注意:如果多边形是凸多边形,下面的算法可以化简)
       原理:
    必要条件一:线段的两个端点都在多边形内;
    必要条件二:线段和多边形的所有边都不内交;
    用途:1. 判断折线是否在简单多边形内
          2. 判断简单多边形是否在另一个简单多边形内
    */
    bool LinesegInsidePolygon(int vcount,POINT polygon[],LINESEG l)
    {
    // 判断线端l的端点是否不都在多边形内
    if(!insidepolygon(vcount,polygon,l.s)||!insidepolygon(vcount,polygon,l.e))
    return false;
    int top=0,i,j;
    POINT PointSet[MAXV],tmp;
    LINESEG s; for(i=0;i<vcount;i++)
    {
    s.s=polygon[i];
    s.e=polygon[(i+1)%vcount];
    if(online(s,l.s))                     //线段l的起始端点在线段s上
    PointSet[top++]=l.s;
    else if(online(s,l.e))                //线段l的终止端点在线段s上
    PointSet[top++]=l.e;
    else
    {
    if(online(l,s.s))                  //线段s的起始端点在线段l上
    PointSet[top++]=s.s;
    else if(online(l,s.e))          // 线段s的终止端点在线段l上
    PointSet[top++]=s.e;
    else
    {
    if(intersect(l,s))          // 这个时候如果相交,肯定是内交,返回false
    return false;
    }
    }
    } for(i=0;i<top-1;i++) /* 冒泡排序,x坐标小的排在前面;x坐标相同者,
    y坐标小的排在前面  */
    {
    for(j=i+1;j<top;j++)
    {
    if( PointSet[i].x>PointSet[j].x || fabs(PointSet[i].x-PointSet[j].x)<EP && PointSet[i].y>PointSet[j].y )
       {
    tmp=PointSet[i];
    PointSet[i]=PointSet[j];
    PointSet[j]=tmp;
    }
    }
    } for(i=0;i<top-1;i++)
    {
    tmp.x=(PointSet[i].x+PointSet[i+1].x)/2;         //得到两个相邻交点的中点
    tmp.y=(PointSet[i].y+PointSet[i+1].y)/2;
    if(!insidepolygon(vcount,polygon,tmp))
    return false;
    }
    return true;
    }