ClippingPoints.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #include "ClippingPoints.h"
  2. ClippingPoints::ClippingPoints()
  3. {
  4. }
  5. bool ClippingPoints :: getClippingPoints(double* dRectU , double* dRectV,
  6. int* iCordinates, int* iClipPoints )
  7. {
  8. // https://code.google.com/p/chilay/source/browse/src/main/java/org/ivis/util/IGeometry.java?name=
  9. //SBGN+Layout&r=e3f8360f41dfd86012603d678861b8f462b58659
  10. //dRect[i] = centrex,i+1 = centrey,i+2 = height,i+3 = width,i+4 = lefttopx,i+5 = lefttopy;
  11. int i=0;
  12. double dVXCoord =dRectV[i],dVYCoord = dRectV[i+1],dUXCoord = dRectU[i],
  13. dUYCoord = dRectU[i+1] ;
  14. // variables for rectangle U
  15. double dUHeight = dRectU[i+2], dUWidth=dRectU[i+3], dVHeight = dRectV[i+2],
  16. dVWidth = dRectV[i+3], dUXTopLeft = dRectU[4], dUYTopLeft = dRectU[5],
  17. dVXTopLeft = dRectV[4], dVYTopLeft = dRectV[5];
  18. bool bClipA = false, bClipB = false ;
  19. // line is vertical
  20. if(dUXCoord == dVXCoord)
  21. {
  22. if(dUYCoord > dUYCoord)
  23. {
  24. iClipPoints[0] = (int) dUXCoord;
  25. iClipPoints[1] = (int) dUYTopLeft;
  26. iClipPoints[2] = (int) dVXCoord;
  27. iClipPoints[3] = (int) dVYTopLeft - dVHeight;
  28. return false ;
  29. }
  30. else if(dUYCoord < dVYCoord)
  31. {
  32. iClipPoints[0] = (int) dUXCoord;
  33. iClipPoints[1] = (int) dUYTopLeft - dUHeight;
  34. iClipPoints[2] = (int) dVXCoord;
  35. iClipPoints[3] = (int) dVYTopLeft;
  36. return false;
  37. }
  38. else
  39. {
  40. // not a line
  41. return false;
  42. }
  43. }
  44. else if( dUYCoord == dVYCoord )
  45. {
  46. if(dUXCoord > dVXCoord)
  47. {
  48. iClipPoints[0] = (int) dUXTopLeft;
  49. iClipPoints[1] = (int) dUYCoord;
  50. iClipPoints[2] = (int) dVXTopLeft+ dVWidth ;
  51. iClipPoints[3] = (int) dVYCoord;
  52. return false;
  53. }
  54. else if(dUXCoord < dVXCoord)
  55. {
  56. iClipPoints[0] = (int) dUXTopLeft + dUWidth;
  57. iClipPoints[1] = (int) dUYCoord;
  58. iClipPoints[2] = (int) dVXTopLeft ;
  59. iClipPoints[3] = (int) dVYCoord;
  60. return false;
  61. }
  62. else
  63. {
  64. return false;
  65. }
  66. }
  67. else
  68. {
  69. double dSlopeU = dUHeight / dUWidth ;
  70. double dSlopeV = dVHeight / dVWidth ;
  71. double dSlopePrime = (dVYCoord - dUYCoord) / (dVXCoord - dUXCoord);
  72. int iCardinalDirecU , iCardinalDirecV;
  73. double dTempUX, dTempUY , dTempVX , dTempVY;
  74. if( - dSlopeU == dSlopePrime)
  75. {
  76. if(dUXCoord > dVXCoord)
  77. {
  78. iClipPoints[0] = dUXTopLeft;
  79. iClipPoints[1] = dUYTopLeft - dUHeight;
  80. bClipA = true;
  81. }
  82. else
  83. {
  84. iClipPoints[0] = dUXTopLeft + dUWidth;
  85. iClipPoints[1] = dVYTopLeft;
  86. bClipA = true;
  87. }
  88. }
  89. else if (dSlopeU == dSlopePrime )
  90. {
  91. if(dUXCoord > dVXCoord)
  92. {
  93. iClipPoints[0] = dUXTopLeft;
  94. iClipPoints[1] = dUYTopLeft;
  95. bClipA = true;
  96. }
  97. else
  98. {
  99. iClipPoints[0] = dUXTopLeft + dUWidth ;
  100. iClipPoints[1] = dUYTopLeft - dUHeight;
  101. bClipA = true;
  102. }
  103. }
  104. //
  105. if( (- dSlopeV ) == dSlopePrime )
  106. {
  107. if( dVXCoord > dUXCoord )
  108. {
  109. iClipPoints[2] = dVXTopLeft ;
  110. iClipPoints[3] = dVYTopLeft - dVHeight;
  111. bClipB = true;
  112. }
  113. else
  114. {
  115. iClipPoints[2] = dVXTopLeft + dVWidth ;
  116. iClipPoints[3] = dVYTopLeft ;
  117. bClipB = true;
  118. }
  119. }
  120. else if( dSlopeV == dSlopePrime )
  121. {
  122. if( dVXCoord > dUXCoord )
  123. {
  124. iClipPoints[2] = dVXTopLeft ;
  125. iClipPoints[3] = dVYTopLeft ;
  126. bClipB = true;
  127. }
  128. else
  129. {
  130. iClipPoints[2] = dVXTopLeft + dVWidth ;
  131. iClipPoints[3] = dVYTopLeft - dVWidth ;
  132. bClipB = true;
  133. }
  134. }
  135. //
  136. if( bClipA && bClipB )
  137. {
  138. return false;
  139. }
  140. // determine cardinal direction of rectangles .
  141. if(dUXCoord > dVXCoord )
  142. {
  143. if(dUYCoord > dVYCoord )
  144. {
  145. iCardinalDirecU = getCardinalDirections(dSlopeU,dSlopePrime,4);
  146. iCardinalDirecV = getCardinalDirections(dSlopeV,dSlopePrime,2);
  147. }
  148. else
  149. {
  150. iCardinalDirecU = getCardinalDirections(-dSlopeU,dSlopePrime,3);
  151. iCardinalDirecV = getCardinalDirections(-dSlopeV,dSlopePrime,1);
  152. }
  153. }
  154. else
  155. {
  156. if(dUYCoord > dVYCoord )
  157. {
  158. iCardinalDirecU = getCardinalDirections(-dSlopeU,dSlopePrime,1);
  159. iCardinalDirecV = getCardinalDirections(-dSlopeV,dSlopePrime,3);
  160. }
  161. else
  162. {
  163. iCardinalDirecU = getCardinalDirections(dSlopeU,dSlopePrime,2);
  164. iCardinalDirecV = getCardinalDirections(dSlopeV,dSlopePrime,4);
  165. }
  166. }
  167. // calculate clipping pt if not calculated earlier
  168. if(!bClipA)
  169. {
  170. switch (iCardinalDirecU) {
  171. case 1:
  172. dTempUX = dUXCoord + (- dUHeight /2)/ dSlopePrime;
  173. dTempUY = dUYTopLeft;
  174. iClipPoints[0] = dTempUX;
  175. iClipPoints[1] = dTempUY;
  176. break;
  177. case 2:
  178. dTempUX = dUXTopLeft + dUWidth;
  179. dTempUY = dUYCoord + (dUWidth/2)*dSlopePrime ;
  180. iClipPoints[0] = dTempUX;
  181. iClipPoints[1] = dTempUY;
  182. break;
  183. case 3:
  184. dTempUX = dUXCoord + (dUHeight /2)/ dSlopePrime;
  185. dTempUY = dUYTopLeft - dUHeight;
  186. iClipPoints[0] = dTempUX;
  187. iClipPoints[1] = dTempUY;
  188. break;
  189. case 4:
  190. dTempUX = dUXTopLeft;
  191. dTempUY = dUYCoord + (-dUWidth /2)*dSlopePrime ;
  192. iClipPoints[0] = dTempUX;
  193. iClipPoints[1] = dTempUY;
  194. break;
  195. default:
  196. break;
  197. }
  198. }
  199. if(!bClipB)
  200. {
  201. switch (iCardinalDirecV) {
  202. case 1:
  203. dTempVX = dVXCoord + (-dVHeight/2)*dSlopePrime;
  204. dTempVY = dUYTopLeft;
  205. iClipPoints[2] = dTempVX;
  206. iClipPoints[3] = dTempVY;
  207. break;
  208. case 2:
  209. dTempVX = dVXTopLeft + dVWidth;
  210. dTempVY = dVYCoord + (dVWidth/2)*dSlopePrime ;
  211. iClipPoints[2] = dTempVX;
  212. iClipPoints[3] = dTempVY;
  213. break;
  214. case 3:
  215. dTempVX = dVXCoord + (dVHeight /2)/ dSlopePrime;
  216. dTempVY = dVYTopLeft - dVHeight;
  217. iClipPoints[2] = dTempVX;
  218. iClipPoints[3] = dTempVY;
  219. break;
  220. case 4:
  221. dTempVX = dVXTopLeft;
  222. dTempVY = dVYCoord + (-dVWidth /2)*dSlopePrime ;
  223. iClipPoints[2] = dTempVX;
  224. iClipPoints[3] = dTempVY;
  225. break;
  226. default:
  227. break;
  228. }
  229. }
  230. }
  231. return false;
  232. }
  233. int ClippingPoints :: getCardinalDirections(double dSlope,double dSlopePrime, int iLine)
  234. {
  235. if(dSlope > dSlopePrime)
  236. {
  237. return iLine;
  238. }
  239. else
  240. {
  241. return (1 + iLine % 4 ) ;
  242. }
  243. }
  244. bool ClippingPoints :: doIntersect(int *iP , int*iQ)
  245. {
  246. /*
  247. // returns true if two line segments intersect
  248. // ip ={ x1,y1,x2,y2}
  249. // Find the four orientations needed for general and
  250. // special cases
  251. int o1 = orientation( iP[0],iP[1],iP[2],iP[3],iQ[0],iQ[1]);
  252. int o2 = orientation( iP[0],iP[1],iP[2],iP[3],iQ[2],iQ[3]);
  253. int o3 = orientation( iQ[0],iQ[1],iQ[2],iQ[3],iP[0],iP[1]);
  254. int o4 = orientation(iQ[0],iQ[1],iQ[2],iQ[3] ,iP[2],iP[3]);
  255. // General case
  256. if (o1 != o2 && o3 != o4)
  257. {
  258. return true;
  259. }
  260. return false; // Doesn't fall in any of the above cases */
  261. float a1, a2, b1, b2, c1, c2;
  262. float r1, r2 , r3, r4;
  263. // Compute a1, b1, c1, where line joining points 1 and 2
  264. // is "a1 x + b1 y + c1 = 0".
  265. a1 = iP[1] - iP[3];
  266. b1 = iP[0] - iP[2];
  267. c1 = (iP[2] * iP[1]) - (iP[0] * iP[3]);
  268. // Compute r3 and r4.
  269. r3 = ((a1 * iQ[0]) + (b1 * iQ[1]) + c1);
  270. r4 = ((a1 * iQ[2]) + (b1 * iQ[3]) + c1);
  271. // Check signs of r3 and r4. If both point 3 and point 4 lie on
  272. // same side of line 1, the line segments do not intersect.
  273. if ((r3 != 0) && (r4 != 0) && ((r3 > 0 && r4> 0)|| (r3<0 && r4 <0))){
  274. return false;
  275. }
  276. else
  277. {
  278. return true;
  279. }
  280. }
  281. int ClippingPoints :: orientation(int ipx, int ipy ,int iqx ,int iqy ,int irx ,int iry )
  282. {
  283. int val = (iqy - ipy) * (irx - iqx) -
  284. (iqx - ipx) * (iry - iqy);
  285. if (val == 0) return 0; // colinear
  286. return (val > 0)? 1: 2;
  287. }
  288. void ClippingPoints :: calcIntersection(int *iP , int* iEdge, int* iIntersection )
  289. {
  290. float iDx1 , iDy1 , iDx2 , iDy2 , im1, im2 , iC1 , iC2 ;
  291. iDx1 = iP[0] - iP[2] +0.00001;
  292. iDy1 = iP[1] - iP[3] + 0.00001 ;
  293. im1 = iDy1/iDx1;
  294. iC1 = iP[1] - (im1 *iP[0]);
  295. iDx2 = iEdge[0] - iEdge[2] +0.00001; // to remove divide by zero
  296. iDy2 = iEdge[1] - iEdge[3] + 0.00001;
  297. im2 = iDy2/iDx2;
  298. iC2 = iEdge[3] - (im2 * iEdge[2]);
  299. iIntersection[0] = (iC2 - iC1)/(im1 - im2);
  300. iIntersection[1] = im1*iIntersection[0] + iC1;
  301. }