TTXView.cpp
上传用户:tengfei20
上传日期:2022-07-03
资源大小:11400k
文件大小:13k
源码类别:

界面编程

开发平台:

C/C++

  1. // TTXView.cpp : CTTXView 类的实现
  2. //
  3. #include "stdafx.h"
  4. #include "math.h"
  5. #include "TTX.h"
  6. #include "TTXDoc.h"
  7. #include "TTXView.h"
  8. #include "MyDialog1.h"
  9. #include "Mydialog2.h"
  10. #include "MyDialog3.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #endif
  14. #define LEFT 1
  15. #define RIGHT 2
  16. #define BOTTOM 4
  17. #define TOP 8
  18. // CTTXView
  19. IMPLEMENT_DYNCREATE(CTTXView, CView)
  20. BEGIN_MESSAGE_MAP(CTTXView, CView)
  21. // 标准打印命令
  22. ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
  23. ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
  24. ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
  25. ON_COMMAND(ID_DDN, &CTTXView::OnDdn)
  26. ON_COMMAND(ID_MID, &CTTXView::OnMid)
  27. ON_COMMAND(ID_Circle, &CTTXView::OnCircle)
  28. ON_COMMAND(ID_Ellipse, &CTTXView::OnEllipse)
  29. ON_COMMAND(ID_RED, &CTTXView::OnRed)
  30. ON_COMMAND(ID_GREEN, &CTTXView::OnGreen)
  31. ON_COMMAND(ID_yellow, &CTTXView::Onyellow)
  32. ON_COMMAND(ID_mcut, &CTTXView::Onmcut)
  33. ON_WM_LBUTTONDOWN()
  34. ON_WM_MOUSEMOVE()
  35. ON_UPDATE_COMMAND_UI(ID_mcut, &CTTXView::OnUpdatemcut)
  36. ON_COMMAND(ID_Curve, &CTTXView::OnCurve)
  37. END_MESSAGE_MAP()
  38. // CTTXView 构造/析构
  39. CTTXView::CTTXView()
  40. : d_x(0)
  41. , d_x1(0)
  42. , d_x2(0)
  43. , d_y1(0)
  44. , d_y2(0)
  45. , fill(0)
  46. , WT(0)
  47. , WB(0)
  48. , WR(0)
  49. , WL(0)
  50. , m_list(0)
  51. , m_p1(0)
  52. , m_p2(0)
  53. , m_cut(false)
  54. {
  55. // TODO: 在此处添加构造代码
  56. WL=100;WR=500;WB=100;WT=300;
  57.     m_p1.x=0; m_p1.y=0;
  58.     m_p2.x=0; m_p2.y=0;
  59.     m_list=0; //m_ist=0 表示起点,m_ist=1 表示终点
  60. }
  61. CTTXView::~CTTXView()
  62. {
  63. }
  64. BOOL CTTXView::PreCreateWindow(CREATESTRUCT& cs)
  65. {
  66. // TODO: 在此处通过修改
  67. //  CREATESTRUCT cs 来修改窗口类或样式
  68. return CView::PreCreateWindow(cs);
  69. }
  70. // CTTXView 绘制
  71. void CTTXView::OnDraw(CDC* /*pDC*/)
  72. {
  73. CTTXDoc* pDoc = GetDocument();
  74. ASSERT_VALID(pDoc);
  75. if (!pDoc)
  76. return;
  77. // TODO: 在此处为本机数据添加绘制代码
  78. }
  79. // CTTXView 打印
  80. BOOL CTTXView::OnPreparePrinting(CPrintInfo* pInfo)
  81. {
  82. // 默认准备
  83. return DoPreparePrinting(pInfo);
  84. }
  85. void CTTXView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  86. {
  87. // TODO: 添加额外的打印前进行的初始化过程
  88. }
  89. void CTTXView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  90. {
  91. // TODO: 添加打印后进行的清理过程
  92. }
  93. // CTTXView 诊断
  94. #ifdef _DEBUG
  95. void CTTXView::AssertValid() const
  96. {
  97. CView::AssertValid();
  98. }
  99. void CTTXView::Dump(CDumpContext& dc) const
  100. {
  101. CView::Dump(dc);
  102. }
  103. CTTXDoc* CTTXView::GetDocument() const // 非调试版本是内联的
  104. {
  105. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTTXDoc)));
  106. return (CTTXDoc*)m_pDocument;
  107. }
  108. #endif //_DEBUG
  109. // CTTXView 消息处理程序
  110. //DDN算法画直线
  111. void CTTXView::OnDdn()
  112. {
  113. // TODO: Add your command handler code here
  114. MyDialog1 dlg;
  115. CDC* pDC;
  116. pDC=GetWindowDC();
  117. if(dlg.DoModal()==IDOK) //显示对话框
  118. {
  119. d_x1=dlg.XX1;
  120. d_y1=dlg.YY1;
  121. d_x2=dlg.XX2;
  122. d_y2=dlg.YY2;
  123. }
  124. //从对话框获取相应的数据
  125.     float k;
  126. k=(float)(d_y2-d_y1)/(d_x2-d_x1);
  127. int x;
  128. float y=d_y1;
  129. for(x=d_x1;x<=d_x2;x++)
  130. {
  131. pDC->SetPixel(x,int(y+0.5),RGB(0,250,0));
  132. y=y+k;
  133. Sleep(20);
  134. }
  135. pDC->TextOut(d_x1+5,d_y1,_T("DDA 法"));
  136. m_cut=false;
  137. }
  138. void CTTXView::OnMid()
  139. {
  140. // TODO: Add your command handler code here
  141.    MyDialog1 dlg;
  142. CDC* pDC;
  143. pDC=GetWindowDC();
  144. if(dlg.DoModal()==IDOK)
  145. {
  146. d_x1=dlg.XX1;
  147. d_y1=dlg.YY1;
  148. d_x2=dlg.XX2;
  149. d_y2=dlg.YY2;
  150. }
  151. //从对话框获取相应的数据
  152. float a,b,c;
  153. a=float(d_y1-d_y2);
  154. b=float(d_x2-d_x1);
  155. float k;
  156. k=(float)(d_y2-d_y1)/(d_x2-d_x1);
  157. float d;
  158. d=(1/k)*a+b;
  159. float x,y;
  160.  y=float(d_y1);
  161. for(x=d_x1;x<=d_x2;x++)
  162. {
  163. pDC->SetPixel(x,y,RGB(255,0,255));
  164. if(d>=0)
  165. d=d+a;
  166. else
  167. {
  168. d=d+a+b;
  169. y=y+1;
  170. }
  171. Sleep(20);
  172. }
  173.  
  174. pDC->TextOut(d_x1+5,d_y1,_T("中点法"));
  175. m_cut=false;
  176.  
  177. }
  178. void CTTXView::OnCircle()
  179. {
  180. // TODO: Add your command handler code here
  181. RedrawWindow();
  182. Mydialog2 dlg;
  183. int r,a,b;
  184. if(dlg.DoModal()==IDOK)
  185. {
  186.  r=dlg.R;
  187.          a=dlg.X1;
  188.          b=dlg.Y1;
  189. }
  190.    int x=0,y=r; // 初始点(0,r) 
  191.    float d;     // d--半径
  192. d=1.25-r;
  193. CDC* pDC;
  194. pDC=GetWindowDC();
  195. //  画八对称点
  196. pDC->SetPixel(a+x,b+y,RGB(250,0,0));
  197. pDC->SetPixel(a+y,b+x,RGB(250,0,0));
  198. pDC->SetPixel(a-y,b+x,RGB(250,0,0));
  199. pDC->SetPixel(a-x,b+y,RGB(250,0,0));
  200. pDC->SetPixel(a+y,b-x,RGB(250,0,0));
  201. pDC->SetPixel(a+x,b-y,RGB(250,0,0));
  202. pDC->SetPixel(a-x,b-y,RGB(250,0,0));
  203. pDC->SetPixel(a-y,b-x,RGB(250,0,0));
  204. while(x<=y)
  205. {
  206. if(d<0)
  207. {
  208. d+=2*x+3;
  209. }
  210. else
  211. {
  212. d+=2*(x-y)+5;
  213. y--;
  214. }
  215.         x++;
  216. //  画八对称点
  217. pDC->SetPixel(a+x,b+y,RGB(250,0,0));
  218. pDC->SetPixel(a+y,b+x,RGB(250,0,0));
  219. pDC->SetPixel(a-y,b+x,RGB(250,0,0));
  220. pDC->SetPixel(a-x,b+y,RGB(250,0,0));
  221. pDC->SetPixel(a+y,b-x,RGB(250,0,0));
  222. pDC->SetPixel(a+x,b-y,RGB(250,0,0));
  223. pDC->SetPixel(a-x,b-y,RGB(250,0,0));
  224. pDC->SetPixel(a-y,b-x,RGB(250,0,0));
  225.  Sleep(10);
  226. }
  227.     
  228. m_cut=false;
  229. }
  230. void CTTXView::OnEllipse()
  231. {
  232. // TODO: Add your command handler code here
  233. RedrawWindow();
  234. CDC* pDC;
  235. pDC=GetWindowDC();
  236. MyDialog3 dlg;
  237. double d;
  238. int x,y;
  239. double ta2,tb2;
  240. double df1,df2;
  241. double a2,b2;
  242. int a,b;
  243. if(dlg.DoModal()==IDOK)
  244. {
  245. a=dlg.rrr;
  246. b=dlg.RRR;
  247. x=dlg.XXX;
  248. y=dlg.YYY;
  249. }
  250. x=0;y=b;
  251. a2=1.0*a*a;
  252. b2=1.0*b*b;
  253. ta2=a2*2;
  254. tb2=b2*2;
  255. d=b2+(0.25-b)*a2;
  256. df1=b2*3;
  257. df2=b2*3+ta2-ta2*b;
  258. while(b2*(x+1)<=a2*(y-0.5))
  259. {
  260. pDC->SetPixel(100+x,200+y,RGB(0,255,0));
  261. pDC->SetPixel(100-x,200+y,RGB(0,255,0));
  262. pDC->SetPixel(100+x,200-y,RGB(0,255,0));
  263. pDC->SetPixel(100-x,200-y,RGB(0,255,0));
  264. if(d<0)
  265. {
  266. d+=df1;
  267. x++;
  268. df1+=tb2;
  269. df2+=tb2;
  270. }
  271. else
  272. {
  273. d+=df2;
  274. x++;
  275. y--;
  276. df1+=tb2;
  277. df2+=tb2+ta2;
  278. }
  279. }
  280. df1=b2*(2*x+2)+a2*(3-2*y);
  281. df2=a2*(3-2*y);
  282. d=b2*(x+0.5)*(x+0.5)+a2*(y-1)*(y-1)-a2*b2;
  283. while(y>=0)
  284. {
  285. pDC->SetPixel(100+x,200+y,RGB(0,255,0));
  286. pDC->SetPixel(100-x,200+y,RGB(0,255,0));
  287. pDC->SetPixel(100+x,200-y,RGB(0,255,0));
  288. pDC->SetPixel(100-x,200-y,RGB(0,255,0));
  289. if(d<0)
  290. {
  291. d+=df1;
  292. x++;
  293. y--;
  294. df2+=ta2;
  295. df1+=ta2+tb2;
  296. }
  297. else
  298. {
  299. d+=df2;
  300. y--;
  301. df1+=ta2;
  302. df2+=ta2;
  303. }
  304. Sleep(1);
  305. }
  306. m_cut=false;
  307. }
  308. void CTTXView::OnRed()
  309. {
  310. // TODO: Add your command handler code here
  311. RedrawWindow();
  312. CPoint *poly;
  313. CDC* pDC;
  314. pDC=GetWindowDC();
  315. poly=new CPoint[5];
  316.     poly[0].x=110;
  317. poly[0].y = 110;        /* 第一个点的x坐标以及y坐标 */
  318. poly[1].x = 160;      /* 第二点 */
  319. poly[1].y = 105;
  320. poly[2].x = 200;      /* 第三点 */
  321. poly[2].y = 120;
  322. poly[3].x=150;        /*第四点*/
  323. poly[3].y=170;
  324. poly[4].x=110;       /*多边形的起点与终点一样*/
  325. poly[4].y=110;
  326. pDC->Polyline(poly,5);
  327. filling(pDC,150,110,RGB(250,0,0),RGB(0,0,0));  /*种子填充多边形*/
  328. m_cut=false;
  329. }
  330. void CTTXView::filling(CDC *pDc, int x,int y,COLORREF c_fill,COLORREF c_bound)
  331. {
  332. COLORREF c;
  333. c=pDc->GetPixel(CPoint(x,y)); /*获取当前点的颜色*/
  334. if((c!=c_bound)&&(c!=c_fill))  /*如果颜色为边界色则不填充*/
  335. {
  336.   Sleep(1);
  337. pDc->SetPixel(x, y, c_fill); /*画点*/
  338. filling(pDc,x+1,y, c_fill, c_bound);
  339. filling(pDc,x-1,y, c_fill, c_bound);
  340. filling(pDc,x, y+1, c_fill, c_bound);
  341. filling(pDc,x, y-1, c_fill, c_bound);
  342. }
  343. m_cut=false;
  344. }
  345. void CTTXView::OnGreen()
  346. {
  347. // TODO: Add your command handler code here
  348. RedrawWindow();
  349. CPoint *poly;
  350. CDC* pDC;
  351. pDC=GetWindowDC();
  352. poly=new CPoint[5];
  353.     poly[0].x=110;
  354. poly[0].y = 110;        /* 第一个点的x坐标以及y坐标 */
  355. poly[1].x = 160;      /* 第二点 */
  356. poly[1].y = 105;
  357. poly[2].x = 200;      /* 第三点 */
  358. poly[2].y = 120;
  359. poly[3].x=150;        /*第四点*/
  360. poly[3].y=170;
  361. //poly[4].x=110;       /*多边形的起点与终点一样*/
  362. //poly[4].y=110;
  363. pDC->Polyline(poly,5);
  364. filling(pDC,150,110,RGB(0,255,0),RGB(0,0,0));  /*种子填充多边形*/
  365. m_cut=false;
  366. }
  367. void CTTXView::Onyellow()
  368. {
  369. // TODO: Add your command handler code here
  370. RedrawWindow();
  371. CPoint *poly;
  372. CDC* pDC;
  373. pDC=GetWindowDC();
  374. poly=new CPoint[5];
  375.     poly[0].x=110;
  376. poly[0].y = 110;        /* 第一个点的x坐标以及y坐标 */
  377. poly[1].x = 160;      /* 第二点 */
  378. poly[1].y = 105;
  379. poly[2].x = 200;      /* 第三点 */
  380. poly[2].y = 120;
  381. poly[3].x=150;        /*第四点*/
  382. poly[3].y=170;
  383. poly[4].x=110;       /*多边形的起点与终点一样*/
  384. poly[4].y=110;
  385. pDC->Polyline(poly,5);
  386. filling(pDC,150,110,RGB(250,250,0),RGB(0,0,0));  /*种子填充多边形*/
  387. m_cut=false;
  388. }
  389. void CTTXView::encode(int x, int y, int *code)
  390. {
  391. int c=0;
  392. if (x<WL) c=c|LEFT;
  393. else if (x>WR) c=c|RIGHT;
  394. if (y<WB) c=c|BOTTOM;
  395. else if (y>WT) c=c|TOP;
  396. *code=c;
  397. }
  398. int CTTXView::Line(CDC* pDC,int x1, int y1, int x2, int y2)
  399. {
  400. // CDC *pDC=GetDC();
  401.     int code1,code2,code,x,y;
  402. encode(x1,y1,&code1); //(x1,y1)处的编码
  403. encode(x2,y2,&code2); //(x1,y1)处的编码
  404. while (code1!=0||code2!=0) //当 code1 不等于 0 或 code2 不等于 0
  405. {
  406. if ((code1&code2)!=0) return 0; //当 code1 与 code2 不等于 0,在同侧;
  407. code=code1;
  408. if (code1==0) code=code2;
  409. if ((LEFT&code)!=0) //求交点
  410. {
  411. x=WL;
  412. y=y1+(y2-y1)*(WL-x1)/(x2-x1);
  413. }
  414. else if ((RIGHT&code)!=0)
  415. {
  416. x=WR;
  417. y=y1+(y2-y1)*(WR-x1)/(x2-x1);
  418. }
  419. else if ((BOTTOM&code)!=0)
  420. {
  421. y=WB;
  422. x=x1+(x2-x1)*(WB-y1)/(y2-y1);
  423. }
  424. else if ((TOP&code)!=0)
  425. {
  426. y=WT;
  427. x=x1+(x2-x1)*(WT-y1)/(y2-y1);
  428. }
  429. if (code==code1)
  430. {
  431. x1=x;y1=y;
  432. encode(x,y,&code1);
  433. }
  434. else
  435. {
  436. x2=x;y2=y;
  437. encode(x,y,&code2);
  438. }
  439. }
  440. //end while,表示 code1,code2 都为 0,其中的线段为可视部分
  441. pDC->MoveTo(x1,y1);
  442. pDC->LineTo(x2,y2);
  443. }
  444. void CTTXView::Onmcut()
  445. {
  446. // TODO: Add your command handler code here
  447. CDC* pDC;
  448. pDC=GetWindowDC();
  449. CPen PenRed(PS_SOLID,1,RGB(255,0,0));//定义红色笔
  450.     pDC->Rectangle(WL,WB,WR,WT);
  451.    m_cut=true;
  452. }
  453. void CTTXView::OnLButtonDown(UINT nFlags, CPoint point)
  454. {
  455. // TODO: Add your message handler code here and/or call default
  456.     if(m_cut)
  457. {
  458. CDC *pDC=GetDC();
  459. pDC->SelectStockObject(NULL_BRUSH);
  460. if (!m_list) //是起点
  461. {
  462. m_p1=m_p2=point; //纪录第一次单击鼠标位置,定起点
  463. m_list++;
  464. }
  465. else
  466. {
  467. m_p2=point; //记录第二次单击鼠标的位置,定终点的点
  468. m_list--; //  为新绘图作准备
  469. pDC->MoveTo(m_p1.x,m_p1.y); //绘制新直线
  470. pDC->LineTo(m_p2.x,m_p2.y);
  471. }
  472. //用异或方式擦除直线
  473. int nDrawmode=pDC->SetROP2(R2_NOT);//设置异或绘图模式,并保存原来绘图模式
  474. pDC->MoveTo(m_p1.x,m_p1.y); //绘制新直线
  475. pDC->LineTo(m_p2.x,m_p2.y);
  476. pDC->SetROP2(nDrawmode); //恢复原绘图模式
  477. //用红色画出裁剪线段
  478. CPen PenRed(PS_SOLID,1,RGB(255,0,0));//定义红色笔
  479. pDC->SelectObject(&PenRed);
  480. Line(pDC,m_p1.x,m_p1.y,m_p2.x,m_p2.y);
  481. ReleaseDC(pDC); //释放设备环境
  482. }
  483. CView::OnLButtonDown(nFlags, point);
  484. }
  485. void CTTXView::OnMouseMove(UINT nFlags, CPoint point)
  486. {
  487. // TODO: Add your message handler code here and/or call default
  488. if(m_cut)
  489. {
  490. CDC *pDC=GetDC();
  491.     int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式
  492.     pDC->SelectStockObject(NULL_BRUSH);
  493.    if(m_list==1)
  494.    {
  495.        CPoint prePnt,curPnt;
  496.    prePnt=m_p2; //获得鼠标所在的前一位置
  497.       curPnt=point;
  498.       //绘制橡皮筋线
  499.       pDC->MoveTo(m_p1.x,m_p1.y);
  500.       pDC->LineTo(prePnt.x,prePnt.y);//用异或模式重复画直线,擦出所画的直线
  501.       pDC->MoveTo(m_p1.x,m_p1.y);
  502.       pDC->LineTo(curPnt.x,curPnt.y);//用当前位置,画直线
  503.       m_p2=point;
  504.    }
  505.   pDC->SetROP2(nDrawmode); //恢复原绘图模式
  506.   ReleaseDC(pDC); //释放设备环境
  507. }
  508.     
  509. CView::OnMouseMove(nFlags, point);
  510. }
  511. void CTTXView::OnUpdatemcut(CCmdUI *pCmdUI)
  512. {
  513. // TODO: Add your command update UI handler code here
  514. pCmdUI->SetCheck(m_cut);
  515. }
  516. void CTTXView::OnCurve()
  517. {
  518. // TODO: Add your command handler code here
  519. SquareBezier(70/2,210/2,140/2,140/2,280/2,280/2,280/2,420/2,50);
  520.     SquareBezier(70/2,210/2,120,280/2,140/2,420/2,280/2,420/2,50);
  521. //SquareBezier(140/2,420/2,0,560/2,280/2,840/2,560/2,840/2,100);
  522. }
  523. void CTTXView::SquareBezier(int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3,int m)
  524. {//三次Bezier曲线
  525. float C[2][4],t,dx,Newx,Newy;
  526. int Vx,Vy,Nx,Ny,i,j;
  527. C[0][0]=x0;
  528. C[0][1]=-3*x0+3*x1;
  529. C[0][2]=3*x0-6*x1+3*x2;
  530. C[0][3]=-1*x0+3*x1-3*x2+x3;
  531.      C[1][0]=y0;
  532. C[1][1]=-3*y0+3*y1;
  533. C[1][2]=3*y0-6*y1+3*y2;
  534. C[1][3]=-1*y0+3*y1-3*y2+y3;
  535. Vx=x0,Vy=y0;
  536. dx=1.0/m,t=0.0;
  537. for(i=1;i<=m;i++)
  538. {t+=dx;
  539.  Newx=C[0][0]+t*(C[0][1]+t*(C[0][2]+t*C[0][3]));
  540.  Newy=C[1][0]+t*(C[1][1]+t*(C[1][2]+t*C[1][3]));
  541.  Nx=(int)(Newx+0.5),Ny=(int)(Newy+0.5);
  542.  MidLine(Vx,Vy,Nx,Ny);  //调用中点法画直线
  543.  Vx=Nx,Vy=Ny;
  544. }
  545. m_cut=false;
  546. }
  547. void CTTXView::MidLine(int x0, int y0, int x1, int y1) //中点法画直线
  548. {
  549. int dx,dy,dxy,s1,s2,flag,i,d,x,y,color = 0;
  550. CDC* pDC = GetDC();
  551. x = x0;
  552. y = y0;
  553. dx = abs(x1 - x0);
  554. dy = abs(y1 - y0);
  555. s1 = (x1 - x0) > 0 ? 1:-1;
  556. s2 = (y1 - y0) > 0 ? 1:-1;
  557. if(dy > dx)
  558. {
  559. dxy = dx;dx = dy;dy = dxy;
  560. flag = 1;
  561. }
  562. else
  563. flag = 0;
  564. d = 2*dy - dx;
  565. for(i = 1;i <= dx;i++)
  566. {
  567. pDC->SetPixel(x,y,color);
  568. pDC->SetPixel(350-y,x+70,color);
  569. pDC->SetPixel(-x+280,420-y,color);
  570. pDC->SetPixel(y-70,-x+350,color);
  571.         while(d >= 0)
  572.             {
  573.                 if(flag == 1)
  574.                     x += s1;
  575.                 else
  576.                     y += s2;
  577.                 d += -2*dx;
  578. }
  579.             if(flag == 1)
  580. y += s2;
  581. else
  582. x += s1;
  583. d += 2*dy;
  584. }
  585. }