TouchCPLib  1.0.0
A touch-enabled GUI interface based on SDL and libTS. It provides a simple desktop-free UI for your embedded Raspberry projects.
XiaolinWu.h
Go to the documentation of this file.
1 #pragma once
2 #include <SDL2/SDL.h>
3 #include <algorithm>
4 #include <functional>
5 #include "Color.h"
6 
7 class XiaolinWu
8 {
9 private:
10  // integer part of x
11  static int ipart(float x)
12  {
13  return (int)x;
14  }
15  static int round(float x)
16  {
17  return ipart(x + 0.5);
18  }
19  // fractional part of x
20  static float fpart(float x)
21  {
22  return x - (int)(x);
23  }
24  static int rfpart(int x)
25  {
26  return 1.f - fpart(x);
27  }
28 
29 public:
40  static void drawLine(float x0, float y0, float x1, float y1, std::function<void(int, int, float)> plot)
41  {
42  bool steep = std::abs(y1 - y0) > std::abs(x1 - x0);
43 
44  if (steep)
45  {
46  std::swap(x0, y0);
47  std::swap(x1, y1);
48  }
49  if (x0 > x1)
50  {
51  std::swap(x0, x1);
52  std::swap(y0, y1);
53  }
54 
55  float dx = x1 - x0;
56  float dy = y1 - y0;
57  float gradient = dy / dx;
58  if (dx == 0.0)
59  {
60  gradient = 1.0;
61  }
62 
63  // handle first endpoint
64  float xend = round(x0);
65  float yend = y0 + gradient * (xend - x0);
66  float xgap = rfpart(x0 + 0.5);
67  float xpxl1 = xend; // this will be used in the main loop
68  float ypxl1 = ipart(yend);
69  if (steep)
70  {
71  plot(ypxl1, xpxl1, rfpart(yend) * xgap);
72  plot(ypxl1 + 1, xpxl1, fpart(yend) * xgap);
73  }
74  else
75  {
76  plot(xpxl1, ypxl1, rfpart(yend) * xgap);
77  plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap);
78  }
79  float intery = yend + gradient; // first y-intersection for the main loop
80 
81  // handle second endpoint
82  xend = round(x1);
83  yend = y1 + gradient * (xend - x1);
84  xgap = fpart(x1 + 0.5);
85  float xpxl2 = xend; //this will be used in the main loop
86  float ypxl2 = ipart(yend);
87  if (steep)
88  {
89  plot(ypxl2, xpxl2, rfpart(yend) * xgap);
90  plot(ypxl2 + 1, xpxl2, fpart(yend) * xgap);
91  }
92  else
93  {
94  plot(xpxl2, ypxl2, rfpart(yend) * xgap);
95  plot(xpxl2, ypxl2 + 1, fpart(yend) * xgap);
96  }
97 
98  // main loop
99  if (steep)
100  {
101  for (int x = xpxl1 + 1; x < xpxl2; x++)
102  {
103  plot(ipart(intery), x, rfpart(intery));
104  plot(ipart(intery) + 1, x, fpart(intery));
105  intery = intery + gradient;
106  }
107  }
108  else
109  {
110  for (int x = xpxl1 + 1; x < xpxl2; x++)
111  {
112  plot(x, ipart(intery), rfpart(intery));
113  plot(x, ipart(intery) + 1, fpart(intery));
114  intery = intery + gradient;
115  }
116  }
117  }
118 };
Definition: XiaolinWu.h:7
static void drawLine(float x0, float y0, float x1, float y1, std::function< void(int, int, float)> plot)
Draw a line using the XiaolinWu antialiasing algorithm.
Definition: XiaolinWu.h:40
A color wrapper.