VasilM

zzz

Oct 2nd, 2014
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.36 KB | None | 0 0
  1. double zeroF(double a, double b, double(*f)(double)) {
  2.     double fa=f(a), fb=f(b), fx=1., x, eps=1e-14;
  3.     if (fa*fb > 0) throw exception("Not applicable");
  4.     while(fabs(fx)>eps || fabs(a-b) > eps) {
  5.         x = f(a+b)/2.;
  6.         fx = f(x);
  7.         if(fx*fb < 0) a = x;
  8.         else {b=x; fb=fx;}
  9.     }
  10.     return x;
  11. }
  12.  
  13.  
  14. ///////
  15.  
  16.  
  17. #include <iostream>
  18. #include <math.h>
  19.  
  20. using namespace std;
  21.  
  22. typedef double (*FN)(double);
  23.  
  24. double f(double x){return 5.*sin(x/7.)+0.001*x*x;}
  25. double fi(double x){return x -1.25*f(x);}
  26. // x3+x-1000=0
  27. double fi2(double x){return exp(log(1000.-x)*(1./3.));}
  28.  
  29. // eps - to4nost
  30.  bool iterSolution(double & x, FN fi, double eps, int &iter){
  31. // xn - x novo; xs - x staro
  32.      double xn, xs=x;
  33.      for(int i=0;i<iter;i++){
  34.          xn = fi(xs);
  35.          if(fabs(xn-xs)<eps){
  36.              x=xn;iter=i;return true;
  37.          }
  38.          xs=xn;
  39.      }
  40.      return false;
  41.  }
  42.  
  43. int main(){
  44.      double x, eps=1e-14;
  45.      int iters=100;
  46.      while(true){
  47.          cin>>x;
  48.          double xt=x; int it=iters;
  49.          if(iterSolution(xt,fi2,eps,it)){
  50.             cout<<"zero="<<xt<<", it= "<<it<<endl;
  51.          }else cout<<"Can not apply iterations!"<<endl;
  52.      }
  53.  
  54.     return 0;
  55.  }
  56.  
  57.  
  58.  
  59. /////////////////////////////
  60.  
  61.  
  62. #define _CRT_SECURE_NO_WARNINGS
  63. #include <cstdio>
  64. #include <string>
  65. #include <cmath>
  66. #include <exception>
  67. #include "msw.h"
  68.  
  69. //Начални размери на графичния прозорец в потребителски единици
  70. double DEFAULT_XMIN = -20;
  71. double DEFAULT_YMIN = 20; //знаците по Y са обърнати умишлено
  72. double DEFAULT_XMAX = 20;
  73. double DEFAULT_YMAX = -20;
  74.  
  75. //Заглавие в рамката на приложението
  76. char title[200] = "ГРАФИЧНА КОНЗОЛА";
  77.  
  78.  
  79. int snapfract = 2;
  80.  
  81. ////////
  82. typedef double (*FN)(double);
  83.  
  84. double f(double x){return 5.*sin(x/7.)+0.001*x*x;}
  85. double fi(double x){return x -1.25*f(x);}
  86. // x3+x-1000=0
  87. double fi2(double x){return exp(log(1000.-x)*(1./3.));}
  88.  
  89. // eps - to4nost
  90.  bool iterSolution(double & x, FN fi, double eps, int &iter){
  91. // xn - x novo; xs - x staro
  92.      double xn, xs=x;
  93.      for(int i=0;i<iter;i++){
  94.          xn = fi(xs);
  95.          if(fabs(xn-xs)<eps){
  96.              x=xn;iter=i;return true;
  97.          }
  98.          xs=xn;
  99.      }
  100.      return false;
  101.  }
  102.  /////////////////
  103.  
  104. typedef double (*FUN)(double);
  105.  
  106. double Sin(double x){return x;} // tuk
  107.  
  108. //Изчертаване графиката на функция на една променлива
  109. //[argL, argR} - интервал на аргумента, f -функция
  110. void drawFun(double argL, double argR,FUN f){
  111.     if(argL>argR)std::swap(argL,argR);
  112.     //стъпка на изменение на аргумента = 2 пиксела
  113.     double resx = cwin.disp_to_user_x(2)-cwin.disp_to_user_x(0),
  114.            resy = cwin.disp_to_user_y(0)-cwin.disp_to_user_y(2),
  115.            res = resx<resy? resx : resy;
  116.     //начална точка на графиката
  117.     Point first(argL,f(argL)),second;
  118.     for(double x=argL+res;x<=argR;x+=res){
  119.         second=Point(x,f(x));//текуща точка
  120.         cwin<<Line(first,second);
  121.         first=second;
  122.     }
  123. }
  124.  
  125. //Симулация на конзолна функция
  126. int win_main(){
  127.     string yn;  cwin<<RGB(0,0,100);cwin.axes();//cwin<<SNAP;
  128.     yn=cwin.get_string("Графики на функции на една променлива. \n"
  129.         "[y]/n за продължение:");
  130.  
  131.     double x=50, eps=1e-14;
  132.     int iters=100;
  133.     double xt=x; int it=iters;
  134.     if(iterSolution(xt,fi,eps,it));
  135.  
  136.  
  137.     if(yn[0]!='n'){
  138.         cwin.axes(); //координатни оси с деления
  139.         cwin<<RGB(120,0,0); //смяна на цвета
  140.         drawFun(-20.,20.,Sin);//изчертаване на графиката
  141.     }
  142.     cwin.get_string("<Enter> за край.");
  143.     cwin.clear();exit(0);
  144.     return 0;
  145. }
  146.  
  147.  
  148.  
  149.  
  150. ////////////////////////////////////////////////
  151.  
  152.  
  153.  
  154.  
  155.  
  156. //Демонстрационен програмен текст за алгоритъма на Cohen-Sutherland
  157. //Курс CSCB506 към програма Информатика на НБУ
  158. //Автор: Ст. Иванов, 2013
  159. #include <windows.h>
  160. #include <stdio.h>
  161. #include <math.h>
  162.  
  163.  
  164. struct PNT2{ double x, y; };//точка с реални координати
  165.  
  166. //координати на изрязващия прозорец
  167. double xmin = 100, ymin = 100, xmax = 800, ymax = 500;
  168.  
  169. //Изработване на признак за зоната, в която се намира точката
  170. inline BYTE outcode(PNT2 p){
  171.     BYTE code = 0;
  172.     if (p.y>ymax)code += 8;
  173.     else if (p.y<ymin)code += 4;
  174.     if (p.x>xmax)code += 2;
  175.     else if (p.x<xmin)code += 1;
  176.     return code;
  177. }
  178.  
  179. //Изрязващ алгоритъм на Cohen-Sutherland
  180. //Параметрите p1 и p2 са модифицируеми: при вход съдържат крайните
  181. //точки на отсечката, при изход - крайните точки на участъка,
  182. //намиращ се вътре в правоъгълника.
  183. //Връщаната стойност е 1, ако отсечката е изцяло вън от правоъгълника
  184. //и 0, ако поне част от отсечката е вътре. Тогава в p1 и p2 са краищата
  185. //на въртешната част от отсечката.
  186. int CSClip(PNT2 & p1, PNT2 & p2){
  187.     BYTE code1 = outcode(p1), code2 = outcode(p2), code;
  188.     double x, y;
  189.     do{
  190.         if (code1&code2)return 1;    //изцяло вън
  191.         if (code1 + code2 == 0)return 0; //изцяло вътре
  192.         //поне едната точка е вътре, взема се
  193.         code = code1 != 0 ? code1 : code2;
  194.         if (code & 8){//ако е отгоре, премества се по горната граница
  195.             x = p1.x + (p2.x - p1.x)*(ymax - p1.y) / (p2.y - p1.y);
  196.             y = ymax;
  197.         }
  198.         else if (code & 4){//ако е отдолу, премества се по долната граница
  199.             x = p1.x + (p2.x - p1.x)*(ymin - p1.y) / (p2.y - p1.y);
  200.             y = ymin;
  201.         }
  202.         else if (code & 2){//ако е отдясно, премества се по дясната граница
  203.             y = p1.y + (p2.y - p1.y)*(xmax - p1.x) / (p2.x - p1.x);
  204.             x = xmax;
  205.         }
  206.         else if (code & 1){//ако е отляво, премества се по лявата граница
  207.             y = p1.y + (p2.y - p1.y)*(xmin - p1.x) / (p2.x - p1.x);
  208.             x = xmin;
  209.         }
  210.         //присвояване на преместената точка и ново пресмятане на кода
  211.         if (code == code1){
  212.             p1.x = x; p1.y = y; code1 = outcode(p1);
  213.         }
  214.         else{
  215.             p2.x = x; p2.y = y; code2 = outcode(p2);
  216.         }
  217.     } while (true);
  218. }
  219.  
  220.  
  221. void lineBres(HDC, POINT, POINT, COLORREF);
  222. void showCoord(HWND, LPARAM);
  223. void redraw(HWND);
  224. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  225.  
  226.  
  227. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  228.     PSTR szCmdLine, int iCmdShow)
  229. {
  230.     static TCHAR szAppName[] = L"LinesDemo";
  231.     HWND         hwnd;
  232.     MSG          msg;
  233.     WNDCLASS     wndclass;
  234.  
  235.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  236.     wndclass.lpfnWndProc = WndProc;
  237.     wndclass.cbClsExtra = 0;
  238.     wndclass.cbWndExtra = 0;
  239.     wndclass.hInstance = hInstance;
  240.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  241.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  242.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  243.     wndclass.lpszMenuName = NULL;
  244.     wndclass.lpszClassName = szAppName;
  245.  
  246.     if (!RegisterClass(&wndclass))
  247.     {
  248.         MessageBox(NULL, TEXT("Can not register the window class!"),
  249.             szAppName, MB_ICONERROR);
  250.         return 0;
  251.     }
  252.  
  253.     hwnd = CreateWindow(szAppName,
  254.         L" CSCB506-4: Clipping rectangle. NBU 2013 Ivanov",
  255.         WS_OVERLAPPEDWINDOW,
  256.         CW_USEDEFAULT, CW_USEDEFAULT,
  257.         CW_USEDEFAULT, CW_USEDEFAULT,
  258.         NULL, NULL, hInstance, NULL);
  259.  
  260.     ShowWindow(hwnd, iCmdShow);
  261.     UpdateWindow(hwnd);
  262.  
  263.     while (GetMessage(&msg, NULL, 0, 0))
  264.     {
  265.         TranslateMessage(&msg);
  266.         DispatchMessage(&msg);
  267.     }
  268.     return msg.wParam;
  269. }
  270. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  271. {
  272.     HDC          hdc;
  273.     static bool LBD = true; //сигнал за натиснат ляв бутон на мишката
  274.     static PNT2 p1, p2;    //крайни точки на отсечката в double координати
  275.     static POINT P1, P2;   //крайни точки на отсечката в int координати
  276.     static int ip = 0;      //сигнал за първа-втора въведена точка
  277.     switch (message)
  278.     {
  279.     case WM_LBUTTONDOWN:
  280.         LBD = true;
  281.         return 0;
  282.  
  283.     case WM_MOUSEMOVE:
  284.         showCoord(hwnd, lParam);
  285.         return 0;
  286.  
  287.     case WM_LBUTTONUP:
  288.         if (LBD){
  289.             LBD = !LBD;
  290.             if (ip == 0){//въвеждане на първа точка
  291.                 P1.x = LOWORD(lParam);
  292.                 P1.y = HIWORD(lParam);
  293.                 ip++;
  294.             }
  295.             else{//въвеждане на втора точка
  296.                 P2.x = LOWORD(lParam);
  297.                 P2.y = HIWORD(lParam);
  298.                 ip--;
  299.                 //и обработка на отсечката
  300.                 p1.x = P1.x; p1.y = P1.y;//прехвърляне в double координати
  301.                 p2.x = P2.x; p2.y = P2.y;
  302.                 int code = CSClip(p1, p2);//изрязване
  303.                 hdc = GetDC(hwnd);
  304.                 if (code == 1)
  305.                     //отсечката е вън - чертае се в синьо
  306.                     lineBres(hdc, P1, P2, RGB(0, 0, 150));
  307.                 else{//поне отчасти е вътре
  308.                     POINT P11, P22; //вземат се крайните точки
  309.                     //на вътрешната част
  310.                     P11.x = (int)p1.x; P11.y = (int)p1.y;
  311.                     P22.x = (int)p2.x; P22.y = (int)p2.y;
  312.                     //вътрешната част се чертае в червено
  313.                     //външната(ите) част(и) - в синьо
  314.                     lineBres(hdc, P1, P11, RGB(0, 0, 150));
  315.                     lineBres(hdc, P11, P22, RGB(150, 0, 0));
  316.                     lineBres(hdc, P2, P22, RGB(0, 0, 150));
  317.  
  318.                     // DRASKA KOORDINATI W DOBULE na P1 i P2
  319.                     TCHAR mouf[100], spac[40] = L"                                   ";
  320.                     RECT rect; HDC hdc;
  321.                     swprintf(mouf, 100, L"P1: %20.4f , %20.4f\nP2: %20.4f , %20.4f", p1.x, p1.y, p2.x, p2.y);      
  322.                     hdc = GetDC(hwnd);
  323.                     GetClientRect(hwnd, &rect);
  324.                     DrawText(hdc, spac, -1, &rect,
  325.                         WNFMT_MULTILINE | DT_BOTTOM | DT_RIGHT);
  326.                     DrawText(hdc, mouf, -1, &rect,
  327.                         WNFMT_MULTILINE | DT_BOTTOM | DT_RIGHT);
  328.                 }                
  329.  
  330.                
  331.                 ReleaseDC(hwnd, hdc);
  332.             }
  333.         }
  334.         return 0;
  335.     case WM_RBUTTONDOWN://с десен бутон се изтрива
  336.         InvalidateRect(hwnd, NULL, TRUE);
  337.         return 0;
  338.     case WM_PAINT://изчертава се само рамката - изрязващ правоъгълник
  339.         redraw(hwnd);
  340.         return 0;
  341.  
  342.     case WM_DESTROY:
  343.         PostQuitMessage(0);
  344.         return 0;
  345.     }
  346.     return DefWindowProc(hwnd, message, wParam, lParam);
  347. }
  348.  
  349. void showCoord(HWND hwnd, LPARAM lParam){
  350.     TCHAR mouf[20], spac[20] = L"                   ";
  351.     RECT rect; HDC hdc;
  352.     wsprintf(mouf, L"%i   %i", LOWORD(lParam), HIWORD(lParam));
  353.     hdc = GetDC(hwnd);
  354.     GetClientRect(hwnd, &rect);
  355.     DrawText(hdc, spac, -1, &rect,
  356.         DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  357.     DrawText(hdc, mouf, -1, &rect,
  358.         DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  359.     ReleaseDC(hwnd, hdc);
  360. }
  361. void redraw(HWND hwnd){
  362.     HDC hdc = GetDC(hwnd);
  363.     MoveToEx(hdc, (int)xmin, (int)ymin, NULL);
  364.     LineTo(hdc, (int)xmin, (int)ymax);
  365.     LineTo(hdc, (int)xmax, (int)ymax);
  366.     LineTo(hdc, (int)xmax, (int)ymin);
  367.     LineTo(hdc, (int)xmin, (int)ymin);
  368.  
  369.     ReleaseDC(hwnd, hdc);
  370. }
  371.  
  372. inline void swap(int &p, int &q){ int t = p; p = q; q = t; }
  373.  
  374. void lineBres(HDC hdc, POINT p1, POINT p2, COLORREF c){
  375.     int x0 = p1.x, y0 = p1.y, x1 = p2.x, y1 = p2.y;
  376.     bool str = abs(y1 - y0)>abs(x1 - x0);
  377.     if (str)  { swap(x0, y0); swap(x1, y1); }
  378.     if (x0>x1){ swap(x0, x1); swap(y0, y1); }
  379.     int dx = x1 - x0, dy = abs(y1 - y0), err = 0, y = y0;
  380.     int yst = y0<y1 ? 1 : -1;
  381.     for (int x = x0; x <= x1; x++){
  382.         if (str) SetPixel(hdc, y, x, c);
  383.         else    SetPixel(hdc, x, y, c);
  384.         err += dy;
  385.         if (2 * err >= dx){ y += yst; err -= dx; }
  386.     }
  387. }
  388.  
  389.  
  390. ////////////////////////////////
  391.  
  392.  
  393. #include <iostream>
  394. #include <cmath>
  395. #include <iomanip>
  396. using namespace std;
  397. //Изходен манипулатор за форматиране на double
  398. ostream & setWP(ostream & s){
  399.     s<<fixed<<setw(10)<<setprecision(10);
  400.     return s;
  401. }
  402. //Контролирано въвеждане с подсещане на double
  403. double getDbl(const char *pr){
  404.      double t;char buf[80];bool E;
  405.      do {
  406.          cout<<"Enter double:"<<pr;cin>>t;E=cin.fail();
  407.          if(E){
  408.              cin.clear();cin.getline(buf,79);
  409.              cout<<"Input error. Try again.\n";}
  410.      }while(E);cin.getline(buf,79);
  411.      return t;
  412. }
  413.  
  414. //Клас "3D точка"= вектор в тримерното пространство
  415. class Vector3{
  416.     double x,y,z;      //координати
  417. public:
  418. //Основен конструктор, при изпускане на параметрите генерира (0,0,0)
  419.     Vector3(double x=0,double y=0,double z=0):x(x),y(y),z(z){}
  420. //Предефиниране на оператори за събиране, изваждане, умножение с число
  421.  Vector3 operator +(const Vector3 &b)const{return Vector3(x+b.x,y+b.y,z+b.z);}
  422.  Vector3 operator -(const Vector3 &b)const{return Vector3(x-b.x,y-b.y,z-b.z);}
  423.  Vector3 operator *(double b)const{return Vector3(x*b,y*b,z*b);}
  424. //Оператор за скаларно произведение на вектори
  425.  double operator %(const Vector3 &b)const{return x*b.x+y*b.y+z*b.z;}
  426. //Модул (големина) на вектор
  427.  double mod()const{return sqrt(*this%*this);}
  428. //Оператор за векторно произведение на вектори
  429.  Vector3 operator *(const Vector3 &b)const{
  430.      return Vector3(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);
  431.  }
  432. //Получаване на единичен вектор
  433.  Vector3 operator !()const{
  434.      double m=mod();if(m!=0)return Vector3(x/m,y/m,z/m);else return *this;
  435.  }
  436. //Смяна на знака (унарен минус)
  437.  Vector3 operator -()const{return Vector3(-x,-y,-z);}
  438. //Сравняване на вектори
  439.  bool operator ==(const Vector3 &b)const{return !(*this!=b);}
  440.  bool operator !=(const Vector3 &b)const{
  441.      double m=mod();  return m!=0&&
  442.        (fabs(x-b.x)/m>1e-10||fabs(y-b.y)/m>1e-10||fabs(z-b.z)/m>1e-10);
  443.  }
  444.  ostream & ins(ostream & s)const{
  445.     s<<'('<<setWP<<x<<','<<setWP<<y <<','<<setWP<<z<<')'<<endl;
  446.     return s;
  447.  }
  448. //Въвеждане на вектор от конзолата
  449. void InpVect(){
  450.  cout<<"Input the components of a 3-D vector:\n";
  451.  x=getDbl("x:");y=getDbl("y:");z=getDbl("z:");
  452. }
  453.  
  454. //Промяна на компоненти
  455. void setX(double x){this->x=x;}
  456. void setY(double y){this->y=y;}
  457. void setZ(double z){this->z=z;}
  458. //Извличане на компоненти
  459. double getX()const{return x;}
  460. double getY()const{return y;}
  461. double getZ()const{return z;}
  462. };
  463.  
  464. //Умножение на число по вектор
  465. Vector3 operator *(double b,const Vector3 &a){return a*b;}
  466. //Вмъкване на вектор в изходния поток
  467. ostream& operator <<(ostream &s,const Vector3 &a){return a.ins(s);}
  468.  
  469. //3 zad
  470. double computeTriangleArea(const Vector3 &a,const Vector3 &b,const Vector3 &c) {
  471.     return 0.5*((b-a)*(c-a)).mod();
  472. }
  473.  
  474. //4 zad
  475. Vector3 mediCenter(const Vector3 &a,const Vector3 &b,const Vector3 &c) {
  476.     return (1./3.)*(a+b+c);
  477. }
  478.  
  479. //5 zad
  480. bool izpyknalVector(const Vector3 V [], int n) {
  481.      double z = ((V[n]- V[n-1])*(V[1]-V[0])).getZ();
  482.      for(int i=1; i<n; i++) {
  483.         double t = ((V[i]- V[i-1])*(V[i+1]-V[i])).getZ();
  484.         if( z*t<0 ) return false;
  485.      }
  486.      return true;
  487. }
  488.  
  489. int main(){
  490.  Vector3 A,B,C;
  491.  cout<<"Vector A:\n"; A.InpVect();
  492.  cout<<"Vector B:\n"; B.InpVect();
  493.  cout<<"Vector C:\n"; C.InpVect();
  494.  
  495.  //3 zad
  496.  cout<< computeTriangleArea(A,B,C);
  497.  //4 zad
  498.  cout<< mediCenter(A,B,C);
  499.  
  500.  /*
  501.  cout<<"A="<<A;cout<<"B="<<B;
  502.  cout<<"Additive operations:\n";
  503.  cout<<"A+B="<<A+B; cout<<"B-A="<<B-A;
  504.  cout<<"Products:\n";
  505.  cout<<"A * B= "<<A*B;
  506.  cout<<"A . B= "<<A%B<<endl;
  507.  cout<<"A*2.5="<<A*2.5;
  508.  cout<<"0.1*B="<<0.1*B ;
  509.  cout<<"Unary operations:\n";
  510.  cout<<"|A|="<<A.mod()<<endl;
  511.  cout<<"-A="<<-A;
  512.  cout<<"unified A="<<!A;
  513.  cout<<"Comparision:\n";
  514.  cout<<"A==B? "<<boolalpha<<(A==B)<<endl;
  515.  cout<<"Getters/setters:\n";
  516.  cout<<"Input x-component of A:";double x;cin>>x;A.setX(x);
  517.  cout<<"A is set as:"<<A;cout<<"A.x="<<A.getX()<<endl;
  518.  */
  519.  
  520.  
  521.  
  522. /////////////////////////////////////////////
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530. //main.cpp
  531.  
  532. #include <windows.h>
  533. #include <math.h>
  534. #include "vector2D.h"
  535.  
  536.  
  537.  
  538. COLORREF clrs[6] = { 0xAF0000, 0x00AF00, 0x0000AF, 0x00AFAF, 0xAF00AF };
  539. double scale = 1;
  540. COLORREF defClr = clrs[5];
  541. int clrPt = 5;
  542. int maxRec = 5;
  543. int toDraw = 0;
  544.  
  545. void lineBres(HDC, POINT, POINT, COLORREF);
  546. void redrawAll(HWND);
  547. void Line(HDC, Point, Point);
  548. void drawKoch(HDC, Point, Point);
  549. void drawPeano(HDC, Point, Point);
  550. void drawGosper(HDC, Point, Point);
  551. void drawHarter(HDC, Point, Point);
  552. void drawSerp(HDC, Point, Point);
  553.  
  554. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  555.  
  556. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  557.     PSTR szCmdLine, int iCmdShow)
  558. {
  559.     static TCHAR szAppName[] = TEXT("Fractal Curves Demo");
  560.     HWND         hwnd;
  561.     MSG          msg;
  562.     WNDCLASS     wndclass;
  563.  
  564.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  565.     wndclass.lpfnWndProc = WndProc;
  566.     wndclass.cbClsExtra = 0;
  567.     wndclass.cbWndExtra = 0;
  568.     wndclass.hInstance = hInstance;
  569.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  570.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  571.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  572.     wndclass.lpszMenuName = NULL;
  573.     wndclass.lpszClassName = szAppName;
  574.  
  575.     if (!RegisterClass(&wndclass))
  576.     {
  577.         MessageBox(NULL, TEXT("Can not register the window class!"),
  578.             szAppName, MB_ICONERROR);
  579.         return 0;
  580.     }
  581.  
  582.     hwnd = CreateWindow(szAppName, L" CSCB506-5: Recursive Curves Demo",
  583.         WS_OVERLAPPEDWINDOW,
  584.         CW_USEDEFAULT, CW_USEDEFAULT,
  585.         CW_USEDEFAULT, CW_USEDEFAULT,
  586.         NULL, NULL, hInstance, NULL);
  587.     ShowWindow(hwnd, iCmdShow);
  588.     UpdateWindow(hwnd);
  589.  
  590.     while (GetMessage(&msg, NULL, 0, 0))
  591.     {
  592.         TranslateMessage(&msg);
  593.         DispatchMessage(&msg);
  594.     }
  595.     return msg.wParam;
  596. }
  597.  
  598. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  599. {
  600.     static int        cxClient, cyClient;
  601.  
  602.     switch (message)
  603.     {
  604.     case WM_SIZE:
  605.         cxClient = LOWORD(lParam);
  606.         cyClient = HIWORD(lParam);
  607.         scale = cxClient<cyClient ? cxClient*0.1 : cyClient*0.1;
  608.         return 0;
  609.     case WM_KEYDOWN:
  610.         switch (wParam)
  611.         {
  612.         case VK_LEFT:
  613.             clrPt = (clrPt + 1) % 6; defClr = clrs[clrPt];
  614.             break;
  615.  
  616.         case VK_RIGHT:
  617.             clrPt = (clrPt + 5) % 6; defClr = clrs[clrPt];
  618.             break;
  619.  
  620.         case VK_UP:
  621.             maxRec--;
  622.             break;
  623.  
  624.         case VK_DOWN:
  625.             maxRec++;
  626.             break;
  627.  
  628.         case VK_HOME:
  629.             toDraw = (toDraw + 1) % 5;
  630.             break;
  631.         case VK_END:
  632.             toDraw = (toDraw + 4) % 5;
  633.             break;
  634.         default: return 0;
  635.         }
  636.         InvalidateRect(hwnd, NULL, TRUE);
  637.         return 0;
  638.  
  639.     case WM_PAINT:
  640.         redrawAll(hwnd);
  641.         return 0;
  642.  
  643.     case WM_DESTROY:
  644.         PostQuitMessage(0);
  645.         return 0;
  646.     }
  647.     return DefWindowProc(hwnd, message, wParam, lParam);
  648. }
  649.  
  650. void Line(HDC hdc, Point a, Point b){
  651.     POINT A, B;
  652.     A.x = (LONG)(a.getX()*scale);
  653.     A.y = (LONG)(a.getY()*scale);
  654.     B.x = (LONG)(b.getX()*scale);
  655.     B.y = (LONG)(b.getY()*scale);
  656.  
  657.     lineBres(hdc, A, B, defClr);
  658. }
  659.  
  660. void drawKoch(HDC hdc, Point a, Point b){
  661.     static int rec = 0; rec++;
  662.     if (rec>maxRec)Line(hdc, a, b);
  663.     else{
  664.         Point a1 = a*(2. / 3.) + b*(1. / 3),
  665.             b1 = a*(1. / 3.) + b*(2. / 3),
  666.             c = a1 + ((b - a)*(1. / 3.)).rotA(60.);
  667.         drawKoch(hdc, a, a1); drawKoch(hdc, a1, c);
  668.         drawKoch(hdc, c, b1); drawKoch(hdc, b1, b);
  669.     }
  670.     rec--;
  671. }
  672. void drawPeano(HDC hdc, Point a, Point b){
  673.     static int rec = 0; rec++;
  674.     if (rec>maxRec)Line(hdc, a, b);
  675.     else{
  676.         Point t = (b - a)*(1. / 3.), n = t.rotL(),
  677.             p1 = a + t, p2 = p1 + n, p3 = p2 + t, p4 = p3 - n, p6 = p1 - n, p7 = p6 + t;
  678.         drawPeano(hdc, a, p1); drawPeano(hdc, p1, p2); drawPeano(hdc, p2, p3);
  679.         drawPeano(hdc, p3, p4); /*drawPeano(hdc, p4, p1); drawPeano(hdc, p1, p6);
  680.         drawPeano(hdc, p6, p7); drawPeano(hdc, p7, p4);*/ drawPeano(hdc, p4, b);
  681.  
  682.     }
  683.     rec--;
  684. }
  685. void drawGosper(HDC hdc, Point a, Point b){
  686.     static int rec = 0; rec++;
  687.     if (rec>maxRec)Line(hdc, a, b);
  688.     else{
  689.         Point t = (b - a)*0.5, p = t*(5. / 7), q = t*(sqrt(3.) / 7),
  690.             r = p + q.rotL(), p1 = a + r, p2 = b - r, p3 = p2 - r, l = p2 - (a + r*2.),
  691.             p4 = p3 + l, p5 = p4 + r, p6 = b + l, p7 = p6 + t;
  692. //      Point t = (b - a)*(1. / 3.), n = t.rotL(),
  693. //          p1 = a + t, p2 = p1 + n, p3 = p2 + t, p4 = p3 - n, p6 = p1 - n, p7 = p6 + t,
  694. //          p = t*(5. / 7), q = t*(sqrt(3.) / 7), r = p + q.rotL(), p5 = p4 + r;
  695. //
  696.         drawGosper(hdc, a, p1);
  697.         drawGosper(hdc, p1, p2); drawGosper(hdc, p2, p3);
  698.         drawGosper(hdc, p3, p4); drawGosper(hdc, p4, p1);
  699.         drawGosper(hdc, p1, p6); drawGosper(hdc, p6, p7);
  700.         drawGosper(hdc, p7, p4); drawGosper(hdc, p4, b);
  701.     }
  702.     rec--;
  703. }
  704.  
  705. void drawSerp(HDC hdc, Point a, Point b){
  706.     static int rec = 0; rec++;
  707.     if (rec>maxRec)Line(hdc, a, b);
  708.     else{
  709.         Point t = (b - a)*0.5, p1 = a + t.rotA(60.), p2 = p1 + t;
  710.         drawSerp(hdc, p1, a);
  711.         drawSerp(hdc, p1, p2);
  712.         drawSerp(hdc, b, p2);
  713.     }
  714.     rec--;
  715. }
  716. void drawHarter(HDC hdc, Point a, Point b){
  717.     static int rec = 0; rec++;
  718.     if (rec>maxRec)Line(hdc, a, b);
  719.     else{
  720.         Point t = (b - a)*0.5, c = a + t + t.rotR();
  721.         drawHarter(hdc, a, c); drawHarter(hdc, c, b);
  722.     }
  723.     rec--;
  724. }
  725.  
  726. void draw1(HDC hdc, Point a, Point b){
  727.     static int rec = 0; rec++;
  728.     if (rec>maxRec)Line(hdc, a, b);
  729.     else{
  730.         Point t = (b - a)*(1. / 3.), l = t.rotA(108.), r=t.rotA(72.), rr= r.rotA(72.);
  731.         draw1(hdc, a, a + t);
  732.         // draw2(hdc, a+t, b+t);
  733.         draw1(hdc, b-t, b);
  734.         draw1(hdc, a + t, a + t + l);
  735.         draw1(hdc, b - t, b - t + r);
  736. //      draw1(hdc, a, a + t);
  737. //      draw1(hdc, a, a + t);
  738. //      draw1(hdc, a, a + t);
  739.  
  740.     }
  741.     rec--;
  742. }
  743.  
  744. void draw2(HDC hdc, Point a, Point b){
  745.     static int rec = 0; rec++;
  746.     if (rec>maxRec)Line(hdc, a, b);
  747.     else{
  748.         double tt = tan(PI / 6.);
  749.         Point t = (b - a)*0.5, n = (t*tt).rotL(), c = a + t + n;
  750.         draw2(hdc, a, c);
  751.         draw2(hdc, b, c);
  752.     }
  753.     rec--;
  754. }
  755.  
  756. void draw3(HDC hdc, Point a, Point b){
  757.     static int rec = 0; rec++;
  758.     if (rec>maxRec)Line(hdc, a, b);
  759.     else{
  760.         Point t = (b - a)*0.25, l = t.rotA(60.), r = t.rotA(90.);
  761. //      draw3(hdc, a, c);
  762. //      draw3(hdc, b, c);
  763.     }
  764.     rec--;
  765. }
  766.  
  767.  
  768. void redrawAll(HWND hwnd){
  769.     HDC hdc; RECT rect; PAINTSTRUCT ps;
  770.     TCHAR txt[30];
  771.     wsprintf(txt, L"Дълбочина на рекурсията: %i ", maxRec);
  772.     hdc = BeginPaint(hwnd, &ps);
  773.     GetClientRect(hwnd, &rect);
  774.     DrawText(hdc, txt, -1, &rect, DT_SINGLELINE | DT_TOP | DT_LEFT);
  775.  
  776.     Point cen((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2);
  777.     cen = cen*(1 / scale);
  778.     switch (toDraw){
  779.     case 0:{
  780.         DrawText(hdc, L"Крива на Peano: Up/Down за дълбочина"
  781.             L" , Left/Right за цвят, Home/End = смяна.", -1,
  782.             &rect, DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  783.         Point a(-1, 0), b(1, 0); a = a + cen; b = b + cen;
  784.         drawPeano(hdc, a, b);
  785.     }break;
  786.     case 1:{
  787.         DrawText(hdc, L"Крива на Peano: Up/Down за дълбочина"
  788.             L" , Left/Right за цвят, Home/End = смяна.", -1,
  789.             &rect, DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  790.         Point a(-1, 0), b(1, 0); a = a + cen; b = b + cen;
  791.         drawPeano(hdc, a, b);
  792.     }break;
  793.     case 2:{
  794.         DrawText(hdc, L"Крива на Gosper: Up/Down за дълбочина"
  795.             L" , Left/Right за цвят, Home/End = смяна.", -1,
  796.             &rect, DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  797.         Point a(-2, 1), b(2, 1); a = a + cen; b = b + cen;
  798.         drawGosper(hdc, a, b);
  799.     }break;
  800.     case 3:{
  801.         DrawText(hdc, L"Дракон на Harter: Up/Down за дълбочина"
  802.             L" , Left/Right за цвят, Home/End = смяна.", -1,
  803.             &rect, DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  804.         Point a(-2, 0), b(2, 0); a = a + cen; b = b + cen;
  805.         drawHarter(hdc, a, b);
  806.     }break;
  807.     case 4:{
  808.         DrawText(hdc, L"Крива на Sierpinsky: Up/Down за дълбочина"
  809.             L" , Left/Right за цвят, Home/End = смяна.", -1,
  810.             &rect, DT_SINGLELINE | DT_BOTTOM | DT_LEFT);
  811.         Point a(-2, -2), b(2, -2); a = a + cen; b = b + cen;
  812.         drawSerp(hdc, a, b);
  813.     }
  814.     }
  815.     EndPaint(hwnd, &ps);
  816. }
  817. inline void swap(int &p, int &q){ int t = p; p = q; q = t; }
  818.  
  819. void lineBres(HDC hdc, POINT p1, POINT p2, COLORREF c){
  820.     int x0 = p1.x, y0 = p1.y, x1 = p2.x, y1 = p2.y;
  821.     bool str = abs(y1 - y0)>abs(x1 - x0);
  822.     if (str)  { swap(x0, y0); swap(x1, y1); }
  823.     if (x0>x1){ swap(x0, x1); swap(y0, y1); }
  824.     int dx = x1 - x0, dy = abs(y1 - y0), err = 0, y = y0;
  825.     int yst = y0<y1 ? 1 : -1;
  826.     for (int x = x0; x <= x1; x++){
  827.         if (str) SetPixel(hdc, y, x, c);
  828.         else    SetPixel(hdc, x, y, c);
  829.         err += dy;
  830.         if (2 * err >= dx){ y += yst; err -= dx; }
  831.     }
  832. }
  833.  
  834.  
  835.  
  836.  
  837.  
  838. }
Advertisement
Add Comment
Please, Sign In to add comment