Now with GNU MultiPrecision (GMP) integers
[ipdf/code.git] / src / tests / lines.cpp
1 #include "main.h"
2
3 #include "pointstobitmap.h"
4
5 using namespace std;
6
7 /**
8  * NOTE: I am using vector<pair<T,T> > because it is convenient; don't have to round to pixels, can print to stdout and gnuplot, etc
9  *              vector<pair<T,T> > should obviously not be used in a practical implementation; directly access the pixel buffer
10  */
11
12 template <class T> vector<pair<T, T> > LineDDA(const T & x1, const T & y1, const T & x2, const T & y2)
13 {
14         T dx = x2 - x1;
15         T dy = y2 - y1;
16         uint64_t steps = lround(max(abs(dx), abs(dy)));
17         T xInc = T(dx)/T(steps);
18         T yInc = T(dy)/T(steps);
19         T x = x1; T y = y1;
20         vector<pair<T,T> > result(steps);
21         for (uint64_t k = 0; k <= steps; ++k)
22         {
23                 result[k] = pair<T,T>(round(x), round(y));
24                 x += xInc;
25                 y += yInc;
26         }
27         return result;
28 }
29 /**
30  * Only works for 0 < m < 1
31  */
32 template <class T> vector<pair<T, T> > LineBresenham(const T & x1, const T & y1, const T & x2, const T & y2)
33 {
34         T dx = abs(x2 - x1);
35         T dy = abs(y2 - y1);
36         T p = 2*dy - dx;
37         T two_dy = 2*dy;
38         T two_dxdy = 2*(dy-dx);
39
40         T x; T y; T xEnd;
41         if (x1 > x2)
42         {
43                 x = x2;
44                 y = y2;
45                 xEnd = x1;
46         }
47         else
48         {
49                 x = x1;
50                 y = y1;
51                 xEnd = x2;
52         }
53         vector<pair<T,T> > result;
54         while (x < xEnd)
55         {
56                 x += 1;
57                 if (p < 0)
58                         p += two_dy;
59                 else
60                 {
61                         y += 1;
62                         p += two_dxdy;
63                 }
64                 result.emplace_back(pair<T,T>(x,y));
65         }
66         return result;
67 }
68
69 int main(int argc, char ** argv)
70 {
71         auto f = LineDDA<float>(0,0,400,200);
72         PointsToBitmap<float>(f, 1, 0,0,0,"lines.bmp");
73         auto i = LineBresenham<int>(0,100,400,300);
74         i.push_back(pair<int,int>(0,0));
75         PointsToBitmap<int>(i, 1, 255,0,0,"lines.bmp", true);
76 }

UCC git Repository :: git.ucc.asn.au