MapLine.cpp
上传用户:bjslfz
上传日期:2022-07-25
资源大小:4430k
文件大小:6k
源码类别:

文件操作

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "MapLine.h"
  3. IMPLEMENT_DYNAMIC(CMapLine,CObject)
  4. CMapLine::CMapLine()
  5. {
  6. }
  7. CMapLine::CMapLine(CMapLine& mapline )
  8. {
  9.    int i,iCount;
  10.    CMapParts *pParts;
  11.    
  12.    iCount = m_Line.GetSize() - 1;
  13.    for ( i = 0 ; i <= iCount ; i++ )
  14.    { 
  15. pParts = new CMapParts(*(mapline.GetParts(i)));
  16. m_Line.Add(pParts); 
  17.    }
  18. }
  19. CMapLine::~CMapLine()
  20. {
  21.      Clear();
  22. }
  23. long CMapLine::GetCount()
  24. {
  25. return m_Line.GetSize(); 
  26. }
  27. CMapRectangle CMapLine::GetExtent()
  28. {
  29.     return m_Extent;
  30. }
  31. void CMapLine::SetExtent(CMapRectangle& extent)
  32. {
  33. m_Extent.SetLeft( extent.GetLeft());
  34. m_Extent.SetRight( extent.GetRight());
  35. m_Extent.SetTop(extent.GetTop());
  36.     m_Extent.SetBottom(extent.GetBottom());
  37. }
  38. CMapParts* CMapLine::GetParts(long lIndex)
  39. {
  40. int iCount;
  41. CMapParts  *pParts = NULL;
  42. iCount = m_Line.GetSize()-1;
  43. if ( lIndex < 0 || lIndex > iCount )
  44. return pParts;
  45.     pParts = m_Line.GetAt(lIndex);
  46. return pParts;
  47. }
  48. double CMapLine::GetLength()
  49. {
  50. return 0;
  51. }
  52. /*****************************************************************************
  53.   描述:   点到线距离
  54.   参数:  点
  55.   返回值  距离
  56. ******************************************************************************/
  57. double CMapLine::Distance(CMapPoint& pt )
  58. {
  59. int i,j,k;
  60. double dblMinDist,dblDist;
  61.     CMapParts  *pParts;
  62. CMapPoints *pPoints;
  63. CMapPoint  *pPoint1,*pPoint2;
  64. dblMinDist =  infinity;
  65. dblDist =  infinity;
  66. for ( i = 0 ; i < m_Line.GetSize() ; i++ )
  67. {
  68. pParts = (CMapParts*)m_Line.GetAt(i);
  69. for ( j = 0 ; j < pParts->GetCount() ; j++)
  70. {
  71. pPoints = (CMapPoints*)pParts;
  72. for( k = 0 ; k < pPoints->GetCount() - 1 ; k++)
  73. {
  74. pPoint1 = (CMapPoint*)pPoints->Get(k);
  75. pPoint2 = (CMapPoint*)pPoints->Get(k+1);
  76. //计算点到线段最小距离
  77. dblDist = ptToSegment(pt,*pPoint1,*pPoint2);
  78.                 if ( dblDist <= EP )
  79. return 0.0;
  80. else if ( dblDist < dblMinDist )
  81.                     dblMinDist = dblDist;
  82.             }    
  83. }
  84.     }  
  85. return dblMinDist;
  86. }
  87. /*****************************************************************************
  88.   描述:    计算点到线段最小距离
  89.   参数:   p1 --- 线段起点 p2 --- 线段终点
  90.   返回值:  在点到线段最小距离  
  91. ******************************************************************************/
  92. double CMapLine::ptToSegment(CMapPoint& pt,CMapPoint& ptStart,CMapPoint& ptEnd)
  93. {
  94. double dblDist,dblX,dblY,k;
  95. CMapPoint pPlumb;
  96. if ( pt.IsPointInLine(ptStart, ptEnd) )
  97. return 0.0; //点在直线上
  98.     if ( fabs(ptEnd.GetX() - ptStart.GetX()) <= EP )
  99. {
  100. dblX = ptStart.GetX();
  101. dblY = pt.GetY();
  102. pPlumb.SetX(dblX);
  103. pPlumb.SetY(dblY);
  104. if ( pPlumb.GetY() > min(ptStart.GetY(), ptEnd.GetY()) && pPlumb.GetY()
  105. < max(ptStart.GetY(), ptEnd.GetY()))
  106.         {
  107. //垂足在线段范围内
  108. return fabs(pPlumb.GetX() -pt.GetX());  
  109.         } 
  110. else
  111.         {   //判断线段的哪个端点离垂足比较近,然后计算两点间距离
  112.             if ( fabs(pPlumb.GetY() - ptStart.GetY()) < fabs(pPlumb.GetY() - ptEnd.GetY()))
  113.    dblDist = pt.Distance(ptStart); 
  114. else
  115.    dblDist = pt.Distance(ptEnd); 
  116.         } 
  117. //线段为垂直情况    
  118.     } else if ( fabs(ptEnd.GetY() - ptStart.GetY()) <= EP )
  119.     {
  120. //线段为水平情况
  121. dblX = pt.GetX();
  122. dblY = ptStart.GetY();
  123. pPlumb.SetX(dblX);
  124. pPlumb.SetY(dblY);
  125. if ( pPlumb.GetX() > min(ptStart.GetX(), ptEnd.GetX()) && pPlumb.GetX()
  126. < max(ptStart.GetX(), ptEnd.GetX()))
  127.         {
  128. //垂足在线段范围内
  129. return fabs(pPlumb.GetY() -pt.GetY());  
  130.         } 
  131. else
  132.         {   //判断线段的哪个端点离垂足比较近,然后计算两点间距离
  133.             if ( fabs(pPlumb.GetX() - ptStart.GetX()) < fabs(pPlumb.GetX() - ptEnd.GetX()))
  134.    dblDist = pt.Distance(ptStart); 
  135. else
  136.    dblDist = pt.Distance(ptEnd); 
  137.         } 
  138.     } 
  139. else
  140.     {
  141. //线段倾斜状态
  142. k = (double)((ptEnd.GetY() - ptStart.GetY() ) /(ptEnd.GetX() - ptStart.GetX()));
  143. // 计算垂足坐标
  144. dblX = (k*k*ptStart.GetX() + k*(pt.GetY()-ptStart.GetY())+pt.GetX())/(k*k+1);    
  145. dblY = k*(dblX-ptStart.GetX()) + ptStart.GetY(); 
  146. pPlumb.SetX(dblX);
  147. pPlumb.SetY(dblY);
  148. if ( pPlumb.IsPointInLine(ptStart,ptEnd) )
  149.         {
  150. //垂足在线段上
  151.     dblDist = pt.Distance(pPlumb);  
  152.         }  
  153. else
  154.         {
  155. //判断线段的哪个端点离垂足比较近,然后计算两点间距离
  156. if ( pPlumb.Distance(ptStart) < pPlumb.Distance(ptEnd))
  157.                dblDist = pt.Distance(ptStart); 
  158. else
  159.    dblDist = pt.Distance(ptEnd); 
  160.  
  161.     }
  162. return dblDist;
  163. }
  164. void CMapLine::Add(CMapParts* pParts)
  165. {
  166.     if ( pParts == NULL )
  167. return;
  168. m_Line.Add( pParts );
  169. }
  170. void CMapLine::Set(long lIndex , CMapParts* pParts)
  171. {
  172. int iCount;
  173. CMapParts *pOldParts;
  174. if ( pParts == NULL )
  175. return;
  176. iCount = m_Line.GetSize()-1;
  177. if ( lIndex < 0 || lIndex > iCount )
  178. return ;
  179.     pOldParts = m_Line.GetAt( lIndex );
  180.     m_Line.SetAt(lIndex,pParts);
  181.     delete pOldParts; 
  182. }
  183. void CMapLine::Remove(long lIndex)
  184. {
  185. int iCount;
  186. CMapParts *pParts;
  187. iCount = m_Line.GetSize()-1;
  188. if ( lIndex < 0 || lIndex > iCount )
  189. return ;
  190. pParts = m_Line.GetAt( lIndex );  
  191.     m_Line.RemoveAt(lIndex,1);   
  192. delete pParts; 
  193. }
  194. void CMapLine::Insert(long lIndex , CMapParts* pParts)
  195. {
  196. int iCount;
  197. iCount = m_Line.GetSize()-1;
  198. if ( lIndex < 0 || lIndex > iCount )
  199. return ;
  200. m_Line.InsertAt(lIndex,pParts);
  201. }
  202. void CMapLine::Clear()
  203. {
  204.    int i,iCount;
  205.    CMapParts *pParts;
  206.    
  207.    iCount = m_Line.GetSize() - 1;
  208.    for ( i = iCount ; i >= 0   ; i-- )
  209.    {
  210. pParts = m_Line.GetAt(i);
  211. delete pParts;
  212.    } 
  213.    m_Line.RemoveAll(); 
  214. }