Guest User

math failure on msvc++ release mode

a guest
Nov 8th, 2014
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.91 KB | None | 0 0
  1. // math_failure.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <memory.h>
  7. #include <math.h>
  8.  
  9. #ifdef __GNUC__
  10.     // gcc
  11.     #include <stdint.h>
  12.  
  13.     typedef uint64_t            u64;
  14.     typedef uint32_t            u32;
  15.     typedef uint16_t            u16;
  16.     typedef uint8_t             u8;
  17.  
  18.     typedef int64_t             s64;
  19.     typedef int32_t             s32;
  20.     typedef int16_t             s16;
  21.     typedef int8_t              s8;
  22. #else
  23.     typedef unsigned __int64    u64;
  24.     typedef unsigned int        u32;
  25.     typedef unsigned short      u16;
  26.     typedef unsigned char       u8;
  27.  
  28.     // Signed
  29.     typedef __int64             s64;
  30.     typedef int                 s32;
  31.     typedef short               s16;
  32.     typedef char                s8;
  33. #endif
  34.  
  35. typedef u16 WORD;
  36. typedef u32 DWORD;
  37. typedef s32 LONG;
  38.  
  39. #ifndef bool
  40.     typedef int bool;
  41. #endif
  42.  
  43. #ifndef true
  44.     #define true 1
  45. #endif
  46.  
  47. #ifndef false
  48.     #define false 0
  49. #endif
  50.  
  51. #ifndef min
  52.     #define min(a,b) ((a <= b) ? a : b)
  53. #endif
  54.  
  55. #ifndef max
  56.     #define max(a,b) ((a >= b) ? a : b)
  57. #endif
  58.  
  59. // Floating point
  60. typedef     float               f32;
  61. typedef     double              f64;
  62.  
  63. // Constant signed
  64. typedef     const s8            cs8;
  65. typedef     const s16           cs16;
  66. typedef     const s32           cs32;
  67. typedef     const s64           cs64;
  68.  
  69. // Constant unsigned
  70. typedef     const u8            cu8;
  71. typedef     const u16           cu16;
  72. typedef     const u32           cu32;
  73. typedef     const u64           cu64;
  74.  
  75. // Constant floating point
  76. typedef     const f64           cf64;
  77. typedef     const f64           cf64;
  78.  
  79. typedef struct tagBmpFileHeader {
  80.     WORD    bfType;
  81.     DWORD   bfSize;
  82.     WORD    bfReserved1;
  83.     WORD    bfReserved2;
  84.     DWORD   bfOffBits;
  85. } BFH;
  86.  
  87. typedef struct tagBmpInfoHeader {
  88.     DWORD      biSize;
  89.     LONG       biWidth;
  90.     LONG       biHeight;
  91.     WORD       biPlanes;
  92.     WORD       biBitCount;
  93.     DWORD      biCompression;
  94.     DWORD      biSizeImage;
  95.     LONG       biXPelsPerMeter;
  96.     LONG       biYPelsPerMeter;
  97.     DWORD      biClrUsed;
  98.     DWORD      biClrImportant;
  99. } BIH;
  100.  
  101. typedef struct SBmp
  102. {
  103.     // Raw bitmap data (suitable for writing to disk)
  104.     BFH         bh;
  105.     BIH         bi;
  106.     s8*         bd;
  107.     u32         rowWidth;
  108. } SBitmap;
  109.  
  110. typedef struct SF32
  111. {
  112.     f32         x;
  113.     f32         y;
  114. } SXYF32;
  115.  
  116. typedef struct SS32
  117. {
  118.     s32         x;
  119.     s32         y;
  120. } SXYS32;
  121.  
  122. typedef struct SLF32
  123. {
  124.     union {
  125.         SXYF32  start;                      // [input] Starting point
  126.         SXYF32  p1;
  127.     };
  128.  
  129.     union {
  130.         SXYF32  end;                        // [input] Ending point
  131.         SXYF32  p2;
  132.     };
  133.  
  134.     // The following are computed with vvm_math_computeLine()
  135.     SXYF32      delta;                      // Delta between start and end
  136.     SXYF32      mid;                        // Midpoint
  137.     union {
  138.         f32     length;                     // Length
  139.         f32     radius;                     // Radius for the trig function
  140.     };
  141.     f32         m;                          // Slope
  142.     f32         mp;                         // Perpendicular slope
  143.  
  144.     // Only used and computed if trig is true
  145.     bool        trig;                       // Should trig functions be computed?
  146.     f32         theta;                      // Theta (from p1 to p2, note: add _PI to reverse the angle from p2 to p1)
  147.  
  148.     // Only used and computed if ints is true
  149.     bool        ints;                       // Should integer approximations be calculated?
  150.     union {
  151.         SXYS32  starti;                     // Starting x,y
  152.         SXYS32  p1i;
  153.     };
  154.     union {
  155.         SXYS32  endi;                       // Ending x,y
  156.         SXYS32  p2i;
  157.     };
  158.  
  159.     // Only used and computed if quads is true
  160.     bool        quads;                      // Should we compute quadrants?
  161.     union {
  162.         s32     start_quad;                 // What quadrant is start/p1 in?
  163.         s32     p1_quad;
  164.     };
  165.     union {
  166.         s32     end_quad;                   // What quadrant is end/p2 in?
  167.         s32     p2_quad;
  168.     };
  169. } SLineF32;
  170.  
  171. typedef struct sb
  172. {
  173.     u8  blu;
  174.     u8  grn;
  175.     u8  red;
  176. } SBgr;
  177.  
  178. typedef struct Sba
  179. {
  180.     union {
  181.         u32     color;
  182.         struct {
  183.             u8  blu;
  184.             u8  grn;
  185.             u8  red;
  186.             u8  alp;
  187.         };
  188.     };
  189. } SBgra;
  190.  
  191. SBgra blackColor;
  192.  
  193.  
  194.  
  195.  
  196. //////////
  197. //
  198. // Computes the row width of the pixels using BGR format (3 bytes per pixel) then rounded up to
  199. // the nearest DWORD.
  200. //
  201. //////
  202.     s32 iBmp_computeRowWidth(SBitmap* bmp)
  203.     {
  204.         s32 lnWidth;
  205.  
  206.  
  207.         // Make sure our environment is sane
  208.         if (bmp)
  209.         {
  210.             // See the bit counts
  211.             if (bmp->bi.biBitCount == 24)
  212.             {
  213.                 // 24-bit formats are rounded up to nearest DWORD
  214.                 lnWidth = bmp->bi.biWidth * 3;
  215.                 if (lnWidth % 4 == 0)
  216.                     return(lnWidth);
  217.  
  218.                 // Increase the width
  219.                 lnWidth += (4 - (lnWidth % 4));
  220.                 return(lnWidth);
  221.  
  222.  
  223.             } else if (bmp->bi.biBitCount == 32) {
  224.                 // 32-bit formats are also DWORD aligned, but naturally, of course. :-)
  225.                 return(bmp->bi.biWidth * 4);
  226.  
  227.  
  228.             } else {
  229.                 // Uh oh, spaghetti-oh!
  230.                 return(bmp->bi.biSizeImage / bmp->bi.biHeight);
  231.             }
  232.         }
  233.  
  234.         // Invalid
  235.         return(0);
  236.     }
  237.  
  238.  
  239.  
  240.  
  241. //////////
  242. //
  243. // Called to create an empty bitmap
  244. //
  245. //////
  246.     void iBmp_populateBitmapStructure(SBitmap* bmp, u32 tnWidth, u32 tnHeight, u32 tnBitCount)
  247.     {
  248.         if (bmp)
  249.         {
  250.             memset(&bmp->bi, 0, sizeof(bmp->bi));
  251.             bmp->bi.biSize              = sizeof(bmp->bi);
  252.             bmp->bi.biWidth             = tnWidth;
  253.             bmp->bi.biHeight            = tnHeight;
  254.             bmp->bi.biCompression       = 0;
  255.             bmp->bi.biPlanes            = 1;
  256.             bmp->bi.biBitCount          = (u16)((tnBitCount == 24 || tnBitCount == 32) ? tnBitCount : 24);
  257.             bmp->bi.biXPelsPerMeter     = 2835; // Assume 72 dpi
  258.             bmp->bi.biYPelsPerMeter     = 2835;
  259.             bmp->rowWidth               = iBmp_computeRowWidth(bmp);
  260.             bmp->bi.biSizeImage         = bmp->rowWidth * tnHeight;
  261.  
  262.             memset(&bmp->bh, 0, sizeof(bmp->bh));
  263.             bmp->bh.bfType              = 0x4d42;   // BM file prefix
  264.             bmp->bh.bfOffBits           = sizeof(bmp->bh) + sizeof(bmp->bi);
  265.             bmp->bh.bfSize              = bmp->bh.bfOffBits + bmp->bi.biSizeImage;
  266.         }
  267.     }
  268.  
  269.  
  270.  
  271.  
  272. //////////
  273. //
  274. // Called to create a basic bitmap by the indicated size, and initially populate it to white
  275. //
  276. //////
  277.     void iBmp_createBySize(SBitmap* bmp, u32 width, u32 height, u32 tnBitCount)
  278.     {
  279.         if (bmp)
  280.         {
  281.             // Populate the initial structure (min of 1x1, max of 7680x4320 (4x 1920x1080)
  282.             iBmp_populateBitmapStructure(bmp, min(max(width, 1), 7680), min(max(height, 1), 4320), tnBitCount);
  283.  
  284.             // Create the HDC and DIB Section
  285.             bmp->bd = (s8*)malloc(bmp->bi.biSizeImage);
  286.  
  287.             // Paint it white initially (the fast/easy way)
  288.             if (bmp->bd)
  289.                 memset(bmp->bd, 255, bmp->bi.biSizeImage);
  290.         }
  291.     }
  292.  
  293.  
  294.  
  295.  
  296. //////////
  297. // Allocates a new structure
  298. //////
  299.     SBitmap* iBmp_allocate(u32 width, u32 height, u32 tnBitCount)
  300.     {
  301.         SBitmap* bmp;
  302.  
  303.  
  304.         // Allocate our new structure
  305.         bmp = (SBitmap*)malloc(sizeof(SBitmap));
  306.  
  307.         // Initialize if successful
  308.         if (bmp)
  309.             iBmp_createBySize(bmp, width, height, tnBitCount);
  310.  
  311.         // Indicate our success or failure
  312.         return(bmp);
  313.     }
  314.  
  315.  
  316.  
  317.  
  318. //////////
  319. //
  320. // Adjusts theta into the 0..2pi range
  321. //
  322. //////
  323. #ifndef M_PI
  324.     #define M_PI 3.14159265358979323846
  325. #endif
  326.     const f32 _2PI = (f32)M_PI * 2.0f;  // 2 * pi
  327.  
  328.     f32 iivvm_math_adjustTheta(f32 tfTheta)
  329.     {
  330.         // Validate theta is positive
  331.         while (tfTheta < 0.0)
  332.             tfTheta += _2PI;
  333.  
  334.         // Validate theta is 0..2pi
  335.         while (tfTheta > _2PI)
  336.             tfTheta -= _2PI;
  337.  
  338.         return(tfTheta);
  339.     }
  340.  
  341.  
  342.  
  343.  
  344. //////////
  345. //
  346. // Determines the quandrant of the point
  347. //
  348. //////
  349.     s32 iivvm_math_computeQuadrant(SXYF32* p)
  350.     {
  351.         if (p->x >= 0.0)
  352.         {
  353.             // Either 1 or 4
  354.             if (p->y >= 0.0)        return(1);      // X is positive, Y is positive
  355.             else                    return(4);      // X is positive, Y is negative
  356.  
  357.         } else {
  358.             // Either 2 or 3
  359.             if (p->y >= 0.0)        return(2);      // X is negative, Y is positive
  360.             else                    return(3);      // X is negative, Y is negative
  361.         }
  362.     }
  363.  
  364.     void iivvm_math_computeLine(SLineF32* line)
  365.     {
  366.         // Midpoint = (x2-x1)/2, (y2-y1)/2
  367.         line->mid.x     = (line->p1.x + line->p2.x) / 2.0f;
  368.         line->mid.y     = (line->p1.y + line->p2.y) / 2.0f;
  369.  
  370.         // Compute our deltas
  371.         line->delta.x   = line->p2.x - line->p1.x;
  372.         line->delta.y   = line->p2.y - line->p1.y;
  373.  
  374.         // Length
  375.         line->length    = (f32)sqrt(line->delta.x*line->delta.x + line->delta.y*line->delta.y);
  376.  
  377.         // Slope = rise over run
  378.         line->m         = line->delta.y / ((line->delta.x == 0.0f) ? 0.000001f : line->delta.x);
  379.  
  380.         // Perpendicular slope = -1/m
  381.         line->mp        = -1.0f / ((line->m == 0.0) ? 0.000001f : line->m);
  382.  
  383.  
  384.         //////////
  385.         // Compute theta if need be (radius is same as length)
  386.         /////
  387.             if (line->trig)
  388.                 line->theta     = iivvm_math_adjustTheta((f32)atan2(line->delta.y, line->delta.x));
  389.  
  390.  
  391.         //////////
  392.         // Compute the integer roundings if need be
  393.         //////
  394.             if (line->ints)
  395.             {
  396.                 // Start
  397.                 line->p1i.x     = (s32)line->p1.x;
  398.                 line->p1i.y     = (s32)line->p1.y;
  399.                 // End
  400.                 line->p2i.x     = (s32)line->p2.x;
  401.                 line->p2i.y     = (s32)line->p2.y;
  402.             }
  403.  
  404.  
  405.         //////////
  406.         // Compute the quadrants if need be
  407.         //////
  408.             if (line->quads)
  409.             {
  410.                 // Quads 1..4
  411.                 line->p1_quad   = iivvm_math_computeQuadrant(&line->p1);
  412.                 line->p2_quad   = iivvm_math_computeQuadrant(&line->p2);
  413.             }
  414.     }
  415.  
  416.     void iivvm_copyLine(SLineF32* line, SXYF32* p1, SXYF32* p2, bool tlComputeLine)
  417.     {
  418.         // Copy
  419.         memcpy(&line->p1, p1, sizeof(line->p1));
  420.         memcpy(&line->p2, p2, sizeof(line->p2));
  421.  
  422.         // Compute if need be
  423.         if (tlComputeLine)
  424.             iivvm_math_computeLine(line);
  425.     }
  426.  
  427.  
  428.  
  429.  
  430. //////////
  431. //
  432. // Called to draw or generate the bezier using 3 points
  433. //
  434. //////
  435.     SXYF32* iivvm_canvasBezier3(s32 tnSegments, SXYF32* tfP1, SXYF32* tfP2, SXYF32* tfP3)
  436.     {
  437.         s32             lnI;
  438.         f32             lfPercent, lfCosTheta1, lfSinTheta1, lfCosTheta2, lfSinTheta2;
  439.         SXYF32          p1, p2, pbez;
  440.         SLineF32        l1, l2;     // Lines from bez->p1 to bez->p2, and bez->p2 to bez->p3
  441.         SLineF32        lmid;       // Line from l1 to l2
  442.         SXYF32*         points;
  443.  
  444.  
  445.         // Allocate our return buffer
  446.         points = (SXYF32*)malloc(tnSegments * sizeof(SXYF32));
  447.         memset(points, 0, tnSegments * sizeof(SXYF32));
  448.  
  449.  
  450.         //////////
  451.         // Copy and compute our lines
  452.         //////
  453.             iivvm_copyLine(&l1, tfP1, tfP2, true);
  454.             iivvm_copyLine(&l2, tfP2, tfP3, true);
  455.  
  456.  
  457.         //////////
  458.         // Compute our thetas for rapid use
  459.         //////
  460.             // L1
  461.             lfCosTheta1     = (f32)cos(l1.theta);
  462.             lfSinTheta1     = (f32)sin(l1.theta);
  463.             // L2
  464.             lfCosTheta2     = (f32)cos(l2.theta);
  465.             lfSinTheta2     = (f32)sin(l2.theta);
  466.  
  467.  
  468.         //////////
  469.         // Now, iterate through the bezier building the points
  470.         //////
  471.             for (lnI = 0; lnI < tnSegments; lnI++)
  472.             {
  473.                 //////////
  474.                 // Get our percentage
  475.                 //////
  476.                     lfPercent = (f32)lnI / (f32)tnSegments;
  477.  
  478.  
  479.                 //////////
  480.                 // Determine the two points for l1 and l2
  481.                 //////
  482.                     // P1, L1
  483.                     p1.x = tfP1->x + (lfPercent * l1.radius * lfCosTheta1);
  484.                     p1.y = tfP1->y + (lfPercent * l1.radius * lfSinTheta1);
  485.                     // P2, L2
  486.                     p2.x = tfP2->x + (lfPercent * l2.radius * lfCosTheta2);
  487.                     p2.y = tfP2->y + (lfPercent * l2.radius * lfSinTheta2);
  488.  
  489.  
  490.                 //////////
  491.                 // Construct the line between
  492.                 //////
  493.                     iivvm_copyLine(&lmid, &p1, &p2, true);
  494.  
  495.  
  496.                 //////////
  497.                 // Derive the position of this bezier point
  498.                 //////
  499.                     // PBEZ
  500.                     pbez.x = lmid.p1.x + (lfPercent * lmid.radius * (f32)cos(lmid.theta));
  501.                     pbez.y = lmid.p1.y + (lfPercent * lmid.radius * (f32)sin(lmid.theta));
  502.  
  503.  
  504.                 //////////
  505.                 // Store the point
  506.                 //////
  507.                     points[lnI].x = pbez.x;
  508.                     points[lnI].y = pbez.y;
  509.             }
  510.  
  511.         return(points);
  512.     }
  513.  
  514.  
  515.  
  516.  
  517. //////////
  518. //
  519. // Called to draw a point
  520. //
  521. //////
  522.     void iBmp_drawPoint(SBitmap* bmp, s32 tnX, s32 tnY, SBgra color)
  523.     {
  524.         SBgr*   lbgr;
  525.         SBgra*  lbgra;
  526.  
  527.  
  528.         if (bmp)
  529.         {
  530.             // Make sure our coordinates are valid
  531.             if (tnX >= 0 && tnX < bmp->bi.biWidth && tnY >= 0 && tnY < bmp->bi.biHeight)
  532.             {
  533.                 if (bmp->bi.biBitCount == 24)
  534.                 {
  535.                     // Get our offset
  536.                     lbgr = (SBgr*)(bmp->bd + ((bmp->bi.biHeight - tnY - 1) * bmp->rowWidth) + (tnX * 3));
  537.  
  538.                     // Draw it
  539.                     lbgr->red   = color.red;
  540.                     lbgr->grn   = color.grn;
  541.                     lbgr->blu   = color.blu;
  542.  
  543.                 } else if (bmp->bi.biBitCount == 32) {
  544.                     // Get our offset
  545.                     lbgra = (SBgra*)(bmp->bd + ((bmp->bi.biHeight - tnY - 1) * bmp->rowWidth) + (tnX * 4));
  546.  
  547.                     // Draw it
  548.                     lbgra->red  = color.red;
  549.                     lbgra->grn  = color.grn;
  550.                     lbgra->blu  = color.blu;
  551.                 }
  552.             }
  553.         }
  554.     }
  555.  
  556.  
  557.  
  558.  
  559. //////////
  560. //
  561. // Called to draw an arbitary line between two points.  Does
  562. // not handle any anti-aliasing, but rather is a brute-force
  563. // method to present a simple line.
  564. //
  565. /////
  566.     void iBmp_drawArbitraryLine(SBitmap* bmp, s32 tnX1, s32 tnY1, s32 tnX2, s32 tnY2, SBgra color)
  567.     {
  568.         f32 lfX, lfY, lfXStep, lfYStep, lfRadius, lfDeltaX, lfDeltaY;
  569.  
  570.  
  571.         // Compute the distance
  572.         lfDeltaX    = (f32)(tnX2 - tnX1);
  573.         lfDeltaY    = (f32)(tnY2 - tnY1);
  574.         lfRadius    = (f32)sqrt((lfDeltaX*lfDeltaX) + (lfDeltaY*lfDeltaY));
  575.         if (lfRadius < 1.0f)
  576.             return;
  577.  
  578.         // Compute our steps per pixel
  579.         lfXStep     = lfDeltaX / lfRadius;
  580.         lfYStep     = lfDeltaY / lfRadius;
  581.  
  582.         // Iterate for each point
  583.         for (lfX = (f32)tnX1, lfY = (f32)tnY1; lfRadius > 0.0f; lfRadius--, lfX += lfXStep, lfY += lfYStep)
  584.             iBmp_drawPoint(bmp, (s32)lfX, (s32)lfY, color);
  585.     }
  586.  
  587.  
  588.  
  589.  
  590. //////////
  591. //
  592. // Draws a rectange around an arbitrary line.
  593. //
  594. //////
  595. #ifndef _PI2
  596.     #define _PI2 1.570796327
  597. #endif
  598.     void iBmp_drawArbitraryQuad(SBitmap* bmp, s32 tnX1, s32 tnY1, s32 tnX2, s32 tnY2, s32 tnWidth, bool tlDrawEnds, SBgra color)
  599.     {
  600.         f32         lfX1, lfY1, lfX2, lfY2, lfX3, lfY3, lfX4, lfY4;
  601.         SLineF32    line;
  602.  
  603.  
  604.         //////////
  605.         // Compute the line
  606.         /////
  607.             line.p1.x = (f32)tnX1;
  608.             line.p1.y = (f32)tnY1;
  609.             line.p2.x = (f32)tnX2;
  610.             line.p2.y = (f32)tnY2;
  611.             iivvm_math_computeLine(&line);
  612.  
  613.  
  614.         //////////
  615.         // Draw the line
  616.         //////
  617.             lfX1 = line.p1.x + ((f32)cos(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  618.             lfY1 = line.p1.y + ((f32)sin(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  619.             lfX2 = line.p1.x + ((f32)cos(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  620.             lfY2 = line.p1.y + ((f32)sin(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  621.             if (tlDrawEnds)
  622.                 iBmp_drawArbitraryLine(bmp, (s32)lfX1, (s32)lfY1, (s32)lfX2, (s32)lfY2, color);
  623.  
  624.             lfX3 = line.p2.x + ((f32)cos(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  625.             lfY3 = line.p2.y + ((f32)sin(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  626.             lfX4 = line.p2.x + ((f32)cos(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  627.             lfY4 = line.p2.y + ((f32)sin(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  628.             if (tlDrawEnds)
  629.                 iBmp_drawArbitraryLine(bmp, (s32)lfX3, (s32)lfY3, (s32)lfX4, (s32)lfY4, color);
  630.  
  631.             iBmp_drawArbitraryLine(bmp, (s32)lfX1, (s32)lfY1, (s32)lfX3, (s32)lfY3, color);
  632.             iBmp_drawArbitraryLine(bmp, (s32)lfX2, (s32)lfY2, (s32)lfX4, (s32)lfY4, color);
  633.     }
  634.  
  635.  
  636.  
  637.  
  638. //////////
  639. //
  640. // Create a two-part bezier-3 line, one from upper-left to center,
  641. // the other from lower-right to center.
  642. //
  643. //////
  644.     void iTest_nodeLine(SBitmap* bmp, f32 lfFactorX, f32 lfFactorY)
  645.     {
  646.         s32     lnI, lnWidth;
  647.         SXYF32* points1;
  648.         SXYF32* points2;
  649.         SXYF32  p1, p2, p3, p4, p5;
  650.         f32     lfWidth, lfHeight;
  651.  
  652.  
  653.         lfWidth  = bmp->bi.biWidth  * lfFactorX / 8.0f;
  654.         lfHeight = bmp->bi.biHeight * lfFactorY / 8.0f;
  655.  
  656.         p1.x = ((f32)bmp->bi.biWidth  / 2.0f) - (lfWidth / 2.0f);
  657.         p1.y = ((f32)bmp->bi.biHeight / 2.0f) - (lfHeight / 2.0f);
  658.  
  659.         p2.x = ((f32)bmp->bi.biWidth  / 2.0f) - (lfWidth / 4.0f);
  660.         p2.y = ((f32)bmp->bi.biHeight / 2.0f) - (lfHeight / 2.0f);
  661.  
  662.         p3.x = ((f32)bmp->bi.biWidth  / 2.0f);
  663.         p3.y = ((f32)bmp->bi.biHeight / 2.0f);
  664.         points1 = iivvm_canvasBezier3(20, &p1, &p2, &p3);
  665.  
  666.         p4.x = ((f32)bmp->bi.biWidth  / 2.0f) + (lfWidth / 4.0f);
  667.         p4.y = ((f32)bmp->bi.biHeight / 2.0f) + (lfHeight / 2.0f);
  668.  
  669.         p5.x = ((f32)bmp->bi.biWidth  / 2.0f) + (lfWidth / 2.0f);
  670.         p5.y = ((f32)bmp->bi.biHeight / 2.0f) + (lfHeight / 2.0f);
  671.         points2 = iivvm_canvasBezier3(20, &p5, &p4, &p3);
  672.  
  673.         lnWidth = 5;
  674.         for (lnI = 0; lnI < 20 - 1; lnI++)
  675.         {
  676.             iBmp_drawArbitraryQuad(bmp, (s32)points1[lnI].x, (s32)points1[lnI].y, (s32)points1[lnI+1].x, (s32)points1[lnI+1].y, lnWidth, true, blackColor);
  677.             iBmp_drawArbitraryQuad(bmp, (s32)points2[lnI].x, (s32)points2[lnI].y, (s32)points2[lnI+1].x, (s32)points2[lnI+1].y, lnWidth, true, blackColor);
  678.         }
  679.         --lnI;
  680.         iBmp_drawArbitraryQuad(bmp, (s32)points1[lnI].x, (s32)points1[lnI].y, (s32)points2[lnI].x, (s32)points2[lnI].y, lnWidth, true, blackColor);
  681.         free(points1);
  682.         free(points2);
  683.     }
  684.  
  685.  
  686.  
  687.  
  688. //////////
  689. //
  690. // Create an 800x600 bitmap, populate it with a double bezier-3 curve,
  691. // and write the bitmap to disk.
  692. //
  693. //////
  694.     int main(int argc, char* argv[])
  695.     {
  696.         size_t      numwritten1, numwritten2, numwritten3;
  697.         SBitmap*    bmp;
  698.         FILE*       lfh;
  699.  
  700.  
  701.         //////////
  702.         // Create the bitmap
  703.         //////
  704.             bmp = iBmp_allocate(800, 600, 24);
  705.             if (!bmp)
  706.             {
  707.                 printf("Failure allocating bitmap.\n");
  708.                 return -1;
  709.             }
  710.  
  711.  
  712.         //////////
  713.         // Draw the node line
  714.         //////
  715.             blackColor.color = 0;
  716.             iTest_nodeLine(bmp, 7.0f, 7.0f);
  717.  
  718.  
  719.         //////////
  720.         // Write the output file
  721.         //////
  722.             lfh = fopen("output.bmp", "wb+");
  723.             if (!lfh)
  724.             {
  725.                 printf("Error creating output.bmp\n");
  726.                 return -2;
  727.             }
  728.             numwritten1 = fwrite(&bmp->bh, 1, sizeof(bmp->bh), lfh);
  729.             numwritten2 = fwrite(&bmp->bi, 1, sizeof(bmp->bi), lfh);
  730.             numwritten3 = fwrite(bmp->bd, 1, bmp->bi.biSizeImage, lfh);
  731.             fclose(lfh);
  732.             if (!(numwritten1 == sizeof(bmp->bh) && numwritten2 == sizeof(bmp->bi) && numwritten3 == bmp->bi.biSizeImage))
  733.             {
  734.                 printf("Error writing output.bmp\n");
  735.                 return -3;
  736.             }
  737.  
  738.  
  739.         //////////
  740.         // Indicate our status
  741.         //////
  742.             printf("Success.  output.bmp created.\n");
  743.             return 0;
  744.     }
Advertisement
Add Comment
Please, Sign In to add comment