Guest User

Floral_Gaf_Submission

a guest
Jul 1st, 2012
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.57 KB | None | 0 0
  1. // Compiled and tested with Microsoft Visual C++ 2010 Express.  
  2. // To run this, you'll need to setup your own Win32 Project.
  3. // 1) First step is to create a new project:  click on File->New->Project
  4. // 2) Make sure the Win32 template is set and Select Win32 Project.  Set the name to floral_pattern and the location wherever you'd like
  5. // 3) For your setting, Make sure the Application type is set to "Windows Application".   Hit finished
  6. // 4) Copy and paste this file into floral_pattern.cpp
  7. // 5) Compile and execute the program
  8. //
  9. // When the window is up, press a key to have it redraw at a different time of year/day
  10.  
  11. #include "stdafx.h"
  12. #include <math.h>
  13. #include "floral_pattern.h"
  14.  
  15. #define MAX_LOADSTRING 100
  16.  
  17. // Global Variables:
  18. HINSTANCE hInst;                                // current instance
  19. TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
  20. TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
  21.  
  22. // Forward declarations of functions included in this code module:
  23. ATOM                MyRegisterClass(HINSTANCE hInstance);
  24. BOOL                InitInstance(HINSTANCE, int);
  25. LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
  26. INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
  27.  
  28. const int WINDOW_WIDTH = 1600;
  29. const int WINDOW_HEIGHT = 800;
  30.  
  31. enum Seasons
  32. {
  33.     SUMMER,
  34.     SUMMER_NIGHT,
  35.     AUTUMN,
  36.     AUTUMN_NIGHT,
  37.     WINTER,
  38.     WINTER_NIGHT,
  39.     NUMBER_OF_SEASONS
  40. };
  41.  
  42. int currentSeason = SUMMER;
  43.  
  44. struct vec2
  45. {
  46.     vec2( const float initX, const float initY )
  47.     {
  48.         x = initX;
  49.         y = initY;
  50.     }
  51.  
  52.     void Rotate( const float angle )
  53.     {
  54.         const float rad = angle * ( 3.14159265f / 180.0f );
  55.         const float cosAngle = cos( rad );
  56.         const float sinAngle = sin( rad );
  57.  
  58.         float newX = ( x * cosAngle ) + ( y * sinAngle );
  59.         float newY = ( x * -sinAngle ) + ( y * cosAngle );
  60.         float len = sqrt( newX * newX + newY * newY );
  61.  
  62.         x = newX / len;
  63.         y = newY / len;
  64.     }
  65.  
  66.     float x, y;
  67. };
  68.  
  69. struct PenList
  70. {
  71.     HPEN stemPen;
  72.     HPEN foliagePen1;
  73.     HPEN foliagePen2;
  74. };
  75.  
  76. // draws a line
  77. void FloraLine( HDC hdc, HPEN pen, const float startX, const float startY, const float endX, const float endY )
  78. {
  79.     SelectObject( hdc, pen );
  80.     MoveToEx( hdc, (int)startX, (int)startY, NULL );
  81.     LineTo( hdc, (int)endX, (int)endY );
  82. }
  83.  
  84. // recursively draws a leaf
  85. void LeafRecurse( HDC hdc, int recursionlevel, const float smallestLength, const float leafLength, const float branchAngle, const vec2 & pos, const vec2 & dir, float length, HPEN foliagePen, HPEN stemPen )
  86. {
  87.     if ( length < smallestLength )
  88.     {
  89.         return;
  90.     }
  91.  
  92.     // Draw the current stem
  93.     vec2 currentBranchEnd( pos );
  94.     currentBranchEnd.x += dir.x * length;
  95.     currentBranchEnd.y += dir.y * length;
  96.  
  97.     FloraLine( hdc, stemPen, pos.x, pos.y, currentBranchEnd.x, currentBranchEnd.y );
  98.  
  99.     // recursively draw an off shoot
  100.     vec2 sideBranch( pos );
  101.     sideBranch.x += ( dir.x * length * 0.5f );
  102.     sideBranch.y += ( dir.y * length * 0.5f );
  103.  
  104.     vec2 sideBranchDir( dir );
  105.     if ( ( recursionlevel & 1 ) == 0 )
  106.     {
  107.         sideBranchDir.Rotate( branchAngle * 5 );
  108.         LeafRecurse( hdc, recursionlevel + 1, leafLength, leafLength, branchAngle, sideBranch, sideBranchDir, length * 0.7f, foliagePen, foliagePen );
  109.     }
  110.     else
  111.     {
  112.         sideBranchDir.Rotate( -branchAngle * 5 );
  113.         LeafRecurse( hdc, recursionlevel + 1, leafLength, leafLength, branchAngle, sideBranch, sideBranchDir, length * 0.7f, foliagePen, foliagePen );
  114.     }
  115.  
  116.     // continue drawing the current stem
  117.     vec2 nextStemBranchDir( dir );
  118.     nextStemBranchDir.Rotate( branchAngle );
  119.     LeafRecurse( hdc, recursionlevel + 1, smallestLength, leafLength, branchAngle, currentBranchEnd, nextStemBranchDir, length * 0.9f, foliagePen, stemPen );
  120. }
  121.  
  122. // recursively draws a tree
  123. void TreeRecurse( HDC hdc, const float smallestLength, const float leafLength, const vec2 & position, const vec2 & direction, float length, const PenList & penList )
  124. {
  125.     if ( length < smallestLength )
  126.     {
  127.         // leaves, alternate colors
  128.         return;
  129.     }
  130.  
  131.     // draw the current stem
  132.     vec2 currentBranchEnd( position );
  133.     currentBranchEnd.x += ( direction.x * length );
  134.     currentBranchEnd.y += ( direction.y * length );
  135.     float childBranchLen = length / 1.2f;
  136.  
  137.     if ( length > leafLength )
  138.     {
  139.         FloraLine( hdc, penList.stemPen, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
  140.     }
  141.     else
  142.     {
  143.         if ( rand() % 3 )
  144.         {
  145.             FloraLine( hdc, penList.foliagePen1, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
  146.         }
  147.         else
  148.         {
  149.             FloraLine( hdc, penList.foliagePen2, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
  150.         }
  151.     }
  152.  
  153.     // left branch
  154.     vec2 secondBranchDir( direction );
  155.     secondBranchDir.Rotate( 25 + ( ( rand() % 10 ) - 5.0f ) );
  156.     TreeRecurse( hdc, smallestLength, leafLength, currentBranchEnd, secondBranchDir, childBranchLen, penList );
  157.  
  158.     // right branch
  159.     vec2 thirdBranchDir( direction );
  160.     thirdBranchDir.Rotate( -25 + ( ( rand() % 10 ) - 5.0f ) );
  161.     TreeRecurse( hdc, smallestLength, leafLength, currentBranchEnd, thirdBranchDir, childBranchLen, penList );
  162. }
  163.  
  164. // main entry point for drawing
  165. void FloraMain( HDC hdc )
  166. {
  167.     HPEN whitePen  = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
  168.     HPEN stemPen;
  169.     HPEN foliagePen;
  170.     HPEN redLeafPen;
  171.     HPEN yellowLeafPen;
  172.     HPEN snowPen;
  173.  
  174.     HBRUSH blueBrush = CreateSolidBrush( RGB( 100, 195, 253 ) );
  175.     HBRUSH yellowBrush = CreateSolidBrush( RGB( 255, 255, 0 ) );
  176.     HBRUSH whiteBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
  177.     HBRUSH blackBrush = CreateSolidBrush( RGB( 0, 0, 0 ) );
  178.     HBRUSH foliageBrush;
  179.     HBRUSH snowBrush;
  180.     HBRUSH redBrush;
  181.  
  182.     if ( currentSeason != SUMMER_NIGHT && currentSeason != AUTUMN_NIGHT && currentSeason != WINTER_NIGHT )
  183.     {
  184.         redLeafPen = CreatePen( PS_SOLID, 1, RGB( 252, 178, 0 ) );
  185.         snowPen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
  186.         yellowLeafPen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 0 ) );
  187.         stemPen = CreatePen( PS_SOLID, 1, RGB( 185, 122, 87 ) );
  188.  
  189.         snowBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
  190.         redBrush = CreateSolidBrush( RGB( 252, 178, 0 ) );
  191.        
  192.         if ( currentSeason != WINTER )
  193.         {
  194.             foliageBrush = CreateSolidBrush( RGB( 0, 128, 0 ) );
  195.             foliagePen = CreatePen( PS_SOLID, 1, RGB( 0, 128, 0 ) );
  196.         }
  197.         else
  198.         {
  199.             foliageBrush = whiteBrush;
  200.             foliagePen = snowPen;
  201.         }
  202.  
  203.         // draw sky
  204.         RECT box;
  205.         box.bottom = 600;
  206.         box.top = 0;
  207.         box.left = 0;
  208.         box.right = 1600;
  209.         FillRect( hdc, &box, blueBrush );
  210.  
  211.         // draw sun
  212.         SelectObject( hdc, yellowBrush );
  213.         Ellipse( hdc, 250, 50, 350, 150 );
  214.  
  215.         // draw sun beams
  216.         const vec2 sunLocation( 300.0f, 100.0f );
  217.         vec2 sunBeamDirection( 0.0f, 1.0f );
  218.         for ( int i = 0; i < 36; i++ )
  219.         {
  220.             sunBeamDirection.Rotate( 10.0f );
  221.             FloraLine( hdc, yellowLeafPen, sunLocation.x + ( sunBeamDirection.x * 55 ), sunLocation.y + ( sunBeamDirection.y * 55 ), sunLocation.x + ( sunBeamDirection.x * 85 ), sunLocation.y + ( sunBeamDirection.y * 85 ) );
  222.         }
  223.     }
  224.     else
  225.     {
  226.         const int darken = 2;
  227.         stemPen = CreatePen( PS_SOLID, 1, RGB( 185 >> darken, 122 >> darken, 87 >> darken ) );
  228.         yellowLeafPen = CreatePen( PS_SOLID, 1, RGB( 255 >> darken, 255 >> darken, 0 ) );
  229.         snowPen = CreatePen( PS_SOLID, 1, RGB( 255 >> 2, 255 >> 2, 255 >> darken ) );
  230.         redLeafPen = CreatePen( PS_SOLID, 1, RGB( 252 >> darken, 178 >> darken, 0 ) );
  231.  
  232.         redBrush = CreateSolidBrush( RGB( 252 >> darken, 178 >> darken, 0 ) );
  233.         snowBrush = CreateSolidBrush( RGB( 255 >> darken, 255 >> darken, 255 >> darken ) );
  234.  
  235.         if ( currentSeason != WINTER_NIGHT )
  236.         {
  237.             foliageBrush = CreateSolidBrush( RGB( 0, 32, 0 ) );
  238.             foliagePen = CreatePen( PS_SOLID, 1, RGB( 0, 32, 0 ) );
  239.         }
  240.         else
  241.         {
  242.             foliageBrush = whiteBrush;
  243.             foliagePen = snowPen;
  244.         }
  245.  
  246.         // draw sky
  247.         RECT box;
  248.         box.bottom = 600;
  249.         box.top = 0;
  250.         box.left = 0;
  251.         box.right = 1600;
  252.         FillRect( hdc, &box, blackBrush );
  253.  
  254.         // moon
  255.         SelectObject( hdc, whiteBrush );
  256.         Ellipse( hdc, 250, 50, 350, 150 );
  257.  
  258.         // stars
  259.         vec2 starPositions[] = { vec2( 50, 50 ), vec2( 200, 200 ), vec2( 400, 150 ), vec2( 500, 75 ), vec2( 725, 85 ),
  260.             vec2( 800, 25 ), vec2( 1200, 75 ), vec2( 1400, 100 ), vec2( 900, 125 ), vec2( 1300, 170 ), vec2( 69, 160 ),
  261.             vec2( 610, 165 ), vec2( 1069, 109 ), vec2( 1510, 200 ) };
  262.  
  263.         for ( int i = 0; i < 14; i++ )
  264.         {
  265.             FloraLine( hdc, whitePen, starPositions[i].x + 0, starPositions[i].y + 0, starPositions[i].x - 2, starPositions[i].y + 7 );
  266.             FloraLine( hdc, whitePen, starPositions[i].x - 2, starPositions[i].y + 7, starPositions[i].x + 3, starPositions[i].y + 2 );
  267.             FloraLine( hdc, whitePen, starPositions[i].x + 3, starPositions[i].y + 2, starPositions[i].x - 3, starPositions[i].y + 2 );
  268.             FloraLine( hdc, whitePen, starPositions[i].x - 3, starPositions[i].y + 2, starPositions[i].x + 2, starPositions[i].y + 7 );
  269.             FloraLine( hdc, whitePen, starPositions[i].x + 2, starPositions[i].y + 7, starPositions[i].x + 0, starPositions[i].y + 0 );
  270.         }
  271.     }
  272.  
  273.     // draw ground
  274.     RECT box;
  275.     box.left = 0;
  276.     box.right = 1600;
  277.     box.bottom = 800;
  278.     box.top = 600;
  279.  
  280.     PenList penList;
  281.  
  282.     if ( currentSeason == AUTUMN || currentSeason == AUTUMN_NIGHT )
  283.     {
  284.         penList.foliagePen1 = yellowLeafPen;
  285.         penList.foliagePen2 = redLeafPen;
  286.         FillRect( hdc, &box, redBrush );
  287.     }
  288.     else if ( currentSeason == WINTER || currentSeason == WINTER_NIGHT )
  289.     {
  290.         penList.foliagePen1 = foliagePen;
  291.         penList.foliagePen2 = foliagePen;
  292.         FillRect( hdc, &box, snowBrush );
  293.     }
  294.     else
  295.     {
  296.         penList.foliagePen1 = foliagePen;
  297.         penList.foliagePen2 = foliagePen;
  298.         FillRect( hdc, &box, foliageBrush );
  299.     }
  300.     penList.stemPen = stemPen;
  301.  
  302.     // trees
  303.     TreeRecurse( hdc, 10, 20, vec2( 700.0f, 600.0f ), vec2( 0.0f, -1.0f ), 80.0f, penList );
  304.     TreeRecurse( hdc, 5, 15, vec2( 200.0f, 600.0f ), vec2( 0.0f, -1.0f ), 40.0f, penList );
  305.  
  306.     // more trees
  307.     LeafRecurse( hdc, 0, 5,4, 5.0f, vec2( 1200, 600 ), vec2( 0.0f, -1.0f ), 40.0f, penList.foliagePen1, stemPen );
  308.     LeafRecurse( hdc, 0, 5,4, 3.0f, vec2( 1400, 600 ), vec2( 0.0f, -1.0f ), 35.0f, penList.foliagePen2, stemPen );
  309.  
  310.     DeleteObject( stemPen );
  311.     DeleteObject( foliagePen );
  312.     DeleteObject( redLeafPen );
  313.     DeleteObject( yellowLeafPen );
  314.     DeleteObject( whitePen );
  315.     DeleteObject( snowPen );
  316.  
  317.     DeleteObject( blueBrush );
  318.     DeleteObject( foliageBrush );
  319.     DeleteObject( yellowBrush );
  320.     DeleteObject( whiteBrush );
  321.     DeleteObject( blackBrush );
  322.     DeleteObject( snowBrush );
  323.     DeleteObject( redBrush );
  324. }
  325.  
  326. int APIENTRY _tWinMain(HINSTANCE hInstance,
  327.                      HINSTANCE hPrevInstance,
  328.                      LPTSTR    lpCmdLine,
  329.                      int       nCmdShow)
  330. {
  331.     UNREFERENCED_PARAMETER(hPrevInstance);
  332.     UNREFERENCED_PARAMETER(lpCmdLine);
  333.  
  334.     // TODO: Place code here.
  335.     MSG msg;
  336.     HACCEL hAccelTable;
  337.  
  338.     // Initialize global strings
  339.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  340.     LoadString(hInstance, IDC_FLORAL_PATTERN, szWindowClass, MAX_LOADSTRING);
  341.     MyRegisterClass(hInstance);
  342.  
  343.     // Perform application initialization:
  344.     if (!InitInstance (hInstance, nCmdShow))
  345.     {
  346.         return FALSE;
  347.     }
  348.  
  349.     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FLORAL_PATTERN));
  350.  
  351.     // Main message loop:
  352.     while (GetMessage(&msg, NULL, 0, 0))
  353.     {
  354.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  355.         {
  356.             TranslateMessage(&msg);
  357.             DispatchMessage(&msg);
  358.         }
  359.     }
  360.  
  361.     return (int) msg.wParam;
  362. }
  363.  
  364.  
  365.  
  366. //
  367. //  FUNCTION: MyRegisterClass()
  368. //
  369. //  PURPOSE: Registers the window class.
  370. //
  371. //  COMMENTS:
  372. //
  373. //    This function and its usage are only necessary if you want this code
  374. //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
  375. //    function that was added to Windows 95. It is important to call this function
  376. //    so that the application will get 'well formed' small icons associated
  377. //    with it.
  378. //
  379. ATOM MyRegisterClass(HINSTANCE hInstance)
  380. {
  381.     WNDCLASSEX wcex;
  382.  
  383.     wcex.cbSize = sizeof(WNDCLASSEX);
  384.  
  385.     wcex.style          = CS_HREDRAW | CS_VREDRAW;
  386.     wcex.lpfnWndProc    = WndProc;
  387.     wcex.cbClsExtra     = 0;
  388.     wcex.cbWndExtra     = 0;
  389.     wcex.hInstance      = hInstance;
  390.     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FLORAL_PATTERN));
  391.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  392.     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  393.     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_FLORAL_PATTERN);
  394.     wcex.lpszClassName  = szWindowClass;
  395.     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  396.  
  397.     return RegisterClassEx(&wcex);
  398. }
  399.  
  400. //
  401. //   FUNCTION: InitInstance(HINSTANCE, int)
  402. //
  403. //   PURPOSE: Saves instance handle and creates main window
  404. //
  405. //   COMMENTS:
  406. //
  407. //        In this function, we save the instance handle in a global variable and
  408. //        create and display the main program window.
  409. //
  410. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  411. {
  412.    HWND hWnd;
  413.  
  414.    hInst = hInstance; // Store instance handle in our global variable
  415.  
  416.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  417.       0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
  418.  
  419.    if (!hWnd)
  420.    {
  421.       return FALSE;
  422.    }
  423.  
  424.    ShowWindow(hWnd, nCmdShow);
  425.    UpdateWindow(hWnd);
  426.  
  427.    return TRUE;
  428. }
  429.  
  430. //
  431. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  432. //
  433. //  PURPOSE:  Processes messages for the main window.
  434. //
  435. //  WM_COMMAND  - process the application menu
  436. //  WM_PAINT    - Paint the main window
  437. //  WM_DESTROY  - post a quit message and return
  438. //
  439. //
  440. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  441. {
  442.     int wmId, wmEvent;
  443.     PAINTSTRUCT ps;
  444.     HDC hdc;
  445.  
  446.     switch (message)
  447.     {
  448.     case WM_KEYDOWN:
  449.         {
  450.         RECT rect;
  451.         rect.left = 0;
  452.         rect.top = 0;
  453.         rect.right = WINDOW_WIDTH;
  454.         rect.bottom = WINDOW_HEIGHT;
  455.         InvalidateRect( hWnd, &rect, true );
  456.         break;
  457.         }
  458.     case WM_COMMAND:
  459.         wmId    = LOWORD(wParam);
  460.         wmEvent = HIWORD(wParam);
  461.         // Parse the menu selections:
  462.         switch (wmId)
  463.         {
  464.         case IDM_ABOUT:
  465.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  466.             break;
  467.         case IDM_EXIT:
  468.             DestroyWindow(hWnd);
  469.             break;
  470.         default:
  471.             return DefWindowProc(hWnd, message, wParam, lParam);
  472.         }
  473.         break;
  474.     case WM_PAINT:
  475.         hdc = BeginPaint(hWnd, &ps);
  476.  
  477.         FloraMain( hdc );
  478.  
  479.         EndPaint(hWnd, &ps);
  480.  
  481.         currentSeason++;
  482.         if ( currentSeason >= NUMBER_OF_SEASONS )
  483.         {
  484.             currentSeason = SUMMER;
  485.         }
  486.         break;
  487.     case WM_DESTROY:
  488.         PostQuitMessage(0);
  489.         break;
  490.     default:
  491.         return DefWindowProc(hWnd, message, wParam, lParam);
  492.     }
  493.     return 0;
  494. }
  495.  
  496. // Message handler for about box.
  497. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  498. {
  499.     UNREFERENCED_PARAMETER(lParam);
  500.     switch (message)
  501.     {
  502.     case WM_INITDIALOG:
  503.         return (INT_PTR)TRUE;
  504.  
  505.     case WM_COMMAND:
  506.         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  507.         {
  508.             EndDialog(hDlg, LOWORD(wParam));
  509.             return (INT_PTR)TRUE;
  510.         }
  511.         break;
  512.     }
  513.     return (INT_PTR)FALSE;
  514. }
Advertisement
Add Comment
Please, Sign In to add comment