Advertisement
stgatilov

Quadratic bezier curve rasterization

Aug 1st, 2015
1,187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.98 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. //==============================
  7. #include "loadbmp.h"
  8. Bitmap bmp;
  9. void DrawPixel(int x, int y) {
  10.     int pixel = y * bmp.width + x;
  11.     auto ptr = bmp.buffer + (bmp.bpp/8) * pixel;
  12.     ptr[0] = ptr[1] = ptr[2] = 255;
  13. }
  14. //==============================
  15.  
  16.  
  17. struct Point {
  18.     union {
  19.         struct { double x, y; };
  20.         double a[2];
  21.     };
  22. };
  23.  
  24. struct Bezier {
  25.     Point pts[3];
  26. };
  27.  
  28. const double EPS = 1e-7;
  29. const double INF = 1e+50;
  30.  
  31. double WhenEquals(double p0, double p1, double p2, double val, double minp) {
  32.     //p0 * (1-t)^2 + p1 * 2t(1 - t) + p2 * t^2 = val
  33.     double qa = p0 + p2 - 2 * p1;
  34.     double qb = p1 - p0;
  35.     double qc = p0 - val;
  36.     assert(fabs(qa) > EPS); //singular case must be handled separately
  37.     double qd = qb * qb - qa * qc;
  38.     if (qd < -EPS)
  39.         return INF;
  40.     qd = sqrt(max(qd, 0.0));
  41.     double t1 = (-qb - qd) / qa;
  42.     double t2 = (-qb + qd) / qa;
  43.     if (t2 < t1) swap(t1, t2);
  44.     if (t1 > minp + EPS)
  45.         return t1;
  46.     else if (t2 > minp + EPS)
  47.         return t2;
  48.     return INF;
  49. }
  50.  
  51. void DrawCurve(const Bezier &curve) {
  52.     int cell[2];
  53.     for (int c = 0; c < 2; c++)
  54.         cell[c] = int(floor(curve.pts[0].a[c]));
  55.     DrawPixel(cell[0], cell[1]);
  56.     double param = 0.0;
  57.     while (1) {
  58.         int bc = -1, bs = -1;
  59.         double bestTime = 1.0;
  60.         for (int c = 0; c < 2; c++)
  61.             for (int s = 0; s < 2; s++) {
  62.                 double crit = WhenEquals(
  63.                     curve.pts[0].a[c],
  64.                     curve.pts[1].a[c],
  65.                     curve.pts[2].a[c],
  66.                     cell[c] + s, param
  67.                 );
  68.                 if (crit < bestTime) {
  69.                     bestTime = crit;
  70.                     bc = c, bs = s;
  71.                 }
  72.             }
  73.         if (bc < 0)
  74.             break;
  75.         param = bestTime;
  76.         cell[bc] += (2*bs - 1);
  77.         DrawPixel(cell[0], cell[1]);
  78.     }
  79. }
  80.  
  81. int main() {
  82.     bmp = Bitmap(24, 100, 100);
  83.     bmp.alloc();
  84.     memset(bmp.buffer, 0, bmp.size());
  85.  
  86.     Bezier crv;
  87.     crv.pts[0].x = 10.1;
  88.     crv.pts[0].y = 10.2;
  89.     crv.pts[1].x = 70.1;
  90.     crv.pts[1].y = 110.3;
  91.     crv.pts[2].x = 70.4;
  92.     crv.pts[2].y = 30.1;
  93.     DrawCurve(crv);
  94.  
  95.     SaveBMP(bmp, "res.bmp", 24);
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement