KPolygon.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:8k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KPolygon.cpp
  5. // Date: 2002.01.10
  6. // Code: Spe
  7. // Desc: Polygon Functions
  8. //---------------------------------------------------------------------------
  9. #include "KWin32.h"
  10. #include "KDebug.h"
  11. #include "KPolygon.h"
  12. #include <string.h>
  13. //////////////////////////////
  14. // Construction/Destruction //
  15. //////////////////////////////
  16. KPolygon::KPolygon()
  17. {
  18. m_Polygon.nVertex = 0;
  19. ZeroMemory(m_Polygon.Pos, sizeof(POINT) * defMaxVertex);
  20. }
  21. BOOL KPolygon::IsPointInPolygon(POINT pos)
  22. {
  23. static POINT pPos[defMaxVertex+1];
  24. BOOL bRet = TRUE;
  25. int nFlag[2];
  26. int nResult;
  27. register int i;
  28. for (i = 0; i < m_Polygon.nVertex; i++)
  29. {
  30. pPos[i].x = m_Polygon.Pos[i].x - pos.x;
  31. pPos[i].y = m_Polygon.Pos[i].y - pos.y;
  32. }
  33. pPos[m_Polygon.nVertex] = pPos[0];
  34. nFlag[1] = 0;
  35. for (i = 0; i < m_Polygon.nVertex; i++)
  36. {
  37. nResult = pPos[i].x * pPos[i + 1].y - pPos[i + 1].x * pPos[i].y;
  38. nFlag[0]=(nResult>0)?1:((nResult<0)?-1:0);
  39. if (nFlag[0])
  40. {
  41. if (!nFlag[1])
  42. {
  43. nFlag[1] = nFlag[0];
  44. }
  45. if (nFlag[0] != nFlag[1])
  46. {
  47. bRet = FALSE;
  48. break;
  49. }
  50. }
  51. }
  52. return bRet;
  53. }
  54. BOOL KPolygon::IsPointInPolygon(int x, int y)
  55. {
  56. static POINT pPos[defMaxVertex+1];
  57. BOOL bRet = TRUE;
  58. int nFlag[2];
  59. int nResult;
  60. register int i;
  61. for (i = 0; i < m_Polygon.nVertex; i++)
  62. {
  63. pPos[i].x = m_Polygon.Pos[i].x - x;
  64. pPos[i].y = m_Polygon.Pos[i].y - y;
  65. }
  66. pPos[m_Polygon.nVertex] = pPos[0];
  67. nFlag[1] = 0;
  68. for (i = 0; i < m_Polygon.nVertex; i++)
  69. {
  70. nResult = pPos[i].x * pPos[i + 1].y - pPos[i + 1].x * pPos[i].y;
  71. nFlag[0]=(nResult>0)?1:((nResult<0)?-1:0);
  72. if (nFlag[0])
  73. {
  74. if (!nFlag[1])
  75. {
  76. nFlag[1] = nFlag[0];
  77. }
  78. if (nFlag[0] != nFlag[1])
  79. {
  80. bRet = FALSE;
  81. break;
  82. }
  83. }
  84. }
  85. return bRet;
  86. }
  87. int KPolygon::GetNearVertex(POINT pos)
  88. {
  89. int i;
  90. int nMin = 0x7fffffff;
  91. int nIndex;
  92. for (i = 0; i < m_Polygon.nVertex; i++)
  93. {
  94. if ((m_Polygon.Pos[i].x - pos.x) * (m_Polygon.Pos[i].x - pos.x) + (m_Polygon.Pos[i].y - pos.y) * (m_Polygon.Pos[i].y - pos.y) < nMin)
  95. {
  96. nIndex = i;
  97. nMin = (m_Polygon.Pos[i].x - pos.x) * (m_Polygon.Pos[i].x - pos.x) + (m_Polygon.Pos[i].y - pos.y) * (m_Polygon.Pos[i].y - pos.y);
  98. }
  99. }
  100. return nIndex;
  101. }
  102. BOOL KPolygon::GetIndexVertex(int i, POINT* vertex)
  103. {
  104. if (i >= m_Polygon.nVertex)
  105. return FALSE;
  106. vertex->x = m_Polygon.Pos[i].x;
  107. vertex->y = m_Polygon.Pos[i].y;
  108. return TRUE;
  109. }
  110. BOOL KPolygon::RemoveIndexVertex(int index)
  111. {
  112. if (m_Polygon.nVertex < 4)
  113. return FALSE;
  114. m_Polygon.nVertex --;
  115. for (int i = index; i < defMaxVertex - 1; i++)
  116. {
  117. m_Polygon.Pos[i] = m_Polygon.Pos[i+1];
  118. }
  119. return TRUE;
  120. }
  121. BOOL KPolygon::AddPointToVertex(POINT pos)
  122. {
  123. int nPrevIndex, nNextIndex;
  124. if (m_Polygon.nVertex < 3)
  125. {
  126. m_Polygon.Pos[m_Polygon.nVertex] = pos;
  127. m_Polygon.nVertex++;
  128. return TRUE;
  129. }
  130. if (m_Polygon.nVertex >= defMaxVertex)
  131. return FALSE;
  132. //-------------------------------------------------------------------
  133. // Add Point to Polygon Last point First
  134. POINT pVector[2];
  135. int nResult, nFlag[2];
  136. m_Polygon.Pos[m_Polygon.nVertex] = pos;
  137. nFlag[1] = 0;
  138. for (int i = 0; i < m_Polygon.nVertex + 1; i++)
  139. {
  140. nPrevIndex = i - 1;
  141. if (nPrevIndex < 0)
  142. nPrevIndex = m_Polygon.nVertex;
  143. nNextIndex = i + 1;
  144. if (nNextIndex > m_Polygon.nVertex)
  145. nNextIndex = 0;
  146. // Get Vector of point to next point
  147. pVector[0].x = m_Polygon.Pos[nNextIndex].x - m_Polygon.Pos[i].x;
  148. pVector[0].y = m_Polygon.Pos[nNextIndex].y - m_Polygon.Pos[i].y;
  149. // Get Vector of point to previous point
  150. pVector[1].x = m_Polygon.Pos[nPrevIndex].x - m_Polygon.Pos[i].x;
  151. pVector[1].y = m_Polygon.Pos[nPrevIndex].y - m_Polygon.Pos[i].y;
  152. nResult = pVector[0].x * pVector[1].y - pVector[1].x * pVector[0].y;
  153. nFlag[0] = (nResult > 0)?1:((nResult < 0)?-1:0);
  154. if (nFlag[0])
  155. {
  156. if (!nFlag[1])
  157. {
  158. nFlag[1] = nFlag[0];
  159. }
  160. if (nFlag[0] != nFlag[1])
  161. {
  162. m_Polygon.Pos[m_Polygon.nVertex].x = 0;
  163. m_Polygon.Pos[m_Polygon.nVertex].y = 0;
  164. return FALSE;
  165. }
  166. }
  167. }
  168. //-------------------------------------------------------------------
  169. m_Polygon.nVertex++;
  170. return TRUE;
  171. }
  172. BOOL KPolygon::AddPointToVertex(int x, int y)
  173. {
  174. int nPrevIndex, nNextIndex;
  175. if (m_Polygon.nVertex < 3)
  176. {
  177. m_Polygon.Pos[m_Polygon.nVertex].x = x;
  178. m_Polygon.Pos[m_Polygon.nVertex].y = y;
  179. m_Polygon.nVertex++;
  180. return TRUE;
  181. }
  182. if (m_Polygon.nVertex >= defMaxVertex)
  183. return FALSE;
  184. //-------------------------------------------------------------------
  185. // Add Point to Polygon Last point First
  186. POINT pVector[2];
  187. int nResult, nFlag[2];
  188. m_Polygon.Pos[m_Polygon.nVertex].x = x;
  189. m_Polygon.Pos[m_Polygon.nVertex].y = y;
  190. nFlag[1] = 0;
  191. for (int i = 0; i < m_Polygon.nVertex + 1; i++)
  192. {
  193. nPrevIndex = i - 1;
  194. if (nPrevIndex < 0)
  195. nPrevIndex = m_Polygon.nVertex;
  196. nNextIndex = i + 1;
  197. if (nNextIndex > m_Polygon.nVertex)
  198. nNextIndex = 0;
  199. // Get Vector of point to next point
  200. pVector[0].x = m_Polygon.Pos[nNextIndex].x - m_Polygon.Pos[i].x;
  201. pVector[0].y = m_Polygon.Pos[nNextIndex].y - m_Polygon.Pos[i].y;
  202. // Get Vector of point to previous point
  203. pVector[1].x = m_Polygon.Pos[nPrevIndex].x - m_Polygon.Pos[i].x;
  204. pVector[1].y = m_Polygon.Pos[nPrevIndex].y - m_Polygon.Pos[i].y;
  205. nResult = pVector[0].x * pVector[1].y - pVector[1].x * pVector[0].y;
  206. nFlag[0] = (nResult > 0)?1:((nResult < 0)?-1:0);
  207. if (nFlag[0])
  208. {
  209. if (!nFlag[1])
  210. {
  211. nFlag[1] = nFlag[0];
  212. }
  213. if (nFlag[0] != nFlag[1])
  214. {
  215. m_Polygon.Pos[m_Polygon.nVertex].x = 0;
  216. m_Polygon.Pos[m_Polygon.nVertex].y = 0;
  217. return FALSE;
  218. }
  219. }
  220. }
  221. //-------------------------------------------------------------------
  222. m_Polygon.nVertex++;
  223. return TRUE;
  224. }
  225. void KPolygon::LoopVertex(int nTurn)
  226. {
  227. if (nTurn > m_Polygon.nVertex)
  228. return;
  229. if (nTurn < 0)
  230. nTurn = m_Polygon.nVertex + nTurn;
  231. int nNext;
  232. POINT BackPos[defMaxVertex];
  233. memcpy(BackPos, m_Polygon.Pos, sizeof(POINT) * defMaxVertex);
  234. for (int j = 0; j < m_Polygon.nVertex; j++)
  235. {
  236. nNext = j + nTurn;
  237. if (nNext >= m_Polygon.nVertex)
  238. nNext -= m_Polygon.nVertex;
  239. m_Polygon.Pos[j] = BackPos[nNext];
  240. }
  241. }
  242. void KPolygon::Clear()
  243. {
  244. m_Polygon.nVertex = 0;
  245. ZeroMemory(m_Polygon.Pos, sizeof(POINT) * defMaxVertex);
  246. }
  247. void KPolygon::GetCenterPos(POINT *pos)
  248. {
  249. pos->x = 0;
  250. pos->y = 0;
  251. for (int i = 0; i < m_Polygon.nVertex; i++)
  252. {
  253. pos->x += m_Polygon.Pos[i].x;
  254. pos->y += m_Polygon.Pos[i].y;
  255. }
  256. pos->x /= m_Polygon.nVertex;
  257. pos->y /= m_Polygon.nVertex;
  258. }
  259. BOOL KPolygon::ShiftVertex(int nDir, int nDistance)
  260. {
  261. int i;
  262. switch(nDir)
  263. {
  264. case 0:
  265. for (i = 0; i < m_Polygon.nVertex; i++)
  266. {
  267. m_Polygon.Pos[i].y += nDistance;
  268. }
  269. break;
  270. case 1:
  271. for (i = 0; i < m_Polygon.nVertex; i++)
  272. {
  273. m_Polygon.Pos[i].x -= nDistance;
  274. m_Polygon.Pos[i].y += nDistance;
  275. }
  276. break;
  277. case 2:
  278. for (i = 0; i < m_Polygon.nVertex; i++)
  279. {
  280. m_Polygon.Pos[i].x -= nDistance;
  281. }
  282. break;
  283. case 3:
  284. for (i = 0; i < m_Polygon.nVertex; i++)
  285. {
  286. m_Polygon.Pos[i].x -= nDistance;
  287. m_Polygon.Pos[i].y -= nDistance;
  288. }
  289. break;
  290. case 4:
  291. for (i = 0; i < m_Polygon.nVertex; i++)
  292. {
  293. m_Polygon.Pos[i].y -= nDistance;
  294. }
  295. break;
  296. case 5:
  297. for (i = 0; i < m_Polygon.nVertex; i++)
  298. {
  299. m_Polygon.Pos[i].x += nDistance;
  300. m_Polygon.Pos[i].y -= nDistance;
  301. }
  302. break;
  303. case 6:
  304. for (i = 0; i < m_Polygon.nVertex; i++)
  305. {
  306. m_Polygon.Pos[i].x += nDistance;
  307. }
  308. break;
  309. case 7:
  310. for (i = 0; i < m_Polygon.nVertex; i++)
  311. {
  312. m_Polygon.Pos[i].x += nDistance;
  313. m_Polygon.Pos[i].y += nDistance;
  314. }
  315. break;
  316. default:
  317. return FALSE;
  318. }
  319. return TRUE;
  320. }
  321. int KPolygon::GetLeftVertex()
  322. {
  323. int nLeft = m_Polygon.Pos[0].x;
  324. int nIdx = 0;
  325. for (int i = 1; i < m_Polygon.nVertex; i++)
  326. {
  327. if (m_Polygon.Pos[i].x < nLeft)
  328. {
  329. nLeft = m_Polygon.Pos[i].x;
  330. nIdx = i;
  331. }
  332. }
  333. return nIdx;
  334. }
  335. int KPolygon::GetRightVertex()
  336. {
  337. int nRight = m_Polygon.Pos[0].x;
  338. int nIdx = 0;
  339. for (int i = 1; i < m_Polygon.nVertex; i++)
  340. {
  341. if (m_Polygon.Pos[i].x > nRight)
  342. {
  343. nRight = m_Polygon.Pos[i].x;
  344. nIdx = i;
  345. }
  346. }
  347. return nIdx;
  348. }