54 inline double ipart(
const double & x)
56 return (x == x) ? x - fmod(x, 1.0) : x;
62 inline double round(
const double & x)
64 return ipart(x + 0.5);
71 inline double fpart(
const double & x)
79 inline double rfpart(
const double & x)
81 return 1.0 - fpart(x);
87 template <
class image_t>
89 plot_pixel(
typename image_t::Pointer & image,
90 const unsigned int & width,
91 const unsigned int & height,
92 const typename image_t::IndexType & index,
96 if ((
unsigned int)(index[0]) >= width ||
97 (
unsigned int)(index[1]) >= height)
102 typedef typename image_t::PixelType color_t;
103 double o = double(image->GetPixel(index));
104 double n = (1.0 - w) * o + w * c;
105 n = std::max(0.0, std::min(255.0, n));
106 image->SetPixel(index, color_t(n));
112 template <
class image_t>
114 plot_normal(
typename image_t::Pointer & image,
115 const unsigned int & width,
116 const unsigned int & height,
122 typename image_t::IndexType index;
123 index[0] = (
unsigned int)(x);
124 index[1] = (
unsigned int)(y);
125 plot_pixel<image_t>(image, width, height, index, w, c);
131 template <
class image_t>
133 plot_swapped(
typename image_t::Pointer & image,
134 const unsigned int & width,
135 const unsigned int & height,
141 typename image_t::IndexType index;
142 index[0] = (
unsigned int)(y);
143 index[1] = (
unsigned int)(x);
144 plot_pixel<image_t>(image, width, height, index, w, c);
153 template <
class image_t>
155 draw_nearly_horizontal_line
156 (
typename image_t::Pointer & image,
162 void(*draw_pixel)(
typename image_t::Pointer &,
163 const unsigned int &,
164 const unsigned int &,
170 typename image_t::SizeType sz =
171 image->GetLargestPossibleRegion().GetSize();
182 double gradient = dy / dx;
185 double xend = round(x1);
186 double yend = y1 + gradient * (xend - x1);
187 double xgap = rfpart(x1 + 0.5);
189 double ypxl1 = ipart(yend);
190 draw_pixel(image, sz[0], sz[1], xpxl1, ypxl1, rfpart(yend) * xgap, c);
191 draw_pixel(image, sz[0], sz[1], xpxl1, ypxl1 + 1, fpart(yend) * xgap, c);
192 double intery = yend + gradient;
196 yend = y2 + gradient * (xend - x2);
197 xgap = rfpart(x2 - 0.5);
199 double ypxl2 = ipart(yend);
200 draw_pixel(image, sz[0], sz[1], xpxl2, ypxl2, rfpart(yend) * xgap, c);
201 draw_pixel(image, sz[0], sz[1], xpxl2, ypxl2 + 1, fpart(yend) * xgap, c);
204 for (
double x = xpxl1 + 1.0; x <= xpxl2 - 1.0; x += 1.0)
206 draw_pixel(image, sz[0], sz[1], x, ipart(intery), rfpart(intery), c);
207 draw_pixel(image, sz[0], sz[1], x, ipart(intery) + 1, fpart(intery), c);
208 intery = intery + gradient;
216 template <
class image_t>
218 draw_line(
typename image_t::Pointer & image,
219 const typename image_t::PixelType color,
229 wu::plot_normal<image_t>(image, 0, 0, 0.0, 0.0, 0.0, 0.0);
230 wu::plot_swapped<image_t>(image, 0, 0, 0.0, 0.0, 0.0, 0.0);
233 double dx = fabs(x2 - x1);
234 double dy = fabs(y2 - y1);
236 typename image_t::PointType origin = image->GetOrigin();
237 typename image_t::SpacingType spacing = image->GetSpacing();
248 wu::draw_nearly_horizontal_line<image_t>(image,
251 wu::plot_normal<image_t>);
256 wu::draw_nearly_horizontal_line<image_t>(image,
259 wu::plot_swapped<image_t>);
266 template <
class image_t>
268 draw_line_rotated(
typename image_t::Pointer & image,
269 const typename image_t::PixelType color,
274 const double & radians,
275 const double & ox = 0.0,
276 const double & oy = 0.0)
278 const double ct = ::cos(radians);
279 const double st = ::sin(radians);
281 const double u1 = ox + ct * (x1 - ox) - st * (y1 - oy);
282 const double v1 = oy + ct * (y1 - oy) + st * (x1 - ox);
284 const double u2 = ox + ct * (x2 - ox) - st * (y2 - oy);
285 const double v2 = oy + ct * (y2 - oy) + st * (x2 - ox);
287 draw_line<image_t>(image, color, u1, v1, u2, v2);