drawmethod.cpp
上传用户:fjzzwyy
上传日期:2007-01-14
资源大小:244k
文件大小:14k
源码类别:

绘图程序

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "DrawMethod.h"
  3. CDC * MyDC;
  4. COLORREF Mycol;
  5. int round(float ff)
  6. {
  7. int k;
  8. if((ff-(int)ff)>0.5) k=(int)ff+1;
  9. else k=(int)ff;
  10. return k;
  11. }
  12. int sign(int num)
  13. {
  14. if (num==0) return 0;
  15. return num>0?1:-1;
  16. }
  17. int getmax(int point[],int n)
  18. {
  19. int max=point[0];
  20. for(int i=1;i<=n-1;i++)
  21. {
  22. if(max<point[i]) max=point[i];
  23. }
  24. return max;
  25. }
  26. //取顶点坐标的最小值 
  27. int getmin(int point[],int n)
  28. {
  29. int min=point[0];
  30. for(int j=1;j<=n-1;j++)
  31. {
  32. if(min>point[j]) min=point[j];
  33. }
  34. return min;
  35. }
  36. void DrawMyLine(CDC* pDC,CPoint A,CPoint B,COLORREF Color)
  37. {
  38. int dx,dy;
  39. int px,py;
  40. int cx=0,cy=0;
  41. dx=abs(A.x-B.x)+1;
  42. dy=abs(A.y-B.y)+1;
  43. pDC->SetPixelV(A,Color);
  44. pDC->SetPixelV(B,Color);
  45. px=A.x;py=A.y;
  46. int count=dx+dy-3;
  47. if (A.x<B.x){
  48. if (A.y<B.y) {
  49. cx+=dy;cy+=dx;
  50. for (int i=0;i<count;i++){
  51. if (cx<cy) {px+=1;cx+=dy;} else {py+=1;cy+=dx;}
  52. pDC->SetPixelV(px,py,Color);
  53. }
  54. }else{
  55. cx+=dy;cy+=dx;
  56. for (int i=0;i<count;i++){
  57. if (cx<cy) {px+=1;cx+=dy;} else {py-=1;cy+=dx;}
  58. pDC->SetPixelV(px,py,Color);
  59. }
  60. }
  61. }else{
  62. if (A.y<B.y) {
  63. cx+=dy;cy+=dx;
  64. for (int i=0;i<count;i++){
  65. if (cx<cy) {px-=1;cx+=dy;} else {py+=1;cy+=dx;}
  66. pDC->SetPixelV(px,py,Color);
  67. }
  68. }else{
  69. cx+=dy;cy+=dx;
  70. for (int i=0;i<count;i++){
  71. if (cx<cy) {px-=1;cx+=dy;} else {py-=1;cy+=dx;}
  72. pDC->SetPixelV(px,py,Color);
  73. }
  74. }
  75. }
  76. }
  77. bool DrawLine_BPB(CDC * pDC,int x1,int y1,int x2,int y2,COLORREF Color)
  78. {
  79. if((x1==x2)&&(y1==y2)) {
  80. pDC->SetPixelV(x1,y1,Color);
  81. return true;
  82. }
  83. ///////直线竖直/////////////////
  84. if(x1== x2){
  85. int maxy=y1>y2?y1:y2;
  86. int miny=y1<y2?y1:y2;
  87. for(int i=miny; i<=maxy;i++)
  88.     pDC->SetPixelV(x1,i,Color);
  89.         return true;
  90. }
  91. ///////直线水平////////////////
  92. if(y1==y2){
  93. int maxx=x1>x2?x1:x2;
  94. int minx=x1<x2?x1:x2;
  95. for(int i=minx; i<=maxx;i++)
  96.     pDC->SetPixelV(i,y1,Color);
  97.         return true;
  98. }
  99. int x,y;
  100. int dx,dy,c,f;
  101. dx=abs(x2-x1);
  102. dy=abs(y1-y2);
  103. ///////c为计步长///////////////////
  104. if(dx>=dy) c=dx;else c=dy;
  105. x=x1;y=y1;f=0;
  106. while(c>=0)
  107. {
  108. pDC->SetPixelV(x,y,Color);
  109. if(f>=0){ 
  110. if(x2>x1) x++;else x--;
  111. f-=dy;
  112. if(dx>dy) c--;
  113. }
  114. else{
  115. if(y2<y1) y--;else y++;
  116. f+=dx;
  117. if(dx<=dy) c--;
  118. }
  119. }
  120. pDC->SetPixelV(x,y,Color);
  121.     return true;
  122. }
  123. void DrawLine_DDA(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
  124. {
  125. float ddx,ddy,x,y;
  126. int dx,dy,i,j;
  127. int b=1,c=0,d=1;
  128. float a=1.0;
  129. float n=1.0;
  130. dx=xb-xa;dy=yb-ya;
  131. if(dx<0) b=-1;        //b判定x的走向
  132. if(dy<0) d=-1;        //d判定y的走向
  133. dx=abs(dx);dy=abs(dy);
  134. if(dx>dy) c=dx;else c=dy;
  135. ddx=(float)dx/c;ddy=(float)dy/c;
  136. x=(float)xa;y=(float)ya;
  137. while(c>=0){
  138. i=round(x);j=round(y);
  139. pDC->SetPixelV(i,j,Color);
  140. x=x+b*ddx;y=y+d*ddy;c--;
  141. }
  142. }
  143. void DrawLine_Thick(CDC* pDC,int xa,int ya,int xb,int yb,int width,COLORREF Color)
  144. {
  145. int q,i,x,y,k,dx,dy,s1,s2,temp,interchange,e;
  146. q=width/2;
  147. x=xa;y=ya;
  148. dx=abs(xb-xa);
  149. dy=abs(yb-ya);
  150. s1=sign(xb-xa);
  151. s2=sign(yb-ya);
  152. if ((s1==0)&&(s2==0)) return;
  153. if (dy>dx) {
  154. temp=dx;
  155. dx=dy;
  156. dy=temp;
  157. interchange=1;
  158. }else {
  159. interchange=0;
  160. }
  161. e=2*dy-dx;
  162. for (i=0;i<=dx;i++){
  163. if (interchange)
  164. for (k=-q;k<=q;k++)
  165.   pDC->SetPixelV(x+k,y,Color);
  166. else
  167. for (k=-q;k<=q;k++)
  168.   pDC->SetPixelV(x,y+k,Color);
  169. while (e>=0){
  170. if (interchange==1) x+=s1;else y+=s2;
  171. e-=dx+dx;
  172. }
  173. if (interchange==1) y+=s2; else x+=s1;
  174. e+=2*dy;
  175. }
  176. }
  177. void DrawLine_BresenHam(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
  178. {
  179. int i,x,y,dx,dy,s1,s2,temp,interchange,e;
  180. x=xa;y=ya;
  181. dx=abs(xb-xa);
  182. dy=abs(yb-ya);
  183. s1=sign(xb-xa);
  184. s2=sign(yb-ya);
  185. if ((s1==0)&&(s2==0)) return;
  186. if (dy>dx) {
  187. temp=dx;
  188. dx=dy;
  189. dy=temp;
  190. interchange=1;
  191. }else {
  192. interchange=0;
  193. }
  194. e=2*dy-dx;
  195. for (i=0;i<=dx;i++){
  196. pDC->SetPixelV(x,y,Color);
  197. while (e>=0){
  198. if (interchange==1) x+=s1;else y+=s2;
  199. e-=dx+dx;
  200. }
  201. if (interchange==1) y+=s2; else x+=s1;
  202. e+=2*dy;
  203. }
  204. }
  205. void DrawLine_BresenHam_Broken(CDC *pDC,int xa,int ya,int xb,int yb,COLORREF Color)
  206. {
  207. int i,x,y,dx,dy,s1,s2,temp,interchange,e,count,draw;
  208. x=xa;y=ya;count=0;draw=1;
  209. dx=abs(xb-xa);
  210. dy=abs(yb-ya);
  211. s1=sign(xb-xa);
  212. s2=sign(yb-ya);
  213. if ((s1==0)&&(s2==0)) return;
  214. if (dy>dx) {
  215. temp=dx;
  216. dx=dy;
  217. dy=temp;
  218. interchange=1;
  219. }else {
  220. interchange=0;
  221. }
  222. e=2*dy-dx;
  223. for (i=0;i<=dx;i++){
  224. count++;
  225. if (draw) pDC->SetPixelV(x,y,Color);
  226. if (count>5) {draw=1-draw;count=0;}
  227. while (e>=0){
  228. if (interchange==1) x+=s1;else y+=s2;
  229. e-=dx+dx;
  230. }
  231. if (interchange==1) y+=s2; else x+=s1;
  232. e+=2*dy;
  233. }
  234. }
  235. void SeedFill(CDC *pDC,CPoint seed,COLORREF Color)
  236. {
  237. struct NodeType{
  238. int x;
  239. int y;
  240.     NodeType *next;
  241. };
  242. NodeType *Node,*Tail,*temp;
  243. COLORREF seedcolor=pDC->GetPixel(seed);
  244. if (seedcolor==Color) return;
  245. pDC->SetPixelV(seed,Color);
  246. Node=new NodeType;
  247. Tail=Node;
  248. Node->x=seed.x;
  249. Node->y=seed.y;
  250. Node->next=NULL;
  251. while (Node){
  252. if (pDC->GetPixel(Node->x+1,Node->y)==seedcolor){
  253. temp=new NodeType;
  254. temp->x=Node->x+1;
  255. temp->y=Node->y;
  256. Tail->next=temp;
  257. temp->next=NULL;
  258. Tail=temp;
  259. pDC->SetPixelV(temp->x,temp->y,Color);
  260. }
  261. if (pDC->GetPixel(Node->x-1,Node->y)==seedcolor){
  262. temp=new NodeType;
  263. temp->x=Node->x-1;
  264. temp->y=Node->y;
  265. Tail->next=temp;
  266. temp->next=NULL;
  267. Tail=temp;
  268. pDC->SetPixelV(temp->x,temp->y,Color);
  269. }
  270. if (pDC->GetPixel(Node->x,Node->y+1)==seedcolor){
  271. temp=new NodeType;
  272. temp->x=Node->x;
  273. temp->y=Node->y+1;
  274. Tail->next=temp;
  275. temp->next=NULL;
  276. Tail=temp;
  277. pDC->SetPixelV(temp->x,temp->y,Color);
  278. }
  279. if (pDC->GetPixel(Node->x,Node->y-1)==seedcolor){
  280. temp=new NodeType;
  281. temp->x=Node->x;
  282. temp->y=Node->y-1;
  283. Tail->next=temp;
  284. temp->next=NULL;
  285. Tail=temp;
  286. pDC->SetPixelV(temp->x,temp->y,Color);
  287. }
  288.  temp=Node;
  289.  Node=Node->next;
  290.  delete temp;
  291. }
  292. }
  293. void insertEdge(EdgeType *list, EdgeType *edge)
  294. {
  295. EdgeType * p,* q=list;
  296. p=q->next;
  297. while(p!=NULL)
  298. {
  299. if(edge->xIntersect<p->xIntersect)
  300. p=NULL;
  301. else 
  302. { q=p; p=p->next;}
  303. }
  304. edge->next=q->next;
  305. q->next=edge;
  306. }
  307. void deleteAfter(EdgeType *q)
  308. {
  309. EdgeType * p=q->next;
  310. q->next=p->next;
  311. free(p);
  312. }
  313. void updateActiveList(int scan, EdgeType *active)
  314. {
  315. EdgeType * q=active,*p=active->next;
  316. while(p)
  317. if(scan>=p->yUpper)
  318. {
  319. p=p->next;
  320. deleteAfter(q);
  321. }
  322. else 
  323. {
  324. p->xIntersect=p->xIntersect+p->dxPerScan;
  325. q=p;
  326. p=p->next;
  327. }
  328. }
  329. void resortActiveList(EdgeType *active)
  330. {
  331. EdgeType   *q,*p=active->next;
  332. active->next=NULL;
  333. while(p)
  334. {
  335. q=p->next;
  336. insertEdge(active,p);
  337. p=q;
  338. }
  339. }
  340. int yNext(int k, int cnt, PointType *pts)
  341. {
  342. int  j;
  343. if((k+1)>(cnt-1))
  344. j=0;
  345. else j=k+1;
  346. while(pts[k].y==pts[j].y)
  347. if((j+1)>(cnt-1))
  348. j=0;
  349. else j++;
  350. return (pts[j].y);
  351. }
  352. void makeEdgeRec(PointType lower, PointType upper, int yComp, 
  353.    EdgeType *edge, EdgeType *edges[])
  354. {
  355. edge->dxPerScan=(float)(upper.x-lower.x)/(upper.y-lower.y);
  356. edge->xIntersect=lower.x;
  357. if(upper.y<yComp)
  358. edge->yUpper=upper.y-1;
  359. else edge->yUpper=upper.y;
  360. insertEdge(edges[lower.y],edge);
  361. }
  362. void buildEdgeList(int cnt, PointType *pts, EdgeType *edges[])
  363. {
  364. EdgeType * edge;
  365. PointType v1,v2;
  366. int i,yPrev=pts[cnt-2].y;
  367. v1.x=pts[cnt-1].x;
  368. v1.y=pts[cnt-1].y;
  369. for(i=0;i<cnt;i++)
  370. {
  371. v2=pts[i];
  372. if(v1.y!=v2.y)
  373. {
  374. edge=(EdgeType *)malloc(sizeof(EdgeType));
  375. if(v1.y<v2.y)
  376. makeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
  377. else 
  378. makeEdgeRec(v2,v1,yPrev,edge,edges);
  379. }
  380. yPrev=v1.y;
  381. v1=v2;
  382. }
  383. }
  384. void buildActiveList(int scan, EdgeType *active, EdgeType *edges[])
  385. {
  386. EdgeType *p, *q;
  387. p=edges[scan]->next;
  388. while(p)
  389. {
  390. q=p->next;
  391. insertEdge(active,p);
  392. p=q;
  393. }
  394. }
  395. void fillScan(int scan, EdgeType *active)
  396. {
  397. EdgeType * p1,*p2;
  398. int i;
  399. p1=active->next;
  400. while(p1)
  401. {
  402. p2=p1->next;
  403. for(i=p1->xIntersect;i<p2->xIntersect;i++)
  404. MyDC->SetPixelV((int) i,scan,Mycol);
  405. p1=p2->next;
  406. }
  407. }
  408. void scanFill(CDC *pDC,int cnt, PointType* pts,int Height,COLORREF col)
  409. {
  410. EdgeType * active;
  411. EdgeType * * edges;
  412. Mycol=col;
  413. edges=(EdgeType * *)malloc(sizeof(EdgeType*)*Height);
  414.     int i,scan;
  415. MyDC=pDC;
  416. for(i=0;i<Height;i++)
  417. {
  418. edges[i]=(EdgeType *)malloc(sizeof(EdgeType));
  419. edges[i]->next=NULL;
  420. }
  421. buildEdgeList(cnt,pts,edges);
  422. active=(EdgeType * )malloc(sizeof(EdgeType));
  423. active->next=NULL;
  424. for(scan=0;scan<Height;scan++)
  425. {
  426. buildActiveList(scan,active,edges);
  427. if(active->next)
  428. {
  429. fillScan(scan,active);
  430. updateActiveList(scan,active);
  431. resortActiveList(active);
  432. }
  433. }
  434. }
  435. void DrawCircle(CDC *p,int xo,int yo,int r,COLORREF color)
  436. {
  437. int xa,ya,l,f;
  438. xa=xo+r;
  439. ya=yo;
  440. l=(int)(r*cos(45*pi/180));
  441. f=0;
  442. //对特殊情况的处理
  443. if(r==0 || r==1 || r==2 || r==3) 
  444. {
  445. CPen newpen;
  446. CPen *oldpen;
  447. newpen.CreatePen(PS_SOLID,1,color);
  448. oldpen=p->SelectObject(&newpen);
  449. p->Ellipse(xo-r,yo-r,xo+r,yo+r);
  450. p->SelectObject(oldpen);
  451. }
  452. else{
  453. while(l>=0)
  454. {
  455. //对称的画八个点
  456. p->SetPixelV(xa,ya,color);
  457.     p->SetPixelV(xa,2*yo-ya,color);
  458.     p->SetPixelV(2*xo-xa,ya,color);
  459.     p->SetPixelV(2*xo-xa,2*yo-ya,color);
  460.     p->SetPixelV(xo+ya-yo,yo+xa-xo,color);
  461.     p->SetPixelV(xo+ya-yo,yo-xa+xo,color);
  462.     p->SetPixelV(xo-ya+yo,yo+xa-xo,color);
  463.     p->SetPixelV(xo-ya+yo,yo-xa+xo,color);
  464.     if(f>=0)
  465. {
  466. xa=xa-1;
  467.     f=f-2*(xa-xo)+1;
  468. }
  469.     else{
  470. ya=ya-1;
  471.     f=f+2*(yo-ya)+1;
  472.     l--;
  473. }
  474. }
  475. }
  476. }
  477. void DrawEllipse(CDC *p,int xo,int yo,int a,int b,COLORREF color)
  478. {
  479. int x,y;
  480. float f;
  481. if(a==0 || b==0){      
  482. p->SetPixelV(xo,yo,color);
  483. return;
  484. }
  485. else{
  486. x=0;y=b;
  487.     f=b*b+a*a*(0.25-b);
  488.     while((float)(b*b*(x+1))<=a*a*(y-0.5))
  489. {
  490. //对称的画出四个向限的点
  491. p->SetPixelV(x+xo,yo-y,color);
  492.     p->SetPixelV(x+xo,yo+y,color);
  493.     p->SetPixelV(xo-x,yo-y,color);
  494.     p->SetPixelV(xo-x,yo+y,color);
  495.     if(f<0) {
  496. f+=(float)(b*b*(2*x+3));
  497.     x++;
  498. }
  499.     else {
  500.     f+=(float)(b*b*(2*x+3)+2*a*a*(1-y));
  501.     x++;y--;
  502. }
  503. }
  504.     f=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*b*a*b;
  505.     while(y>=0)
  506. {
  507. //对称的画出四个向限的点
  508. p->SetPixelV(x+xo,yo-y,color);
  509.     p->SetPixelV(x+xo,yo+y,color);
  510.     p->SetPixelV(xo-x,yo-y,color);
  511.     p->SetPixelV(xo-x,yo+y,color);
  512.     if(f<0) {
  513. f+=(float)(2*b*b*(x+1)+a*a*(3-2*y));
  514.     x++;y--;
  515. }
  516.     else {
  517. f+=a*a*(3-2*y);
  518.     y--;
  519. }
  520. }
  521. }
  522. return;
  523. }
  524. void DrawPipo(CDC *p,int x1,int y1,int x2,int y2,int x3,int y3,COLORREF color)
  525. {
  526. int a1,a2,b1,b2,c1,c2;
  527.     int x,y;
  528. double t,d;
  529. //计算双曲线的参数 
  530. a1=x1-3*x2+2*x3;
  531. a2=y1-3*y2+2*y3;
  532. b1=3*x2-2*x1;
  533. b2=3*y2-2*y1;
  534. c1=x1;
  535. c2=y1;
  536. t=0.0;
  537. d=0.0005;
  538. //t从0到1,步长为0.0005
  539. while(t<=1.0)
  540. {
  541. x=(int)((float)(c1+b1*t+a1*t*t)/(1+t));
  542. y=(int)((float)(c2+b2*t+a2*t*t)/(1+t));
  543. p->SetPixelV(x,y,color);
  544. t+=d;
  545. }
  546. }
  547. COLORREF linecolor=RGB(64,0,0);      
  548. void edgeflagscan(CDC *fl,PointType points[],int n,COLORREF fillcolor)
  549. {
  550. int i,j,x,y,xmin,xmax,ymin,ymax;
  551. int x1,y1,x2,y2,flag=0,already;
  552. int xarray[50],yarray[50];
  553. for(i=0;i<=n-1;i++)
  554. {
  555. xarray[i]=points[i].x;
  556. yarray[i]=points[i].y;
  557. }
  558. xmax=getmax(xarray,n);  //x坐标最大值
  559. xmin=getmin(xarray,n);  //x坐标最小值
  560. ymax=getmax(yarray,n);  //y坐标最大值
  561. ymin=getmin(yarray,n);  //y坐标最小值
  562. for(i=0;i<=n-1;i++)
  563. {
  564. if(points[i].x>points[(i+1)%n].x) j=-1;
  565. else if(points[i].x<points[(i+1)%n].x) j=1;
  566. else j=0;
  567. x1=points[i].x;x2=points[(i+1)%n].x;
  568. y1=points[i].y;y2=points[(i+1)%n].y;
  569. for(x=points[i].x;x!=points[(i+1)%n].x;x+=j)
  570. {
  571. already=0;
  572. if(x==points[i].x && x!=points[0].x)
  573. {
  574. if((x-points[(i-1+n)%n].x)*(x-points[(i+1)%n].x)>0)
  575. {
  576. //对非极值顶点处理:向下移一位
  577. if(x!=points[n-1].x) fl->SetPixelV(x,y+1,linecolor);
  578. already=1;
  579. }
  580. //对极值顶点处理:略过
  581. if((x-points[(i-1+n)%n].x)*(x-points[(i+1)%n].x)<0) 
  582. x+=j;
  583. }
  584. //对竖直边的处理
  585. if(x2!=x1) y=(y2-y1)*(x-x1)/(x2-x1)+y1;
  586. else y=(y1>y2)?y2:y1;
  587. if(already==0) fl->SetPixelV(x,y,linecolor);
  588. }
  589. //对多边形的最后一点补充
  590. if(x!=points[0].x || i!=n-1) fl->SetPixelV(x,y,linecolor);
  591. else if(fl->GetPixel(points[0].x,points[0].y)==linecolor)
  592. fl->SetPixelV(points[0].x,points[0].y+1,linecolor);
  593. }
  594. //根据标志来对多边形填色
  595. for(x=xmin;x<=xmax;x++)
  596. {
  597. for(y=ymin;y<=ymax;y++)
  598. {
  599. if(fl->GetPixel(x,y)==linecolor)
  600. flag=(flag+1)%2;
  601. if(flag==1 && fl->GetPixel(x,y)!=linecolor) fl->SetPixelV(x,y,fillcolor);
  602. }
  603. flag=0;
  604. }
  605. return;
  606. }
  607. ///////////////////判断凹凸性/////////////////////////
  608. //判断一点在直线的哪侧
  609. int flag(int x1,int y1,int x2,int y2,int x,int y)
  610. {
  611. int d;
  612. float f;
  613. f=(float)(y-y1)*(x2-x1)-(float)(y2-y1)*(x-x1);
  614. if(f==0.0) d=0;
  615. else if(f>0) d=1;
  616. else d=-1;
  617. return d;
  618. }
  619. void DecidePolygonUpper(int n,PointType points[])
  620. {
  621. if(points==NULL){ 
  622. AfxMessageBox("请先画一多边形!");
  623. return;
  624. }
  625. else{
  626. int dd=0,count=0;
  627.     int s1=0,s2=0;
  628.     for(int i=0;i<=n-1;i++)
  629. {
  630. for(int j=0;j<=n-1;j++)
  631. {
  632. if(j==i || j==i+1) j++;
  633.     else{
  634. dd=flag(points[i].x,points[i].y,points[(i+1)%n].x,points[(i+1)%n].y,points[j].x,points[j].y);
  635.     if(dd==1) s1++;
  636.     if(dd==-1) s2++;
  637. }
  638. }
  639.     if(s1==n-2 || s2==n-2) count++;
  640.     s1=0;
  641.     s2=0;
  642. }
  643.     if(count==n) 
  644. {
  645. AfxMessageBox("凸多边形!");
  646. }
  647.     else
  648. {
  649. AfxMessageBox("凹多边形!");
  650. }
  651. return;
  652. }
  653. }