Blender  V3.3
image_drawing.h
Go to the documentation of this file.
1 // Copyright (c) 2009 libmv authors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20 
21 // Generic Image Processing Algorithm (GIPA)
22 // Use an ImageModel class that must implement the following :
23 //
24 // ::Contains(int y, int x) <= Tell if a point is inside or not the image
25 // ::operator(int y,int x) <= Modification accessor over the pixel (y,x)
26 // ::Width()
27 // ::Height()
28 
29 #ifndef LIBMV_IMAGE_IMAGE_DRAWING_H
30 #define LIBMV_IMAGE_IMAGE_DRAWING_H
31 
32 namespace libmv {
33 
36 template <class Image, class Color>
37 inline void safePutPixel(int yc, int xc, const Color& col, Image* pim) {
38  if (!pim)
39  return;
40  if (pim->Contains(yc, xc)) {
41  (*pim)(yc, xc) = col;
42  }
43 }
47 template <class Image, class Color>
48 inline void safePutPixel(int yc, int xc, const Color* col, Image* pim) {
49  if (!pim)
50  return;
51  if (pim->Contains(yc, xc)) {
52  for (int i = 0; i < pim->Depth(); ++i)
53  (*pim)(yc, xc, i) = *(col + i);
54  }
55 }
56 
57 // Bresenham approach to draw ellipse.
58 // http://raphaello.univ-fcomte.fr/ig/algorithme/ExemplesGLUt/BresenhamEllipse.htm
59 // Add the rotation of the ellipse.
60 // As the algo. use symmetry we must use 4 rotations.
61 template <class Image, class Color>
62 void DrawEllipse(int xc,
63  int yc,
64  int radiusA,
65  int radiusB,
66  const Color& col,
67  Image* pim,
68  double angle = 0.0) {
69  int a = radiusA;
70  int b = radiusB;
71 
72  // Counter Clockwise rotation matrix.
73  double matXY[4] = {cos(angle), sin(angle), -sin(angle), cos(angle)};
74  int x, y;
75  double d1, d2;
76  x = 0;
77  y = b;
78  d1 = b * b - a * a * b + a * a / 4;
79 
80  float rotX = (matXY[0] * x + matXY[1] * y);
81  float rotY = (matXY[2] * x + matXY[3] * y);
82  safePutPixel(yc + rotY, xc + rotX, col, pim);
83  rotX = (matXY[0] * x - matXY[1] * y);
84  rotY = (matXY[2] * x - matXY[3] * y);
85  safePutPixel(yc + rotY, xc + rotX, col, pim);
86  rotX = (-matXY[0] * x - matXY[1] * y);
87  rotY = (-matXY[2] * x - matXY[3] * y);
88  safePutPixel(yc + rotY, xc + rotX, col, pim);
89  rotX = (-matXY[0] * x + matXY[1] * y);
90  rotY = (-matXY[2] * x + matXY[3] * y);
91  safePutPixel(yc + rotY, xc + rotX, col, pim);
92 
93  while (a * a * (y - .5) > b * b * (x + 1)) {
94  if (d1 < 0) {
95  d1 += b * b * (2 * x + 3);
96  ++x;
97  } else {
98  d1 += b * b * (2 * x + 3) + a * a * (-2 * y + 2);
99  ++x;
100  --y;
101  }
102  rotX = (matXY[0] * x + matXY[1] * y);
103  rotY = (matXY[2] * x + matXY[3] * y);
104  safePutPixel(yc + rotY, xc + rotX, col, pim);
105  rotX = (matXY[0] * x - matXY[1] * y);
106  rotY = (matXY[2] * x - matXY[3] * y);
107  safePutPixel(yc + rotY, xc + rotX, col, pim);
108  rotX = (-matXY[0] * x - matXY[1] * y);
109  rotY = (-matXY[2] * x - matXY[3] * y);
110  safePutPixel(yc + rotY, xc + rotX, col, pim);
111  rotX = (-matXY[0] * x + matXY[1] * y);
112  rotY = (-matXY[2] * x + matXY[3] * y);
113  safePutPixel(yc + rotY, xc + rotX, col, pim);
114  }
115  d2 = b * b * (x + .5) * (x + .5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
116  while (y > 0) {
117  if (d2 < 0) {
118  d2 += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
119  --y;
120  ++x;
121  } else {
122  d2 += a * a * (-2 * y + 3);
123  --y;
124  }
125  rotX = (matXY[0] * x + matXY[1] * y);
126  rotY = (matXY[2] * x + matXY[3] * y);
127  safePutPixel(yc + rotY, xc + rotX, col, pim);
128  rotX = (matXY[0] * x - matXY[1] * y);
129  rotY = (matXY[2] * x - matXY[3] * y);
130  safePutPixel(yc + rotY, xc + rotX, col, pim);
131  rotX = (-matXY[0] * x - matXY[1] * y);
132  rotY = (-matXY[2] * x - matXY[3] * y);
133  safePutPixel(yc + rotY, xc + rotX, col, pim);
134  rotX = (-matXY[0] * x + matXY[1] * y);
135  rotY = (-matXY[2] * x + matXY[3] * y);
136  safePutPixel(yc + rotY, xc + rotX, col, pim);
137  }
138 }
139 
140 // Bresenham approach do not allow to draw concentric circle without holes.
141 // So it's better the use the Andres method.
142 // http://fr.wikipedia.org/wiki/Algorithme_de_tracĂ©_de_cercle_d'Andres.
143 template <class Image, class Color>
144 void DrawCircle(int x, int y, int radius, const Color& col, Image* pim) {
145  Image& im = *pim;
146  if (im.Contains(y + radius, x + radius) ||
147  im.Contains(y + radius, x - radius) ||
148  im.Contains(y - radius, x + radius) ||
149  im.Contains(y - radius, x - radius)) {
150  int x1 = 0;
151  int y1 = radius;
152  int d = radius - 1;
153  while (y1 >= x1) {
154  // Draw the point for each octant.
155  safePutPixel(y1 + y, x1 + x, col, pim);
156  safePutPixel(x1 + y, y1 + x, col, pim);
157  safePutPixel(y1 + y, -x1 + x, col, pim);
158  safePutPixel(x1 + y, -y1 + x, col, pim);
159  safePutPixel(-y1 + y, x1 + x, col, pim);
160  safePutPixel(-x1 + y, y1 + x, col, pim);
161  safePutPixel(-y1 + y, -x1 + x, col, pim);
162  safePutPixel(-x1 + y, -y1 + x, col, pim);
163  if (d >= 2 * x1) {
164  d = d - 2 * x1 - 1;
165  x1 += 1;
166  } else {
167  if (d <= 2 * (radius - y1)) {
168  d = d + 2 * y1 - 1;
169  y1 -= 1;
170  } else {
171  d = d + 2 * (y1 - x1 - 1);
172  y1 -= 1;
173  x1 += 1;
174  }
175  }
176  }
177  }
178 }
179 
180 // Bresenham algorithm
181 template <class Image, class Color>
182 void DrawLine(int xa, int ya, int xb, int yb, const Color& col, Image* pim) {
183  Image& im = *pim;
184 
185  // If one point is outside the image
186  // Replace the outside point by the intersection of the line and
187  // the limit (either x=width or y=height).
188  if (!im.Contains(ya, xa) || !im.Contains(yb, xb)) {
189  int width = pim->Width();
190  int height = pim->Height();
191  const bool xdir = xa < xb, ydir = ya < yb;
192  float nx0 = xa, nx1 = xb, ny0 = ya, ny1 = yb, &xleft = xdir ? nx0 : nx1,
193  &yleft = xdir ? ny0 : ny1, &xright = xdir ? nx1 : nx0,
194  &yright = xdir ? ny1 : ny0, &xup = ydir ? nx0 : nx1,
195  &yup = ydir ? ny0 : ny1, &xdown = ydir ? nx1 : nx0,
196  &ydown = ydir ? ny1 : ny0;
197 
198  if (xright < 0 || xleft >= width)
199  return;
200  if (xleft < 0) {
201  yleft -= xleft * (yright - yleft) / (xright - xleft);
202  xleft = 0;
203  }
204  if (xright >= width) {
205  yright -= (xright - width) * (yright - yleft) / (xright - xleft);
206  xright = width - 1;
207  }
208  if (ydown < 0 || yup >= height)
209  return;
210  if (yup < 0) {
211  xup -= yup * (xdown - xup) / (ydown - yup);
212  yup = 0;
213  }
214  if (ydown >= height) {
215  xdown -= (ydown - height) * (xdown - xup) / (ydown - yup);
216  ydown = height - 1;
217  }
218 
219  xa = (int)xleft;
220  xb = (int)xright;
221  ya = (int)yleft;
222  yb = (int)yright;
223  }
224 
225  int xbas, xhaut, ybas, yhaut;
226  // Check the condition ybas < yhaut.
227  if (ya <= yb) {
228  xbas = xa;
229  ybas = ya;
230  xhaut = xb;
231  yhaut = yb;
232  } else {
233  xbas = xb;
234  ybas = yb;
235  xhaut = xa;
236  yhaut = ya;
237  }
238  // Initialize slope.
239  int x, y, dx, dy, incrmX, incrmY, dp, N, S;
240  dx = xhaut - xbas;
241  dy = yhaut - ybas;
242  if (dx > 0) { // If xhaut > xbas we will increment X.
243  incrmX = 1;
244  } else {
245  incrmX = -1; // else we will decrement X.
246  dx *= -1;
247  }
248  if (dy > 0) { // Positive slope will increment X.
249  incrmY = 1;
250  } else { // Negative slope.
251  incrmY = -1;
252  }
253  if (dx >= dy) {
254  dp = 2 * dy - dx;
255  S = 2 * dy;
256  N = 2 * (dy - dx);
257  y = ybas;
258  x = xbas;
259  while (x != xhaut) {
260  safePutPixel(y, x, col, pim);
261  x += incrmX;
262  if (dp <= 0) { // Go in direction of the South Pixel.
263  dp += S;
264  } else { // Go to the North.
265  dp += N;
266  y += incrmY;
267  }
268  }
269  } else {
270  dp = 2 * dx - dy;
271  S = 2 * dx;
272  N = 2 * (dx - dy);
273  x = xbas;
274  y = ybas;
275  while (y < yhaut) {
276  safePutPixel(y, x, col, pim);
277  y += incrmY;
278  if (dp <= 0) { // Go in direction of the South Pixel.
279  dp += S;
280  } else { // Go to the North.
281  dp += N;
282  x += incrmX;
283  }
284  }
285  }
286  safePutPixel(y, x, col, pim);
287 }
288 
289 } // namespace libmv
290 
291 #endif // LIBMV_IMAGE_IMAGE_DRAWING_H
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
uint col
#define N
static unsigned a[3]
Definition: RandGen.cpp:78
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
void safePutPixel(int yc, int xc, const Color &col, Image *pim)
Definition: image_drawing.h:37
void DrawEllipse(int xc, int yc, int radiusA, int radiusB, const Color &col, Image *pim, double angle=0.0)
Definition: image_drawing.h:62
void DrawLine(int xa, int ya, int xb, int yb, const Color &col, Image *pim)
void DrawCircle(int x, int y, int radius, const Color &col, Image *pim)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)