关于矩形连线 (rectangle connect)
矩形連線問(wèn)題,就是在兩個(gè)矩形之間建立帶可曲折的無(wú)覆蓋的連線(連線不覆蓋圖形),我的方法是這樣的:
?
CPoint pts[5];//輸出連線的點(diǎn)列表
int nPts;//輸出點(diǎn)列表中點(diǎn)的數(shù)量
?
void GetRectConnectLines(CPoint * pts,int nPts?)
{?
CRect recta,rectb;//兩個(gè)矩形
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)當(dāng)矩形可以找到中心分隔線的時(shí)候,并且距離不小于某個(gè)限定值(不應(yīng)該在過(guò)小的間隙中連接),矩形靠近中間分隔線的中點(diǎn)就連接到中間分隔線上。?
int ld = 50;//限定中分線間隔距離
int td = 0;
td = cw*2-aw-bw;
if( td > ld*2 ) //如果中心連接矩形的寬度比兩個(gè)矩形的寬度和還要大,則存在豎直的中心分割線(用*2判斷防止整數(shù)除法丟失精度)
{
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 ;//對(duì)齊?
}
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 ;//對(duì)齊
}?
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)如果兩個(gè)矩形找不到中分線,而且都沒(méi)有互相覆蓋邊的中點(diǎn),那么就取最近的垂直邊進(jìn)行連接。
?
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)第三種情況,獲得兩個(gè)矩形的最小外接矩形,把未覆蓋的邊連接到外接矩形的邊上去,優(yōu)先尋找同側(cè)的可連接邊
rectc.UnionRect( recta,rectb );//外接矩形
rectc.InflateRect( ld/2,ld/2 );//外擴(kuò)一點(diǎn)距離
int ea[4] = {0,0,0,0};
int eb[4] = {0,0,0,0};
?
//找出沒(méi)有被覆蓋中點(diǎn)的邊?,優(yōu)先連接可以同側(cè)連接的邊,即 (eb[i]&&ea[i]);如果沒(méi)有同側(cè)可連接邊就連接下一條邊(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;
}
}
//?連接代碼未給出,請(qǐng)讀者自行完善。?
?
//(4)第四種情況,一個(gè)矩形被另一個(gè)矩形包含而不重合,內(nèi)矩形的邊連接到外矩形的邊的內(nèi)側(cè)
//(5)第五種情況,兩個(gè)矩形完全重疊,連線應(yīng)該是不可見(jiàn)?
?
?}
轉(zhuǎn)載于:https://www.cnblogs.com/cgwolver/archive/2010/01/04/1639140.html
總結(jié)
以上是生活随笔為你收集整理的关于矩形连线 (rectangle connect)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《清夜琴兴》第十二句是什么
- 下一篇: java压缩解压缩类实例[转]