QEllipseObj.cpp
上传用户:oybseng
上传日期:2015-04-27
资源大小:7831k
文件大小:18k
源码类别:

GDI/图象编程

开发平台:

Visual C++

  1. // QEllipseObj.cpp: implementation of the CQEllipseObj class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "..stdafx.h"
  5. #include "..includeResource.h"
  6. #include "..INCLUDEQEllipseObj.h"
  7. #include "..includeQCoordSys.h"
  8. #include "..includeQGISAlgorithmLib.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CQEllipseObj::CQEllipseObj():CQBaseObj() 
  18. {
  19. m_bFill = FALSE;
  20. m_ptCenter.SetX(0);
  21. m_ptCenter.SetY(0);
  22. m_fStartAngleRad = 0.0f;
  23. m_fEndAngleRad = PI;
  24. m_fRotateAngleRad = 0.0f;
  25. m_fLongAxis = 0.0f;
  26. m_fShortAxis = 0.0f;
  27. m_szObjName.Format("椭圆弧%ld",m_lObjID);
  28. m_nObjType = QGIS_OBJ_CIRCLE;  //QGIS的圆类型
  29. m_nLineType = 0; //实线 
  30. }
  31. CQEllipseObj::CQEllipseObj(double dx,double dy,double fLongAxis,double fShortAxis,double fStartAngle, double fEndAngle,double fRotateAngle):CQBaseObj()
  32. {
  33. m_szObjName.Format("椭圆弧%ld",m_lObjID);
  34. m_nObjType = QGIS_OBJ_CIRCLE;
  35. m_nLineType = 0;
  36. m_bFill = FALSE; 
  37. m_ptCenter.SetX(dx);
  38. m_ptCenter.SetY(dy);
  39. m_fLongAxis = fLongAxis;
  40. m_fShortAxis = fShortAxis;
  41. m_fStartAngleRad = fStartAngle;
  42. m_fEndAngleRad = fEndAngle;
  43. m_fRotateAngleRad = fRotateAngle;
  44. RecalculatePtlist();
  45. }
  46. CQEllipseObj::CQEllipseObj(CQEllipseObj & tmEllipse):CQBaseObj(tmEllipse)
  47. {
  48. m_szObjName.Format("椭圆弧%ld",m_lObjID);
  49. m_nObjType = QGIS_OBJ_CIRCLE;
  50. m_nLineType = 0;
  51. m_bFill = FALSE; 
  52. tmEllipse.GetCenterPoint(m_ptCenter);
  53. m_fLongAxis = tmEllipse.GetLongAxis();
  54. m_fShortAxis = tmEllipse.GetShortAxis();
  55. m_fStartAngleRad = tmEllipse.GetStartAngleRad();
  56. m_fEndAngleRad = tmEllipse.GetEndAngleRad();
  57. m_fRotateAngleRad = tmEllipse.GetRotateAngleRad();
  58. RecalculatePtlist();
  59. }
  60. void CQEllipseObj::Copy(CQEllipseObj & tmEllipse)
  61. {
  62. CQBaseObj::Copy(tmEllipse);
  63. m_szObjName.Format("椭圆弧%ld",m_lObjID);
  64. m_nObjType = QGIS_OBJ_CIRCLE;
  65. m_nLineType = 0;
  66. m_bFill = FALSE; 
  67. tmEllipse.GetCenterPoint(m_ptCenter);
  68. m_fLongAxis = tmEllipse.GetLongAxis();
  69. m_fShortAxis = tmEllipse.GetShortAxis();
  70. m_fStartAngleRad = tmEllipse.GetStartAngleRad();
  71. m_fEndAngleRad = tmEllipse.GetEndAngleRad();
  72. m_fRotateAngleRad = tmEllipse.GetRotateAngleRad();
  73. RecalculatePtlist();
  74. }
  75. //通过椭圆的参数, 重新计算椭圆显示,选择时需要的点阵
  76. void CQEllipseObj::RecalculatePtlist()
  77. {
  78. m_PtList.DeleteAll(); //在重新计算之前要把以前的点阵作废
  79. double fStart = m_fStartAngleRad - m_fRotateAngleRad;  //有效的 起始角度 
  80. double fEnd = m_fEndAngleRad - m_fRotateAngleRad;      //有效的终止角度 
  81. if(fEnd < fStart) fEnd = fEnd + 2*PI;   //如果终止角度小于起始角度的话就旋转360度
  82. double fStep = fabs(fEnd - fStart)/360; //360个点绘制椭圆
  83. if(fStep == 0)return;                   //假如步距为0则返回 
  84. double dx = 0,dy = 0;
  85. for(double fStartAngle = fStart;fStartAngle<=fEnd;fStartAngle+=fStep)
  86. {
  87. CalculatePointByAngleRad(fStartAngle,dx,dy);
  88. m_PtList.AddPoint(dx,dy);
  89. }
  90. CalculatePointByAngleRad(fEnd,dx,dy);
  91. m_PtList.AddPoint(dx,dy);
  92. }
  93. void CQEllipseObj::CalculatePointByAngleRad(double dAngleRad, CQPoint & pt)
  94. {
  95. double a = m_fLongAxis;
  96. double b = m_fShortAxis;
  97. double fAngle = dAngleRad; //角度 
  98. double R = a*b / sqrt( b*b*cos(fAngle)*cos(fAngle) + a*a*sin(fAngle)*sin(fAngle));
  99. double fx = R*cos(fAngle);
  100. double fy = R*sin(fAngle);
  101. double xx = fx*cos(m_fRotateAngleRad) - fy*sin(m_fRotateAngleRad);
  102. double yy = fx*sin(m_fRotateAngleRad) + fy*cos(m_fRotateAngleRad);
  103. xx += m_ptCenter.GetX();
  104. yy += m_ptCenter.GetY();
  105. pt.SetPoint(xx,yy);
  106. }
  107. void CQEllipseObj::CalculatePointByAngleRad(double dAngleRad, double &x, double &y)
  108. {
  109. double a = m_fLongAxis;
  110. double b = m_fShortAxis;
  111. double fAngle = dAngleRad; //角度 
  112. //这是个轴长
  113. double R = a*b / sqrt( b*b*cos(fAngle)*cos(fAngle) + a*a*sin(fAngle)*sin(fAngle));
  114. double fx = R*cos(fAngle);
  115. double fy = R*sin(fAngle);
  116. x = fx*cos(m_fRotateAngleRad) - fy*sin(m_fRotateAngleRad);
  117. y = fx*sin(m_fRotateAngleRad) + fy*cos(m_fRotateAngleRad);
  118. x += m_ptCenter.GetX();
  119. y += m_ptCenter.GetY();
  120. }
  121. CQEllipseObj::~CQEllipseObj()
  122. {
  123. m_PtList.DeleteAll(); //删除所有的点
  124. }
  125. double CQEllipseObj::GetLongAxis()
  126. {
  127. return m_fLongAxis;
  128. }
  129. double CQEllipseObj::GetShortAxis()
  130. {
  131. return m_fShortAxis;
  132. }
  133. void CQEllipseObj::SetLongAxis(double a)
  134. {
  135. if(a<=0) a = 0;
  136. m_fLongAxis = a;
  137. RecalculatePtlist();
  138. }
  139. void CQEllipseObj::SetShortAxis(double b)
  140. {
  141. if(b<=0) b = 0;
  142. m_fShortAxis = b;
  143. RecalculatePtlist();
  144. }
  145. double CQEllipseObj::GetStartAngleRad()
  146. {
  147. return m_fStartAngleRad;
  148. }
  149. double CQEllipseObj::GetEndAngleRad()
  150. {
  151. return m_fEndAngleRad;
  152. }
  153. void CQEllipseObj::SetStartAngleRad(double dAngDeg)
  154. {
  155. m_fStartAngleRad = dAngDeg;
  156. RecalculatePtlist();
  157. }
  158. void CQEllipseObj::SetEndAngleRad(double dAngDeg)
  159. {
  160. m_fEndAngleRad = dAngDeg;
  161. RecalculatePtlist();
  162. }
  163. double CQEllipseObj::GetRotateAngleRad()
  164. {
  165. return m_fRotateAngleRad;
  166. }
  167. void CQEllipseObj::SetRotateAngleRad(double dAngDeg)
  168. {
  169. m_fRotateAngleRad = dAngDeg;
  170. RecalculatePtlist();
  171. }
  172. //返回一个椭圆对象的指针
  173. CQEllipseObj * CQEllipseObj::CreateEllipse(CQPoint ptCenter,double fLongAxis,double fShortAxis,double fStartAngle, double fEndAngle,double fRotateAngle)
  174. {
  175. CQEllipseObj * pEllipse = new CQEllipseObj;
  176. pEllipse->SetCenterPoint(ptCenter);
  177. pEllipse->SetLongAxis(fLongAxis);
  178. pEllipse->SetShortAxis(fShortAxis);
  179. pEllipse->SetRotateAngleRad(fRotateAngle);
  180. pEllipse->SetStartAngleRad(fStartAngle);
  181. pEllipse->SetEndAngleRad(fEndAngle);
  182. pEllipse->RecalculatePtlist();
  183. return pEllipse;
  184. }
  185. void CQEllipseObj::Display(CQCoordSys * pSys,CDC * pDC,int nDrawMode,int nSpecialMode,COLORREF * pColor)
  186. {
  187. //首先进行选择判断 如果当前椭圆对象的边界矩形不再视口范围内就不进行显示 
  188. if(GetObjDeleted() || GetObjHided())return;
  189. if(m_bFill)
  190. {
  191. DisplayPolygon(pSys,pDC,nDrawMode,nSpecialMode,pColor);
  192. }
  193. else
  194. {
  195. DisplayPolyline(pSys,pDC,nDrawMode,nSpecialMode,pColor);
  196. }
  197. }
  198. //以区域的方式进行绘制,也就是要填充内部
  199. void CQEllipseObj::DisplayPolygon(CQCoordSys * pSys,CDC * pDC,int nDrawMode,int nSpecialMode,COLORREF * pColor)
  200. {
  201. CRect rectClient;
  202. pSys->GetWndport(rectClient.left,rectClient.top,rectClient.right,rectClient.bottom);
  203. CBoundaryRect bEllipseRect,bWndRect;
  204. CalculateBoundary(&bEllipseRect);
  205. pSys->LPtoWP(rectClient,&bWndRect);
  206. if(!bEllipseRect.IsCross(&bWndRect)) return;
  207. int nPtCount = m_PtList.GetSize();
  208. CPoint * pPoint = NULL;
  209. //保证能分配到空间
  210. while (pPoint == NULL)
  211. {
  212. pPoint = new CPoint[nPtCount];
  213. }
  214. for(int i=0;i<nPtCount;i++)
  215. {
  216. pSys->WPtoLP(*m_PtList.GetPoint(i),pPoint+i);
  217. }
  218. //获取线型
  219. long lPenStype = m_nLineType;
  220. //限制不能用特殊线型绘制
  221. if(lPenStype>5)
  222. lPenStype = 0;
  223. COLORREF crPen,crBrush;
  224. if(nSpecialMode == 1) //假如是选中
  225. {
  226. crPen = RGB(255,0,0);  //红
  227. crBrush = RGB(0,255,0);//绿
  228. }
  229. else if(nSpecialMode == 2) // 指定颜色绘制
  230. {
  231. crPen = *pColor;
  232. crBrush = *pColor;
  233. }
  234. else
  235. {
  236. crPen = m_crPenColor;
  237. crBrush = m_crBrushColor;
  238. }
  239. CPen newPen(lPenStype,(int)m_fLineWidth,crPen);
  240. CPen * pOldPen = pDC->SelectObject(&newPen);
  241. CBrush newBrush(crBrush);
  242. CBrush * pOldBrush = pDC->SelectObject(&newBrush);
  243. pDC->SetMapMode(nDrawMode);
  244. pDC->Polygon(pPoint,nPtCount);  //逼近
  245. pDC->SelectObject(&pOldPen);
  246. pDC->SelectObject(&pOldBrush);
  247. if(pPoint) delete []pPoint;
  248. }
  249. void CQEllipseObj::DisplayPolyline(CQCoordSys * pSys,CDC * pDC,int nDrawMode,int nSpecialMode,COLORREF * pColor)
  250. {
  251. CRect rectClient;
  252. pSys->GetWndport(rectClient.left,rectClient.top,rectClient.right,rectClient.bottom);
  253. CBoundaryRect bEllipseRect,bWndRect;
  254. CalculateBoundary(&bEllipseRect);
  255. pSys->LPtoWP(rectClient,&bWndRect);
  256. if(!bEllipseRect.IsCross(&bWndRect)) return;
  257. int nPtCount = m_PtList.GetSize();
  258. CPoint * pPoint = NULL;
  259. //保证能分配到空间
  260. while (pPoint == NULL)
  261. {
  262. pPoint = new CPoint[nPtCount];
  263. }
  264. for(int i=0;i<nPtCount;i++)
  265. {
  266. pSys->WPtoLP(*m_PtList.GetPoint(i),pPoint+i);
  267. }
  268. //获取线型
  269. long lPenStype = m_nLineType;
  270. //限制不能用特殊线型绘制
  271. if(lPenStype>5)
  272. lPenStype = 0;
  273. COLORREF crPen,crBrush;
  274. if(nSpecialMode == 1) //假如是选中
  275. {
  276. crPen = RGB(255,0,0);  //红
  277. crBrush = RGB(0,255,0);//绿
  278. }
  279. else if(nSpecialMode == 2) // 指定颜色绘制
  280. {
  281. crPen = *pColor;
  282. crBrush = *pColor;
  283. }
  284. else
  285. {
  286. crPen = m_crPenColor;
  287. crBrush = m_crBrushColor;
  288. }
  289. CPen newPen(lPenStype,(int)m_fLineWidth,crPen);
  290. CPen * pOldPen = pDC->SelectObject(&newPen);
  291. pDC->SetMapMode(nDrawMode);
  292. pDC->Polyline(pPoint,nPtCount);  //逼近
  293. pDC->SelectObject(&pOldPen);
  294. if(pPoint) delete []pPoint;
  295. }
  296. void CQEllipseObj::Move(double dx,double dy)
  297. {
  298. double fx = m_ptCenter.GetX();
  299. double fy = m_ptCenter.GetY();
  300. fx += dx;
  301. fy += dy;
  302. m_ptCenter.SetPoint(fx,fy);
  303. RecalculatePtlist();
  304. }
  305. //GIS中的旋转变换就是乘一个旋转矩阵
  306. //cosa  sina 0
  307. //-sina cosa 0
  308. //  0    0   1
  309. void CQEllipseObj::Rotate(CQPoint & pt,double & fAngleDegree)
  310. {
  311. //对于圆这个东西 旋转中心就行了
  312. double dRedAng = CQGISAlgorithmLib::DegreeToRadian(fAngleDegree); //角度转换为弧度
  313. CQBaseObj::Rotate(&m_ptCenter,pt,fAngleDegree);
  314. m_fRotateAngleRad += dRedAng;
  315. m_fStartAngleRad += dRedAng;
  316. m_fEndAngleRad += dRedAng;
  317. RecalculatePtlist();
  318. }
  319. void CQEllipseObj::Mirror(int nMirrorType)
  320. {
  321. double fx,fy; //临时变量用于存放圆心坐标
  322. fx = m_ptCenter.GetX();
  323. fy = m_ptCenter.GetY();
  324. switch(nMirrorType)
  325. {
  326. case 2:  //原点镜像
  327. {
  328. m_ptCenter.SetPoint(-fx,-fy);
  329. m_fStartAngleRad += PI;
  330. m_fEndAngleRad += PI;
  331. m_fRotateAngleRad += PI;
  332. break;
  333. }
  334. case 1://X轴镜像
  335. {
  336. m_ptCenter.SetPoint(fx,-fy);
  337. m_fStartAngleRad = -m_fStartAngleRad;
  338. m_fEndAngleRad = -m_fEndAngleRad;
  339. m_fRotateAngleRad = -m_fRotateAngleRad;
  340. break;
  341. }
  342. case 0://Y轴镜像
  343. {
  344. m_ptCenter.SetPoint(-fx,fy);
  345. m_fStartAngleRad = (PI - m_fStartAngleRad);
  346. m_fEndAngleRad = (PI - m_fEndAngleRad);
  347. m_fRotateAngleRad = (PI - m_fRotateAngleRad);
  348. break;
  349. }
  350. default:
  351. {
  352. m_ptCenter.SetPoint(-fx,fy);
  353. m_fStartAngleRad = (PI - m_fStartAngleRad);
  354. m_fEndAngleRad = (PI - m_fEndAngleRad);
  355. m_fRotateAngleRad = (PI - m_fRotateAngleRad);
  356. break;
  357. }
  358. }
  359. }
  360. //计算椭圆的边界矩形
  361. void CQEllipseObj::CalculateBoundary(CBoundaryRect * pRect /* = 0 */)//计算椭圆对象的边界矩形
  362. {
  363. double dx = m_ptCenter.GetX();
  364. double dy = m_ptCenter.GetY();
  365. double fMinX,fMinY,fMaxX,fMaxY;
  366. int nPtCount = m_PtList.GetSize();
  367. if(nPtCount <= 0)
  368. {
  369. fMinX = 0;
  370. fMinY = 0;
  371. fMaxX = 0;
  372. fMaxY = 0;
  373. }
  374. else
  375. {
  376. fMinX = m_PtList.GetPoint(0)->GetX();
  377. fMinY = m_PtList.GetPoint(0)->GetY();
  378. fMaxX = m_PtList.GetPoint(0)->GetX();
  379. fMaxY = m_PtList.GetPoint(0)->GetY();
  380. for(int i=1;i<nPtCount;i++)
  381. {
  382. fMinX = min(fMinX,m_PtList.GetPoint(i)->GetX());
  383. fMinY = min(fMinY,m_PtList.GetPoint(i)->GetY());
  384. fMaxX = max(fMaxX,m_PtList.GetPoint(i)->GetX());
  385. fMaxY = max(fMaxY,m_PtList.GetPoint(i)->GetY());
  386. }
  387. }
  388. m_Boundary.m_fMinX = fMinX;
  389. m_Boundary.m_fMinY = fMinY;
  390. m_Boundary.m_fMaxX = fMaxX;
  391. m_Boundary.m_fMaxY = fMaxY;
  392. if(pRect)
  393. {
  394. pRect->m_fMinX = fMinX;
  395. pRect->m_fMinY = fMinY;
  396. pRect->m_fMaxX = fMaxX;
  397. pRect->m_fMaxY = fMaxY;
  398. }
  399. }
  400. void CQEllipseObj::GetBoundingRect(CBoundaryRect * pRect)
  401. {
  402. if(!pRect)
  403. {
  404. pRect = NULL;
  405. return;
  406. }
  407. CalculateBoundary(pRect);
  408. }
  409. //框选择
  410. BOOL CQEllipseObj::Select(CQCoordSys * pSys,CBoundaryRect & rect)
  411. {
  412. CBoundaryRect bRect;
  413. CalculateBoundary(&bRect);  //得到当前椭圆对象的边界
  414. if(!bRect.IsCross(&rect)) return FALSE;  
  415. int nPtCount = m_PtList.GetSize();
  416. int nResult = 0;
  417. int i = 0;
  418. CQPoint ptLB,ptLT,ptRB,ptRT;
  419. //构造四个点
  420. ptLT.SetPoint(rect.m_fMinX,rect.m_fMaxY);
  421. ptLB.SetPoint(rect.m_fMinX,rect.m_fMinY);
  422. ptRB.SetPoint(rect.m_fMaxX,rect.m_fMinY);
  423. ptRT.SetPoint(rect.m_fMaxX,rect.m_fMaxY);
  424. for(;i<nPtCount-1;i++)
  425. {
  426. CQPoint * pt1 = NULL;
  427. pt1 = m_PtList.GetPoint(i);
  428. CQPoint * pt2 = NULL;
  429. pt2 = m_PtList.GetPoint(i+1);
  430. if(!pt1 || !pt2)continue;
  431. if(rect.PtInRect(*pt1)) return TRUE;  //假如有点在矩形对象里
  432. if(CQGISAlgorithmLib::IsLineCross(*pt1,*pt2,ptLB,ptLT) == TRUE)
  433. return TRUE;
  434. if(CQGISAlgorithmLib::IsLineCross(*pt1,*pt2,ptLT,ptRT) == TRUE)
  435. return TRUE;
  436. if(CQGISAlgorithmLib::IsLineCross(*pt1,*pt2,ptRT,ptRB) == TRUE)
  437. return TRUE;
  438. if(CQGISAlgorithmLib::IsLineCross(*pt1,*pt2,ptRB,ptLB) == TRUE)
  439. return TRUE;
  440. }
  441. return FALSE;
  442. }
  443. //点选
  444. BOOL CQEllipseObj::Select(CQCoordSys * pSys,CQPoint & pt,double fEffectiveDistance)
  445. {
  446. if(!pSys)return FALSE; //没有坐标系统对象 无法实现
  447. CBoundaryRect bRect;
  448. CalculateBoundary(&bRect);  //得到当前椭圆对象的边界
  449. if(bRect.PtInRect(pt) == FALSE)return FALSE;
  450. int nPtCount = m_PtList.GetSize();
  451. for(int i=0;i<nPtCount-1;i++)
  452. {
  453. CQPoint * pt1 = m_PtList.GetPoint(i);
  454. CQPoint * pt2 = m_PtList.GetPoint(i+1);
  455. double fDistance = CQPoint::Distance(pt,*pt1,*pt2);
  456. if(fDistance<=fEffectiveDistance)return TRUE;
  457. }
  458. return FALSE;
  459. }
  460. //串行化
  461. void CQEllipseObj::Serialize(CArchive& ar)
  462. {
  463. CQBaseObj::Serialize(ar); 
  464. //调用基类的构造函数 串行化基类部分
  465. if (ar.IsStoring()) //写入硬盘
  466. {
  467. //写入椭圆的重点坐标
  468. m_ptCenter.Serialize(ar);
  469. float fLongAxis = static_cast<float>(m_fLongAxis);
  470. ar.Write(&fLongAxis,sizeof(float));
  471. float fShortAxis = static_cast<float>(m_fShortAxis);
  472. ar.Write(&fShortAxis,sizeof(float));
  473. float fStartAngle = static_cast<float>(m_fStartAngleRad);
  474. ar.Write(&fStartAngle,sizeof(float));
  475. float fEndAngle = static_cast<float>(m_fEndAngleRad);
  476. ar.Write(&fEndAngle,sizeof(float));
  477. float fRotateAngle = static_cast<float>(m_fRotateAngleRad);
  478. ar.Write(&fRotateAngle,sizeof(float));
  479. //m_PtList.Serialize(ar); 先 不写
  480. }
  481. else  // 由磁盘读入
  482. {
  483. m_ptCenter.Serialize(ar);
  484. float fTemp = 0.0f;
  485. ar.Read(&fTemp,sizeof(float));
  486. m_fLongAxis = fTemp;
  487. ar.Read(&fTemp,sizeof(float));
  488. m_fShortAxis = fTemp;
  489. ar.Read(&fTemp,sizeof(float));
  490. m_fStartAngleRad = fTemp;
  491. ar.Read(&fTemp,sizeof(float));
  492. m_fEndAngleRad = fTemp;
  493. ar.Read(&fTemp,sizeof(float));
  494. m_fRotateAngleRad = fTemp;
  495. RecalculatePtlist();  //就是 不用写
  496. }
  497. }
  498. void CQEllipseObj::XFlex(double dcp_x,double dFlex)
  499. {
  500. int nPtNum = m_PtList.GetSize();
  501. for(int i=0;i<nPtNum;i++)
  502. {
  503. double dx = m_PtList.GetPoint(i)->GetX();
  504. dx = (dx-dcp_x)*dFlex;
  505. m_PtList.GetPoint(i)->SetX(dx);
  506. }
  507. }
  508. void CQEllipseObj::YFlex(double dcp_y,double dFlex)
  509. {
  510. int nPtNum = m_PtList.GetSize();
  511. for(int i=0;i<nPtNum;i++)
  512. {
  513. double dy = m_PtList.GetPoint(i)->GetY();
  514. dy = (dy-dcp_y)*dFlex;
  515. m_PtList.GetPoint(i)->SetX(dy);
  516. }
  517. }
  518. // 按标准椭圆方程:长半轴a,短半轴b。
  519. // 设 λ=(a-b)/(a+b),
  520. // 椭圆周长L:
  521. // L=π(a+b)(1 + λ^2/4 + λ^4/64 + λ^6/256 + 25λ^8/16384 + ......)
  522. double CQEllipseObj::GetPerimeter() //获取线条的周长,获取的是封闭的椭圆的周长
  523. {
  524. double lam = (m_fLongAxis-m_fShortAxis) / (m_fLongAxis+m_fShortAxis);
  525. double d = PI * (m_fLongAxis+m_fShortAxis) * 
  526. ( 1 + lam*lam/4.0 + pow(lam,4)/64.0 + pow(lam,6)/256.0 + 25*pow(lam,8)/16384.0 );
  527. return d;
  528. }
  529. // 返  回:椭圆的面积
  530. double CQEllipseObj::GetArcLength() //获取线条的长度
  531. {
  532. double fEndAngle = m_fEndAngleRad;
  533. if(fEndAngle<m_fStartAngleRad) fEndAngle += 2*PI;
  534. double dx = (fEndAngle - m_fStartAngleRad)/2*PI;
  535. if(dx > 1.0)dx = 1.0;
  536. return dx*GetPerimeter();
  537. }
  538. //PI * a * b
  539. double CQEllipseObj::GetArea() //获取面积,获取的是封闭的椭圆的面积
  540. {
  541. return PI*m_fLongAxis*m_fShortAxis;
  542. }
  543. //返回点阵的指针
  544. CQPointArray * CQEllipseObj::GetPointList()
  545. {
  546. return & m_PtList;
  547. }
  548. //存入文件 
  549. void CQEllipseObj::WriteToFile(CFile * pf)
  550. {
  551. if(pf == NULL)return;
  552. int nPtCount = m_PtList.GetSize();
  553. return;
  554. CQBaseObj::WriteToFile(pf);
  555. float fLongAxis = static_cast<float>(m_fLongAxis);
  556. pf->Write(&fLongAxis,sizeof(float));
  557. float fShortAxis = static_cast<float>(m_fShortAxis);
  558. pf->Write(&fLongAxis,sizeof(float));
  559. float fStartAngle = static_cast<float>(m_fStartAngleRad);
  560. pf->Write(&fStartAngle,sizeof(float));
  561. float fEndAngle = static_cast<float>(m_fEndAngleRad);
  562. pf->Write(&fEndAngle,sizeof(float));
  563. float fRotateAngle = static_cast<float>(m_fRotateAngleRad);
  564. pf->Write(&fRotateAngle,sizeof(float));
  565. }
  566. void CQEllipseObj::ReadFromFile(CFile * pf)
  567. {
  568. if(pf == NULL)
  569. pf = new CFile;
  570. CQBaseObj::ReadFromFile(pf);
  571. float fTemp = 0.0f;
  572. pf->Read(&fTemp,sizeof(float));
  573. m_fLongAxis = fTemp;
  574. pf->Read(&fTemp,sizeof(float));
  575. m_fShortAxis = fTemp;
  576. pf->Read(&fTemp,sizeof(float));
  577. m_fStartAngleRad = fTemp;
  578. pf->Read(&fTemp,sizeof(float));
  579. m_fEndAngleRad = fTemp;
  580. pf->Read(&fTemp,sizeof(float));
  581. m_fRotateAngleRad = fTemp;
  582. RecalculatePtlist();
  583. }
  584. CString CQEllipseObj::VarToStr() //将对象的成员信息转换成字符串信息
  585. {
  586. CString szFormBase;
  587. szFormBase.Empty();
  588. szFormBase = CQBaseObj::VarToStr();
  589. CString szEllipse,sztemp;
  590. szEllipse.Format("中心点X坐标:%f,中心点Y坐标:%f,椭圆长轴:%f,椭圆短轴:%f,起始角度:%f,终止角度:%f,旋转角度:%f",m_fLongAxis,m_fShortAxis,m_fStartAngleRad,m_fRotateAngleRad,m_fRotateAngleRad);
  591. szFormBase += szEllipse;
  592. return szFormBase;
  593. }
  594. inline void CQEllipseObj::GetCenterPoint(double &x, double &y) //获取椭圆中心点
  595. {
  596. x = m_ptCenter.GetX();
  597. y = m_ptCenter.GetY();
  598. }
  599. inline void CQEllipseObj::GetCenterPoint(CQPoint &pt) //获取椭圆中心点
  600. {
  601. pt.SetPoint(m_ptCenter.GetX(),m_ptCenter.GetY());
  602. }
  603. void CQEllipseObj::SetCenterPoint(double x, double y) //设置椭圆中心点
  604. {
  605. m_ptCenter.SetPoint(x,y);
  606. }
  607. void CQEllipseObj::SetCenterPoint(CQPoint pt) //设置椭圆中心点
  608. {
  609. m_ptCenter.SetPoint(pt.GetX(),pt.GetY());
  610. }
  611. //设定椭圆的参数,五个参数一起设置,这样只需计算一次点阵
  612. void CQEllipseObj::SetEllipseParams(double dCenterX,double dCenterY,double dMajorAxis,
  613. double dMinorAxis,double dStartAngleRad,double dEndAngleRad,double dRotateAngleRad)
  614. {
  615. m_ptCenter.SetPoint(dCenterX,dCenterY);
  616. m_fLongAxis = dMajorAxis;
  617. m_fShortAxis = dMinorAxis;
  618. m_fStartAngleRad = dStartAngleRad;
  619. m_fEndAngleRad = dEndAngleRad;
  620. m_fRotateAngleRad = dRotateAngleRad;
  621. RecalculatePtlist();
  622. }