// Someone asked me how to draw a gear program on the Forum two days ago. I thought it was quite interesting, so I just drew a picture for fun.
// Actually, it is not a gear, but a grating disk of the grating encoder.
// Based on trigonometric functions, the program can draw any number of teeth grating at any angle
// If it is redundant, do not mention the code and graph.
# Include <math. h> // draw the grating disk // PDC Target DC // rect target region // fangledeg baseline angle // The number of tgrid raster void drawgridcoder (CDC * PDC, crect & rect, double fangledeg, int tgrid = 64) {# define Pi (4 * atan (1.0) // π # define angdeg2rad (x) * PI/180.0) // converts degrees to radians # define angrad2deg (x) * 180.0/PI) // converts radians to degrees // converts baseline angles to radians while (fangledeg> 360) fangledeg-= 360; while (fangledeg <0) fangledeg + = 360; double fanglerad = angdeg2rad (fangledeg );// // Save DC int isavedc = PDC-> savedc (); // fill in the background color PDC-> fillsolidrect (rect, RGB (255,255,255 )); // coordinate ing center int oldmapmode = PDC-> setmapmode (mm_isotropic); csize ptoldwinext = PDC-> set1_wext (1700,170 0 ); csize ptoldviewportext = PDC-> setviewportext (rect. width (),-rect. height (); cpoint ptoldorigin = PDC-> setviewportorg (rect. width ()/2, rect. height ()/2); // create and select the paint brush cpen linepen (ps_soli D, 1, RGB (200,200, 0); cpen * poldpen = PDC-> SelectObject (& linepen); // rounding digits # define cuttolong (x) (long) (x)> = 0 )? (X) + 0.5) :( (x)-0.5) // draw the inner wall with a limit gap {double fdeltrad = angdeg2rad (10.0 ); // double fangstart = fanglerad + fdeltrad; double fangend = fanglerad-fdeltrad; int R1 = 60; int r2 = R1 + 20; point pt1 = {cuttolong (R1 * Cos (fangstart), cuttolong (R1 * sin (fangstart)}; point pt2 = {cuttolong (R1 * Cos (fangend )), cuttolong (R1 * sin (fangend)}; double fdang2 = fdeltrad-asin (R1 * sin (fdeltrad)/R2); double fangstart2 = fangstart-fdang2; double fangend2 = fangend + fdang2; point pt3 = {cuttolong (R2 * Cos (fangstart2), cuttolong (R2 * sin (fangstart2 ))}; point Pt4 = {cuttolong (R2 * Cos (fangend2), cuttolong (R2 * sin (fangend2)}; PDC-> moveTo (pt2 ); PDC-> lineto (Pt4); PDC-> lineto (pt3); PDC-> lineto (pt1); PDC-> anglearc (0, 0, R1, (float) angrad2deg (-fangstart),-(float) (360-2 * angrad2deg (fdeltrad);} // draw the circle {int R3 = 100; PDC-> moveTo (R3, 0); PDC-> anglearc (0, 0, R3, 0,360);} // draw 4 small labeled holes {int r4 = 300; int R5 = 10; point pt5 = {cuttolong (R4 * Cos (fanglerad), cuttolong (R4 * sin (fanglerad)}; PDC-> moveTo (pt5.x + R5, pt5.y ); PDC-> anglearc (pt5.x, pt5.y, R5, 0,360); double fdivangrad = angdeg2rad (360.0/8.0); double fangrad1 = fanglerad + fdivangrad/2; double fangrad2 = fanglerad-fdivangrad/2; double R6 = R4/cos (fdivangrad/2); point pt6 = {cuttolong (R6 * Cos (fangrad1 )), cuttolong (R6 * sin (fangrad1)}; PDC-> moveTo (pt6.x + R5, pt6.y); PDC-> anglearc (pt6.x, pt6.y, R5, 0,360 ); point pT7 = {cuttolong (R6 * Cos (fangrad2), cuttolong (R6 * sin (fangrad2)}; PDC-> moveTo (pt7.x + R5, pt7.y ); PDC-> anglearc (pt7.x, pt7.y, R5, 0,360); int R7 = 470; point pt8 = {cuttolong (r7 * Cos (fanglerad )), cuttolong (r7 * sin (fanglerad)}; PDC-> moveTo (pt8.x + R5, pt8.y); PDC-> anglearc (pt8.x, pt8.y, R5, 0,360 );} // draw 8 large holes {double fdivangrad = angdeg2rad (360.0/8.0); int R8 = 500; int R9 = 50; double fangstart3 = (fanglerad + fdivangrad/2 ); for (INT I = 0; I <8; I ++) {point pt8 = {cuttolong (R8 * Cos (fangstart3 )), cuttolong (R8 * sin (fangstart3)}; PDC-> moveTo (pt8.x + R9, pt8.y); PDC-> anglearc (pt8.x, pt8.y, R9, 0,360 ); fangstart3 + = fdivangrad ;}// draw a large circle {int R10 = 600; point pt9 = {cuttolong (R10 * Cos (fanglerad )), cuttolong (R10 * sin (fanglerad)}; PDC-> moveTo (R10, 0); PDC-> anglearc (0, 0, R10, 0,360 );} // draw the tooth {int R11 = 800; int R12 = R11-50; int R13 = R12-100; double fdivangrad = angdeg2rad (360.0/tgrid ); double fangstart4 = (fanglerad + fdivangrad/2); double fdang5 = fdivangrad/8; double fdang6 = fdivangrad/2-fdang5; For (INT I = 0; I <tgrid; I ++) {double F6 = fangstart4-fdivangrad/2; double F5 = fangstart4-fdivangrad/4; if (I = 0) {PDC-> moveTo (cuttolong (R13 * Cos (F6), cuttolong (R13 * sin (F6);} PDC-> anglearc (0, 0, R13, (float) angrad2deg (-F6), (float) angrad2deg (f6-f5); point pt6 = {cuttolong (R12 * Cos (F5 )), cuttolong (R12 * sin (F5)}; PDC-> lineto (pt6); double F4 = fangstart4-fdang6; point pt5 = {cuttolong (R12 * Cos (F4 )), cuttolong (R12 * sin (F4)}; PDC-> lineto (pt5); point Pt4 = {cuttolong (R11 * Cos (F4 )), cuttolong (R11 * sin (F4)}; PDC-> lineto (Pt4); double F3 = fangstart4 + fdang6; PDC-> anglearc (0, 0, R11, (float) angrad2deg (-F4), (float) angrad2deg (f4-f3); point pt3 = {cuttolong (R12 * Cos (F3), cuttolong (R12 * sin (F3 ))}; PDC-> lineto (pt3); double F2 = fangstart4 + fdivangrad/4; point pt2 = {cuttolong (R12 * Cos (F2 )), cuttolong (R12 * sin (F2)}; PDC-> lineto (pt2); point pt1 = {cuttolong (R13 * Cos (F2 )), cuttolong (R13 * sin (F2)}; PDC-> lineto (pt1); double F1 = fangstart4 + fdivangrad/2; PDC-> anglearc (0, 0, R13, (float) angrad2deg (-F1), (float) angrad2deg (F1-F2); fangstart4 + = fdivangrad ;}/// annotation log/* {logfont = {0 }; _ tcscpy_s (logfont. lffacename, _ T ("Arial"); logfont. lfheight =-muldiv (40, PDC-> getdevicecaps (logpixelsy), 72); logfont. lfescapement = cuttolong (-fangledeg + 90) * 10); logfont. lforientation = logfont. lfescapement; // logfont. lfweight = fw_heavy; cfont font; font. createfontindirect (& logfont); cfont * poldfont = PDC-> SelectObject (& font); lpctstr szlog = _ T ("Grid coder "); csize txtsize = PDC-> gettextextent (szlog); PDC-> lptodp (& txtsize); double R20 = 200; double frad2 = fanglerad + pi-0.1; // asin (txtsize. CX/2)/R20); point pt20 = {cuttolong (R20 * Cos (frad2), cuttolong (R20 * sin (frad2 ))}; PDC-> settextcolor (RGB (255, 0, 0); PDC-> setbkmode (transparent); PDC-> textout (pt20.x, pt20.y, szlog ); PDC-> SelectObject (poldfont);} * // restore PDC ing mode PDC-> setjavaswext (ptoldwinext); PDC-> setviewportext (ptoldviewportext); PDC-> setviewportorg (ptoldorigin ); PDC-> setmapmode (oldmapmode); // restores the brush PDC-> SelectObject (poldpen); // restores dc pdc-> restoredc (isavedc );}
// Draw the test program. Add a double variable to the class to record the angle. Use the timer to constantly change the angle and refresh it.
// Add the start, stop, and reset buttons in the menu.
// Observe the dynamic and static running conditions
// Double buffer draw void csdi22view: ondraw (CDC * PDC) {csdi22doc * pdoc = getdocument (); assert_valid (pdoc); If (! Pdoc) return; crect rect; getclientrect (rect); cmemdc memdc (* PDC, this); drawgridcoder (& memdc. getdc (), rect, fstartangleset); // (double) rand ()/rand_max * 360.0); // 0); // todo: add drawing code for local data here} // to prevent flickering wm_erasebkgnd, return truebool csdi22view: onerasebkgnd (CDC * PDC) {// todo: add the message processing program code and/or call the default value return true; return cview: onerasebkgnd (PDC);} // process the menu message and refresh bool csdi22view: on1_msg (uint NID, int ncode, void * Pextra, afx_cmdhandlerinfo * phandlerinfo) {// todo: Add dedicated code and/or call the base class ccmdui * pcmdui = (ccmdui *) pextra; If (phandlerinfo = NULL) {bool bdone = false; Switch (NID) {Case (id_popup_start): // start {If (ncode = cn_update_command_ui) {pcmdui-> enable (mrefreshtimerid = 0 ); pcmdui-> setcheck (mrefreshtimerid? True: false); bdone = true;} else if (ncode = cn_command) {mrefreshtimerid = settimer (10, 10, null); bdone = true;} break ;} case (id_popup_stop): // stop {If (ncode = cn_update_command_ui) {pcmdui-> enable (mrefreshtimerid? True: false); pcmdui-> setcheck (mrefreshtimerid = 0); bdone = true;} else if (ncode = cn_command) {If (mrefreshtimerid) {killtimer (mrefreshtimerid ); mrefreshtimerid = 0;} bdone = true;} break;} case (id_popup_reset): // reset {If (ncode = cn_update_command_ui) {pcmdui-> enable (true ); bdone = true;} else if (ncode = cn_command) {fstartangleset = 0; invalidaterect (null); bdone = true;} break ;}} if (bdone) return true ;} return cview: on1_msg (NID, ncode, pextra, phandlerinfo);} // timer message void csdi22view: ontimer (uint_ptr nidevent) {// todo: add the message processing program code and/or call the default value fstartangleset + = 1.0; invalidaterect (null); cview: ontimer (nidevent );}