X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Ftests%2Flines.cpp;fp=src%2Ftests%2Flines.cpp;h=b15d2182cd72e697c6e72cc51f376c1aeb16e58d;hp=0000000000000000000000000000000000000000;hb=433bde2ed090928b264203c9f422a5b220857120;hpb=57c3c69cbc7d9b3724874fd83cd001984ac21b6a diff --git a/src/tests/lines.cpp b/src/tests/lines.cpp new file mode 100644 index 0000000..b15d218 --- /dev/null +++ b/src/tests/lines.cpp @@ -0,0 +1,76 @@ +#include "main.h" + +#include "pointstobitmap.h" + +using namespace std; + +/** + * NOTE: I am using vector > because it is convenient; don't have to round to pixels, can print to stdout and gnuplot, etc + * vector > should obviously not be used in a practical implementation; directly access the pixel buffer + */ + +template vector > LineDDA(const T & x1, const T & y1, const T & x2, const T & y2) +{ + T dx = x2 - x1; + T dy = y2 - y1; + uint64_t steps = lround(max(abs(dx), abs(dy))); + T xInc = T(dx)/T(steps); + T yInc = T(dy)/T(steps); + T x = x1; T y = y1; + vector > result(steps); + for (uint64_t k = 0; k <= steps; ++k) + { + result[k] = pair(round(x), round(y)); + x += xInc; + y += yInc; + } + return result; +} +/** + * Only works for 0 < m < 1 + */ +template vector > LineBresenham(const T & x1, const T & y1, const T & x2, const T & y2) +{ + T dx = abs(x2 - x1); + T dy = abs(y2 - y1); + T p = 2*dy - dx; + T two_dy = 2*dy; + T two_dxdy = 2*(dy-dx); + + T x; T y; T xEnd; + if (x1 > x2) + { + x = x2; + y = y2; + xEnd = x1; + } + else + { + x = x1; + y = y1; + xEnd = x2; + } + vector > result; + while (x < xEnd) + { + x += 1; + if (p < 0) + p += two_dy; + else + { + y += 1; + p += two_dxdy; + } + result.emplace_back(pair(x,y)); + } + return result; +} + +int main(int argc, char ** argv) +{ + auto f = LineDDA(0,0,400,200); + PointsToBitmap(f, 1, 0,0,0,"lines.bmp"); + auto i = LineBresenham(0,100,400,300); + i.push_back(pair(0,0)); + PointsToBitmap(i, 1, 255,0,0,"lines.bmp", true); +}