关于矩形连线 (rectangle connect)

矩形连线问题,就是在两个矩形之间建立带可曲折的无覆盖的连线(连线不覆盖图形),我的方法是这样的:

 

CPoint pts[5];//输出连线的点列表

int nPts;//输出点列表中点的数量

 

void GetRectConnectLines(CPoint * pts,int nPts )

CRect recta,rectb;//两个矩形

CPoint ac,bc; //矩形中心

CRect rectc;//中心连线矩形 

int aw = recta.Width(); 

int bw = rectb.Width(); 

int ah = recta.Height();

int bh = rectb.Height();

ac = recta.CenterPoint();

  bc = rectb.CenterPoint();

rectc = CRect( ac,bc );

int cw = rectc.Width();

int ch = rectc.Height();

 

//(1)当矩形可以找到中心分隔线的时候,并且距离不小于某个限定值(不应该在过小的间隙中连接),矩形靠近中间分隔线的中点就连接到中间分隔线上。 

int ld = 50;//限定中分线间隔距离

int td = 0;

td = cw*2-aw-bw;

if( td > ld*2 ) //如果中心连接矩形的宽度比两个矩形的宽度和还要大,则存在竖直的中心分割线(用*2判断防止整数除法丢失精度)

{

if( ac.x < bc.x ) //a矩形的右边和b矩形的左边连接到竖直中分线

pts[0] = ac;

pts[0].Offset( aw/2.f,0 );

pts[1] = pts[0];

pts[1].Offset( td/4.f,0 );

pts[3] = bc;

pts[3].Offset( -bw/2.f,0);

pts[2] = pts[3];

pts[2].Offset( -td/4.f,0);


pts[1].x = pts[2].x ;//对齐 

}

else  //a矩形的左边和b矩形的右边连接到竖直中分线

{
pts[0] = ac; pts[0].Offset( -aw/2.f,0 ); pts[1] = pts[0]; pts[1].Offset( -td/4.f,0 ); pts[3] = bc; pts[3].Offset( bw/2.f,0); pts[2] = pts[3]; pts[2].Offset( td/4.f,0); pts[1].x = pts[2].x ;//对齐

nPts = 4;

return; 

 

//同样的方法找到水平中分线,并把边连接上去 

td = ch*2-ah-bh;

if( td > ld*2 )

{

if( ac.y < bc.y )

{

pts[0] = ac;

pts[0].Offset( 0,ah/2.f );

pts[1] = pts[0];

pts[1].Offset( 0,td/4.f );

pts[3] = bc;

pts[3].Offset( 0,-bh/2.f);

pts[2] = pts[3];

pts[2].Offset( 0,-td/4.f);


pts[1].y = pts[2].y ;


}

else

{

pts[0] = ac;

pts[0].Offset( 0,-ah/2.f );

pts[1] = pts[0];

pts[1].Offset( 0,-td/4.f );

pts[3] = bc;

pts[3].Offset( 0,bh/2.f);

pts[2] = pts[3];

pts[2].Offset( 0,td/4.f);


pts[1].y = pts[2].y ;

}

nPts = 4;

return;

 

//(2)如果两个矩形找不到中分线,而且都没有互相覆盖边的中点,那么就取最近的垂直边进行连接。

 

if((cw*2< min(aw , bw) + ld) && (ch*2< max(ah , bh) + ld))

{ pts[0] = ac; pts[0].Offset( aw/2,0); pts[1] = ac; pts[1].Offset( dd.x,0); pts[2] = bc; pts[2].Offset( 0,-bh/2); nPts = 3; return; }

//(3)第三种情况,获得两个矩形的最小外接矩形,把未覆盖的边连接到外接矩形的边上去,优先寻找同侧的可连接边

rectc.UnionRect( recta,rectb );//外接矩形

rectc.InflateRect( ld/2,ld/2 );//外扩一点距离


int ea[4] = {0,0,0,0};

int eb[4] = {0,0,0,0};

 

//找出没有被覆盖中点的边 ,优先连接可以同侧连接的边,即 (eb[i]&&ea[i]);如果没有同侧可连接边就连接下一条边(ea[i]&&eb[i<3?i:0])

if( recta->left<rectb->left )

{

ea[0] = 1;

if( (bc.y>recta->bottom) || (bc.y < recta->top) )

{

eb[0] = 1;

}

}

else

{

eb[0] =1;

if( (ac.y>rectb->bottom) || (ac.y<recta->top ))

{

ea[0] = 1;

}

}


if( recta->right > rectb->right )

{

ea[1] = 1;

if( (bc.y>recta->bottom) || (bc.y < recta->top) )

{

eb[1] = 1;

}

}

else

{

eb[1] =1;

if( (ac.y>rectb->bottom) || (ac.y<recta->top ))

{

ea[1] = 1;

}

}


if( recta->top<rectb->top )

{

ea[2] = 1;

if( (bc.x>recta->right) || (bc.x < recta->left) )

{

eb[2] = 1;

}

}

else

{

eb[2] =1;

if( (ac.x>rectb->right) || (ac.x<recta->left ))

{

ea[2] = 1;

}

}


if( recta->bottom>rectb->bottom )

{

ea[3] = 1;

if( (bc.x>recta->right) || (bc.x < recta->left) )

{

eb[3] = 1;

}

}

else

{

eb[3] =1;

if( (ac.x>rectb->right) || (ac.x<recta->left ))

{

ea[3] = 1;

}

}

// 连接代码未给出,请读者自行完善。 

 

//(4)第四种情况,一个矩形被另一个矩形包含而不重合,内矩形的边连接到外矩形的边的内侧

//(5)第五种情况,两个矩形完全重叠,连线应该是不可见 

 

 }


你可能感兴趣的:(connect)