Line1.cpp
上传用户:ckg1000
上传日期:2013-01-26
资源大小:630k
文件大小:11k
源码类别:

CAD

开发平台:

Visual C++

  1. // Line1.cpp: implementation of the CLine class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CAD2006.h"
  6. #include "Line1.h"
  7. #include "math.h"
  8. #include "Trigon.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. extern enum STATE;
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. CLine::CLine()
  19. {
  20. m_toolState = noClick;
  21. blnlinetemp = true;
  22. }
  23. CLine::~CLine()
  24. {
  25. }
  26. void CLine::Draw(CDC *pDC)
  27. {
  28. HPEN hPen = ::CreatePen(m_borderStyle,
  29. m_borderWidth,m_borderColor^pDC->GetBkColor());
  30. //将创建的HPEN选入DeviceContext,并把默认HPEN保存到hOldPen
  31. HPEN hOldPen = (HPEN)pDC->SelectObject(hPen);
  32. //设置混合模式
  33. int oldR2 = pDC->SetROP2(R2_XORPEN);
  34. //以前背景异或方式两次绘制直线
  35. pDC->MoveTo(m_ptBeginPos.x, m_ptBeginPos.y);
  36. pDC->LineTo(m_ptOldPos.x, m_ptOldPos.y);
  37. pDC->MoveTo(m_ptBeginPos.x, m_ptBeginPos.y);
  38. pDC->LineTo(m_ptEndPos.x, m_ptEndPos.y);
  39. //恢复默认异或方式
  40. pDC->SetROP2(oldR2);
  41. //将默认HPEN返还到DeviceContext
  42. pDC->SelectObject(hOldPen);
  43. //删除创建的HPEN
  44. ::DeleteObject(hPen);
  45. }
  46. void CLine::OnLbuttondown(CDC *pDC,CPoint point)
  47. {
  48. POINT currentPos; //当前鼠标坐标
  49. currentPos.x = point.x;
  50. currentPos.y = point.y;
  51. switch(m_toolState)
  52. {
  53. case noClick: //工具状态为noClick时
  54. {
  55. //确定(一次画线行为) 的起始点坐标 m_ptBeginPos
  56. m_ptBeginPos = m_ptOldPos = point;
  57. //状态转换为clicked
  58. m_toolState = Clicked;
  59. }
  60. break;
  61. case Clicked: //工具状态为Clicked时
  62. {
  63. //确定(一次画线行为) 的结束点坐标 m_ptEndPos
  64. m_ptEndPos = point;
  65. //状态转换为noClick
  66. m_toolState = noClick;
  67. }
  68. break;
  69. }
  70. }
  71. //响应WM_MOUSEMOVE消息
  72. void CLine::Onmousemove(CDC *pDC,CPoint point)
  73. {
  74. POINT currentPos; //当前鼠标坐标
  75. currentPos.x = point.x;
  76. currentPos.y = point.y;
  77. m_ptEndPos = currentPos;
  78. if(m_toolState == Clicked)
  79. {
  80. Draw(pDC);
  81. m_ptOldPos = point;
  82. }
  83. }
  84. CPoint CLine::GetPosBegin()
  85. {
  86. if( blnlinetemp )
  87. {
  88. return m_ptBeginPos;
  89. }
  90. else
  91. {
  92. return m_FirstMirPt;
  93. }
  94. }
  95. CPoint CLine::GetPosEnd()
  96. {
  97. if( blnlinetemp )
  98. {
  99. return m_ptEndPos;
  100. }
  101. else
  102. {
  103. return m_SecondMirPt;
  104. }
  105. }
  106. bool CLine::pick(POINT pt)
  107. {
  108. int dblLength  = Distance(m_ptBeginPos,m_ptEndPos);
  109. int dblLength1 = Distance(m_ptBeginPos,pt);
  110. int dblLength2 = Distance(m_ptEndPos,pt);
  111. if(dblLength1 + dblLength2 - dblLength < 3)
  112. return true;
  113. else
  114. return false;
  115. }
  116. int CLine::Distance(POINT ptPos1, POINT ptPos2)
  117. {
  118. double dbD = sqrt( (ptPos1.x - ptPos2.x) * (ptPos1.x - ptPos2.x) + 
  119. (ptPos1.y - ptPos2.y) *(ptPos1.y - ptPos2.y) );
  120. return (int)dbD;
  121. }
  122. bool CLine::Select(CDC *pDC,CPoint point)
  123. {
  124. if( pick(point) )
  125. {
  126. HDC hdc = pDC->GetSafeHdc();
  127. SelectObject(hdc,GetStockObject(WHITE_BRUSH));
  128. DrawRect(pDC);
  129. m_ptOldPos = point;
  130. // KILLRECT = true;
  131. return true;
  132. }
  133. return false;
  134. }
  135. void CLine::DrawRect(CDC *pDC)
  136. {
  137. HDC hdc = pDC->GetSafeHdc();
  138. HPEN hpen;
  139. int i = ::SetROP2(hdc,R2_XORPEN);
  140. hpen = ::CreatePen(0,0,RGB(255,0,0)^::GetBkColor(hdc));
  141. HPEN holdpen =(HPEN) ::SelectObject(hdc,hpen);
  142. ::SelectObject(hdc,GetStockObject(NULL_BRUSH));
  143. Ellipse(hdc,m_ptBeginPos.x - 4,m_ptBeginPos.y - 4,
  144. m_ptBeginPos.x + 4,m_ptBeginPos.y + 4);
  145. Ellipse(hdc,m_ptEndPos.x - 4,m_ptEndPos.y - 4,
  146. m_ptEndPos.x + 4,m_ptEndPos.y + 4);
  147. ::SetROP2(hdc,i);
  148. ::SelectObject(hdc,holdpen);
  149. ::DeleteObject(hpen);
  150. }
  151. void CLine::SetPosBegin(CPoint point)
  152. {
  153. m_ptBeginPos = point;
  154. }
  155. void CLine::SetPosEnd(CPoint point)
  156. {
  157. m_ptEndPos = point;
  158. }
  159. void CLine::Move(CDC *pDoc, CPoint point)
  160. {
  161. HDC hdc = pDoc->GetSafeHdc();
  162. int nOldMode = ::SetROP2(hdc,R2_XORPEN);
  163. HPEN hPen    = ::CreatePen( m_borderStyle,
  164. m_borderWidth,m_borderColor^pDoc->GetBkColor());
  165. HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);
  166. //擦去前一次线段 
  167. ::MoveToEx(hdc,m_ptBeginPos.x,m_ptBeginPos.y,NULL);
  168. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  169. m_ptBeginPos.x  += point.x - m_ptOldPos.x;
  170. m_ptBeginPos.y  += point.y - m_ptOldPos.y;
  171. m_ptEndPos.x += point.x- m_ptOldPos.x;
  172. m_ptEndPos.y += point.y- m_ptOldPos.y;
  173. //画出这一次线段
  174. ::MoveToEx(hdc,m_ptBeginPos.x,m_ptBeginPos.y,NULL);
  175. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  176. m_ptOldPos = point;
  177. ::SetROP2(hdc,nOldMode);
  178. ::SelectObject(hdc,hOldPen);
  179. ::DeleteObject(hPen);
  180. if (KILLRECT == true)
  181. {
  182. pDoc->SelectObject(GetStockObject(WHITE_BRUSH));
  183. DrawRect(pDoc);
  184. KILLRECT = false;
  185. }
  186. }
  187. void CLine::Rotate(CDC *pDC, CPoint point)
  188. {
  189. CPoint centerpoint;
  190. centerpoint.x =m_ptBeginPos.x - ( m_ptBeginPos.x-m_ptEndPos.x ) / 2;
  191. centerpoint.y =m_ptBeginPos.y - ( m_ptBeginPos.y-m_ptEndPos.y ) / 2;
  192. HDC hdc = pDC->GetSafeHdc();
  193. int nOldMode = ::SetROP2(hdc,R2_XORPEN);
  194. HPEN hPen    = ::CreatePen( m_borderStyle,
  195. m_borderWidth,m_borderColor^pDC->GetBkColor());
  196. HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);
  197. CPoint oldfirstpoint = m_ptBeginPos;
  198. CPoint oldsecondpoiont = m_ptEndPos;
  199. //擦去前一次线段 
  200. ::MoveToEx(hdc,oldfirstpoint.x,oldfirstpoint.y,NULL);
  201. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  202. double Pi = 3.14159;
  203. double radian = Pi * m_angle/180;   //化成弧度
  204. m_ptBeginPos = CalRotatePt(centerpoint,m_ptBeginPos,radian);
  205. m_ptEndPos = CalRotatePt(centerpoint,m_ptEndPos,radian);
  206. //画出这一次线段
  207. ::MoveToEx(hdc,m_ptBeginPos.x,m_ptBeginPos.y,NULL);
  208. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  209. m_ptOldPos = point;
  210. ::SetROP2(hdc,nOldMode);
  211. ::SelectObject(hdc,hOldPen);
  212. ::DeleteObject(hPen);
  213. }
  214. void CLine::Zoom(CDC *pDoc, CPoint point)
  215. {
  216. HDC hdc = pDoc->GetSafeHdc();
  217. int nOldMode = ::SetROP2(hdc,R2_XORPEN);
  218. HPEN hPen    = ::CreatePen( m_borderStyle,
  219. m_borderWidth,m_borderColor^pDoc->GetBkColor());
  220. HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);
  221. CPoint oldfirstpoint = m_ptBeginPos;
  222. // CPoint oldsecondpoiont = m_ptEndPos;
  223. //擦去前一次线段 
  224. ::MoveToEx(hdc,oldfirstpoint.x,oldfirstpoint.y,NULL);
  225. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  226. m_ptBeginPos.x  += point.x - m_ptOldPos.x;
  227. m_ptBeginPos.y  += point.y - m_ptOldPos.y;
  228. // m_ptEndPos.x += point.x- m_ptOldPos.x;
  229. // m_ptEndPos.y += point.y- m_ptOldPos.y;
  230. //画出这一次线段
  231. ::MoveToEx(hdc,m_ptBeginPos.x,m_ptBeginPos.y,NULL);
  232. ::LineTo(hdc,m_ptEndPos.x,m_ptEndPos.y);
  233. m_ptOldPos = point;
  234. ::SetROP2(hdc,nOldMode);
  235. ::SelectObject(hdc,hOldPen);
  236. ::DeleteObject(hPen);
  237. }
  238. bool CLine::SelectOnePt(CDC *pDC, CPoint point)
  239. {
  240. if( point.x >= m_ptBeginPos.x && point.y >= m_ptBeginPos.y && point.x <= m_ptBeginPos.x + 2 && point.y <= m_ptBeginPos.y +2 )
  241. {
  242. m_ptOldPos = point;
  243. DrawRect(pDC);
  244. return true;
  245. }
  246. return false;
  247. }
  248. // 功    能: 计算点绕指定点旋转dbAngle个角度后的点
  249. // 输入参数: 定点:POINT ptCenter 待求点:POINT ptPos
  250. //           弧度 double dbAngle 
  251. // 返 回 值: 旋转到的位置 POINT ptDest;
  252. POINT CLine::CalRotatePt(POINT ptCenter,POINT ptPos,double dbAngle)
  253. {
  254. struct tagMatrix             //旋转矩阵
  255. {
  256. double r11, r12, r13;
  257. double r21, r22, r23;
  258. double r31, r32, r33;
  259. }matrix;
  260. matrix.r11 = (double)cos(dbAngle);
  261. matrix.r21 = (double)sin(dbAngle);
  262. matrix.r31 = 0.0;
  263. matrix.r12 = (double)(-sin(dbAngle));
  264. matrix.r22 = (double)cos(dbAngle);
  265. matrix.r32 = 0.0;
  266. matrix.r13 = (double)((1 - cos(dbAngle)) * ptCenter.x + ptCenter.y * sin(dbAngle));
  267. matrix.r23 = (double)((1 - cos(dbAngle)) * ptCenter.y - ptCenter.x * sin(dbAngle));
  268. matrix.r33 = 1.0;
  269. POINT ptDest;
  270. ptDest.x = (int)(matrix.r11 * ptPos.x + matrix.r12 * ptPos.y + matrix.r13);
  271. ptDest.y = (int)(matrix.r21 * ptPos.x + matrix.r22 * ptPos.y + matrix.r23);
  272. return ptDest;
  273. }
  274. void CLine::Mirror(CDC *pDoc, CPoint point)
  275. {
  276. POINT curPt;
  277. curPt = point;
  278. m_ptOldPos = m_MirEndPt;
  279. m_MirEndPt = curPt;
  280. int nOldMode = pDoc->SetROP2(R2_XORPEN);
  281. POINT FirstMirOldPt = m_FirstMirPt;   //镜像后的老点
  282. POINT SecondMirOldPt = m_SecondMirPt;
  283. m_FirstMirPt = GetMirPt(m_MirBegPt, m_MirEndPt, m_ptBeginPos);
  284. m_SecondMirPt = GetMirPt(m_MirBegPt, m_MirEndPt, m_ptEndPos);
  285. DrawMirLine(pDoc,m_MirBegPt,m_MirEndPt);  //镜像线
  286. HPEN hPen    = ::CreatePen( 0,1,RGB(0,0,0)^pDoc->GetBkColor());
  287. HPEN hOldPen = (HPEN)pDoc->SelectObject(hPen);
  288. pDoc->MoveTo(FirstMirOldPt.x,FirstMirOldPt.y);
  289. pDoc->LineTo(SecondMirOldPt.x,SecondMirOldPt.y);
  290. pDoc->MoveTo(m_FirstMirPt.x,m_FirstMirPt.y);
  291. pDoc->LineTo(m_SecondMirPt.x,m_SecondMirPt.y);
  292. m_oldPt = curPt;
  293. pDoc->SetROP2(nOldMode);
  294. pDoc->SelectObject(hOldPen);
  295. ::DeleteObject(hPen);
  296. blnlinetemp = false;
  297. }
  298. void CLine::DrawMirLine(CDC *pDC, POINT MirBegPt, POINT MirEndPt)
  299. {
  300. HPEN newPen = CreatePen(0,0,RGB(255,0,0)^pDC->GetBkColor());
  301. HPEN oldPen = (HPEN)pDC->SelectObject(newPen);
  302. int oldR2 = pDC->SetROP2(R2_XORPEN);
  303. pDC->MoveTo(MirBegPt.x,MirBegPt.y);
  304. pDC->LineTo(m_oldPt.x,m_oldPt.y);
  305. pDC->MoveTo(MirBegPt.x,MirBegPt.y);
  306. pDC->LineTo(MirEndPt.x,MirEndPt.y);
  307. pDC->SetROP2(oldR2);
  308. pDC->SelectObject(oldPen);
  309. ::DeleteObject(newPen);
  310. ::DeleteObject(oldPen);
  311. }
  312. void CLine::KillMirLine(CDC *pDC)
  313. {
  314. HPEN newPen = CreatePen(0,0,pDC->GetBkColor());  
  315. HPEN oldPen = (HPEN)pDC->SelectObject(newPen);
  316. pDC->MoveTo(m_MirBegPt.x,m_MirBegPt.y);
  317. pDC->LineTo(m_MirEndPt.x,m_MirEndPt.y);
  318. pDC->SelectObject(oldPen);
  319. DeleteObject(newPen);
  320. ::DeleteObject(oldPen);
  321. }
  322. POINT CLine::GetMirPt(const POINT &ptBegin, const POINT &ptEnd, POINT ptCur)
  323. {
  324. POINT ptNew;
  325. double length = Distance(ptBegin,ptEnd);
  326. if(length == 0)
  327. return ptNew=ptCur;
  328. double t1 = 2. * ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.y-ptBegin.y)/length);
  329. double t2 = ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.x-ptBegin.x)/length)
  330. - ((ptEnd.y-ptBegin.y)/length) * ((ptEnd.y-ptBegin.y)/length);
  331. ptNew.x =(int)(ptCur.x*t2 + ptCur.y*t1 + ptBegin.x*(-t2) - ptBegin.y*t1 + ptBegin.x);
  332. ptNew.y =(int)(ptCur.x*t1 + ptCur.y*(-t2) + ptBegin.y*t2 - ptBegin.x*t1 + ptBegin.y);
  333. return ptNew;
  334. }
  335. void CLine::OnMirLBtnDn(CDC *pDC, CPoint point)
  336. {
  337. POINT curPoint;   //左键点击的点
  338. curPoint.x = point.x ;
  339. curPoint.y = point.y ;
  340. m_MirBegPt = m_MirEndPt = m_oldPt = curPoint;
  341. }
  342. void CLine::Update(CDC *pDC)
  343. {
  344. KillMirLine(pDC);
  345. }
  346. void CLine::SetAngle(int m_angle)
  347. {
  348. ::m_angle = m_angle;
  349. }
  350. void CLine::Delete(CDC *pDC)   //删除
  351. {
  352. HDC hdc = pDC->GetSafeHdc();
  353. DrawRect(pDC);
  354. HPEN newPen = CreatePen(m_borderStyle,
  355. m_borderWidth,GetBkColor(hdc));
  356. // SelectObject(hdc,GetStockObject(NULL_BRUSH)); //空画刷
  357. ::SelectObject(hdc,newPen);
  358. pDC->MoveTo(m_ptBeginPos);
  359. pDC->LineTo(m_ptEndPos);
  360. ::DeleteObject(newPen);
  361. }