BGC Tools
Static Public Member Functions
BGC.Mathematics.BezierCurves Class Reference

Static Public Member Functions

static void PlotCubicSplineClosedCurve (int[] x, int[] y, Texture2D contourTex, Color contourColor)
 
static void PlotCubicSpline (int[] x, int[] y, Texture2D contourTex, Color contourColor, bool skipEnds=true)
 
static void PlotCubicSplineClosedCurve (int[] x, int[] y, Action< int, int > addPoint)
 
static void PlotCubicSpline (int[] x, int[] y, Action< int, int > addPoint, bool skipEnds=true)
 From http://members.chello.at/easyfilter/bresenham.pdf More...
 
static void PlotCubicBezier (int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, Action< int, int > addPoint)
 From http://members.chello.at/easyfilter/bresenham.pdf More...
 
static void PlotCubicBezierSeg (int x0, int y0, float x1, float y1, float x2, float y2, int x3, int y3, Action< int, int > addPoint)
 From http://members.chello.at/easyfilter/bresenham.pdf More...
 
static void PlotQuadBezierSeg (int x0, int y0, int x1, int y1, int x2, int y2, Action< int, int > addPoint)
 From http://members.chello.at/easyfilter/bresenham.pdf More...
 
static void PlotLine (int x0, int y0, int x1, int y1, Action< int, int > addPoint)
 From http://members.chello.at/easyfilter/bresenham.pdf More...
 
static void SetPixel (int x, int y, Texture2D contourTex, Color contourColor, int rad=2)
 Use a curried version of this method for the AddPoint action above. Invoke like (x,y) => SetPixel(x, y, localContourTex, localColor, 2); More...
 

Detailed Description

Definition at line 8 of file BezierCurves.cs.

Member Function Documentation

◆ PlotCubicBezier()

static void BGC.Mathematics.BezierCurves.PlotCubicBezier ( int  x0,
int  y0,
int  x1,
int  y1,
int  x2,
int  y2,
int  x3,
int  y3,
Action< int, int >  addPoint 
)
inlinestatic

From http://members.chello.at/easyfilter/bresenham.pdf

Definition at line 202 of file BezierCurves.cs.

204  {
205  /* plot any cubic Bezier curve */
206  int n = 0;
207  int i = 0;
208  long xc = x0 + x1 - x2 - x3;
209  long xa = xc - 4 * (x1 - x2);
210  long xb = x0 - x1 - x2 + x3;
211  long xd = xb + 4 * (x1 + x2);
212  long yc = y0 + y1 - y2 - y3;
213  long ya = yc - 4 * (y1 - y2);
214  long yb = y0 - y1 - y2 + y3;
215  long yd = yb + 4 * (y1 + y2);
216  float fx0 = x0;
217  float fx1;
218  float fx2;
219  float fx3;
220  float fy0 = y0;
221  float fy1;
222  float fy2;
223  float fy3;
224  double t1 = xb * xb - xa * xc;
225  double t2;
226  double[] t = new double[5];
227 
228  /* sub-divide curve at gradient sign changes */
229  if (xa == 0)
230  {
231  /* horizontal */
232  if (Abs(xc) < 2 * Abs(xb))
233  {
234  /* one change */
235  t[n++] = xc / (2.0 * xb);
236  }
237  }
238  else if (t1 > 0.0)
239  {
240  /* two changes */
241  t2 = Sqrt(t1);
242  t1 = (xb - t2) / xa;
243 
244  if (Abs(t1) < 1.0)
245  {
246  t[n++] = t1;
247  }
248 
249  t1 = (xb + t2) / xa;
250 
251  if (Abs(t1) < 1.0)
252  {
253  t[n++] = t1;
254  }
255  }
256 
257  t1 = yb * yb - ya * yc;
258 
259  if (ya == 0)
260  {
261  /* vertical */
262  if (Abs(yc) < 2 * Abs(yb))
263  {
264  /* one change */
265  t[n++] = yc / (2.0 * yb);
266  }
267  }
268  else if (t1 > 0.0)
269  {
270  /* two changes */
271  t2 = Sqrt(t1);
272  t1 = (yb - t2) / ya;
273  if (Abs(t1) < 1.0)
274  {
275  t[n++] = t1;
276  }
277 
278  t1 = (yb + t2) / ya;
279  if (Abs(t1) < 1.0)
280  {
281  t[n++] = t1;
282  }
283  }
284 
285  /* bubble sort of 4 points */
286  for (i = 1; i < n; i++)
287  {
288  if ((t1 = t[i - 1]) > t[i])
289  {
290  t[i - 1] = t[i];
291  t[i] = t1;
292  i = 0;
293  }
294  }
295 
296  /* begin / end point */
297  t1 = -1.0;
298  t[n] = 1.0;
299  for (i = 0; i <= n; i++)
300  {
301  /* plot each segment separately */
302  /* sub-divide at t[i-1], t[i] */
303  t2 = t[i];
304  fx1 = (float)((t1 * (t1 * xb - 2.0 * xc) - t2 * (t1 * (t1 * xa - 2.0 * xb) + xc) + xd) / 8.0 - fx0);
305  fy1 = (float)((t1 * (t1 * yb - 2.0 * yc) - t2 * (t1 * (t1 * ya - 2.0 * yb) + yc) + yd) / 8.0 - fy0);
306  fx2 = (float)((t2 * (t2 * xb - 2.0 * xc) - t1 * (t2 * (t2 * xa - 2.0 * xb) + xc) + xd) / 8.0 - fx0);
307  fy2 = (float)((t2 * (t2 * yb - 2.0 * yc) - t1 * (t2 * (t2 * ya - 2.0 * yb) + yc) + yd) / 8.0 - fy0);
308  fx3 = (float)((t2 * (t2 * (3.0 * xb - t2 * xa) - 3.0 * xc) + xd) / 8.0);
309  fx0 -= fx3;
310  fy3 = (float)((t2 * (t2 * (3.0 * yb - t2 * ya) - 3.0 * yc) + yd) / 8.0);
311  fy0 -= fy3;
312 
313  /* scale bounds to int */
314  x3 = (int)Floor(fx3 + 0.5f);
315  y3 = (int)Floor(fy3 + 0.5f);
316 
317  if (fx0 != 0.0)
318  {
319  fx0 = (x0 - x3) / fx0;
320  fx1 *= fx0;
321  fx2 *= fx0;
322  }
323 
324  if (fy0 != 0.0)
325  {
326  fy0 = (y0 - y3) / fy0;
327  fy1 *= fy0;
328  fy2 *= fy0;
329  }
330 
331  /* segment t1 - t2 */
332  if (x0 != x3 || y0 != y3)
333  {
335  x0: x0,
336  y0: y0,
337  x1: x0 + fx1,
338  y1: y0 + fy1,
339  x2: x0 + fx2,
340  y2: y0 + fy2,
341  x3: x3,
342  y3: y3,
343  addPoint: addPoint);
344  }
345 
346  x0 = x3;
347  y0 = y3;
348  fx0 = fx3;
349  fy0 = fy3;
350  t1 = t2;
351  }
352  }
static void PlotCubicBezierSeg(int x0, int y0, float x1, float y1, float x2, float y2, int x3, int y3, Action< int, int > addPoint)
From http://members.chello.at/easyfilter/bresenham.pdf

◆ PlotCubicBezierSeg()

static void BGC.Mathematics.BezierCurves.PlotCubicBezierSeg ( int  x0,
int  y0,
float  x1,
float  y1,
float  x2,
float  y2,
int  x3,
int  y3,
Action< int, int >  addPoint 
)
inlinestatic

From http://members.chello.at/easyfilter/bresenham.pdf

Definition at line 357 of file BezierCurves.cs.

359  {
360  /* plot limited cubic Bezier segment */
361  int f;
362  int fx;
363  int fy;
364  int leg = 1;
365 
366  /* step direction */
367  int sx = x0 < x3 ? 1 : -1;
368  int sy = y0 < y3 ? 1 : -1;
369  float xc = -Abs(x0 + x1 - x2 - x3);
370  float xa = xc - 4 * sx * (x1 - x2);
371  float xb = sx * (x0 - x1 - x2 + x3);
372  float yc = -Abs(y0 + y1 - y2 - y3);
373  float ya = yc - 4 * sy * (y1 - y2);
374  float yb = sy * (y0 - y1 - y2 + y3);
375 
376  double ab;
377  double ac;
378  double bc;
379  double cb;
380  double xx;
381  double xy;
382  double yy;
383  double dx;
384  double dy;
385  double ex;
386  double EP = 0.01;
387 
388  /* check for curve restrains */
389  /* slope P0-P1 == P2-P3 and (P0-P3 == P1-P2 or no slope change) */
390  Debug.Assert((x1 - x0) * (x2 - x3) < EP && ((x3 - x0) * (x1 - x2) < EP || xb * xb < xa * xc + EP));
391  Debug.Assert((y1 - y0) * (y2 - y3) < EP && ((y3 - y0) * (y1 - y2) < EP || yb * yb < ya * yc + EP));
392  if (xa == 0 && ya == 0)
393  {
394  /* quadratic Bezier */
395  /* new midpoint */
396  sx = (int)Floor((3 * x1 - x0 + 1) / 2);
397  sy = (int)Floor((3 * y1 - y0 + 1) / 2);
398 
400  x0: x0,
401  y0: y0,
402  x1: sx,
403  y1: sy,
404  x2: x3,
405  y2: y3,
406  addPoint: addPoint);
407 
408  return;
409  }
410 
411  /* line lengths */
412  x1 = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) + 1;
413  x2 = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3) + 1;
414  do
415  {
416  /* loop over both ends */
417  ab = xa * yb - xb * ya;
418  ac = xa * yc - xc * ya;
419  bc = xb * yc - xc * yb;
420 
421  /* P0 part of self-intersection loop? */
422  ex = ab * (ab + ac - 3 * bc) + ac * ac;
423 
424  /* calculate resolution */
425  f = ex > 0 ? 1 : (int)Sqrt(1 + 1024 / x1);
426 
427  /* increase resolution */
428  ab *= f;
429  ac *= f;
430  bc *= f;
431  ex *= f * f;
432 
433  /* init differences of 1st degree */
434  xy = 9 * (ab + ac + bc) / 8;
435  cb = 8 * (xa - ya);
436  dx = 27 * (8 * ab * (yb * yb - ya * yc) + ex * (ya + 2 * yb + yc)) / 64 - ya * ya * (xy - ya);
437  dy = 27 * (8 * ab * (xb * xb - xa * xc) - ex * (xa + 2 * xb + xc)) / 64 - xa * xa * (xy + xa);
438  /* init differences of 2nd degree */
439  xx = 3 * (3 * ab * (3 * yb * yb - ya * ya - 2 * ya * yc) - ya * (3 * ac * (ya + yb) + ya * cb)) / 4;
440  yy = 3 * (3 * ab * (3 * xb * xb - xa * xa - 2 * xa * xc) - xa * (3 * ac * (xa + xb) + xa * cb)) / 4;
441  xy = xa * ya * (6 * ab + 6 * ac - 3 * bc + cb);
442  ac = ya * ya;
443  cb = xa * xa;
444  xy = 3 * (xy + 9 * f * (cb * yb * yc - xb * xc * ac) - 18 * xb * yb * ab) / 8;
445 
446  if (ex < 0)
447  {
448  /* negate values if inside self-intersection loop */
449  dx = -dx;
450  dy = -dy;
451  xx = -xx;
452  yy = -yy;
453  xy = -xy;
454  ac = -ac;
455  cb = -cb;
456  }
457 
458  /* init differences of 3rd degree */
459  ab = 6 * ya * ac;
460  ac = -6 * xa * ac;
461  bc = 6 * ya * cb;
462  cb = -6 * xa * cb;
463 
464  /* error of 1st step */
465  dx += xy;
466  ex = dx + dy;
467  dy += xy;
468 
469  bool boundaryHit = false;
470  double pxy = xy;
471 
472  for (fx = fy = f; x0 != x3 && y0 != y3;)
473  {
474  /* plot curve */
475  addPoint.Invoke(x0, y0);
476 
477  do
478  {
479  /* move sub-steps of one pixel */
480  if (dx > pxy || dy < pxy)
481  {
482  /* confusing values */
483  goto exit;
484  }
485 
486  /* save value for test of y step */
487  y1 = (float)(2 * ex - dy);
488  if (2 * ex >= dx)
489  {
490  /* x sub-step */
491  fx--;
492 
493  dx += xx;
494  ex += dx;
495 
496  xy += ac;
497  dy += xy;
498 
499  if (!boundaryHit)
500  {
501  pxy = xy;
502  }
503 
504  yy += bc;
505  xx += ab;
506  }
507 
508  if (y1 <= 0)
509  {
510  /* y sub-step */
511  fy--;
512 
513  dy += yy;
514  ex += dy;
515 
516  xy += bc;
517  dx += xy;
518 
519  if (!boundaryHit)
520  {
521  pxy = xy;
522  }
523 
524  xx += ac;
525  yy += cb;
526  }
527  }
528  while (fx > 0 && fy > 0); /* pixel complete? */
529 
530  /* x step */
531  if (2 * fx <= f)
532  {
533  x0 += sx;
534  fx += f;
535  }
536 
537  /* y step */
538  if (2 * fy <= f)
539  {
540  y0 += sy;
541  fy += f;
542  }
543 
544  if (!boundaryHit && dx < 0 && dy > 0)
545  {
546  boundaryHit = true;
547  /* pixel ahead valid */
548  pxy = EP;
549  }
550  }
551 
552  exit:
553 
554  /* swap legs */
555  int tempInt = x0;
556  x0 = x3;
557  x3 = tempInt;
558  sx = -sx;
559  xb = -xb;
560 
561 
562  tempInt = y0;
563  y0 = y3;
564  y3 = tempInt;
565  sy = -sy;
566  yb = -yb;
567  x1 = x2;
568 
569  }
570  while (leg-- > 0); /* try other end */
571 
572  /* remaining part in case of cusp or crunode */
573  PlotLine(
574  x0: x0,
575  y0: y0,
576  x1: x3,
577  y1: y3,
578  addPoint: addPoint);
579  }
static void PlotLine(int x0, int y0, int x1, int y1, Action< int, int > addPoint)
From http://members.chello.at/easyfilter/bresenham.pdf
static void PlotQuadBezierSeg(int x0, int y0, int x1, int y1, int x2, int y2, Action< int, int > addPoint)
From http://members.chello.at/easyfilter/bresenham.pdf

◆ PlotCubicSpline() [1/2]

static void BGC.Mathematics.BezierCurves.PlotCubicSpline ( int []  x,
int []  y,
Texture2D  contourTex,
Color  contourColor,
bool  skipEnds = true 
)
inlinestatic

Definition at line 19 of file BezierCurves.cs.

23  {
24  PlotCubicSpline(x, y,
25  addPoint: (x0, y0) => SetPixel(x0, y0, contourTex, contourColor),
26  skipEnds: skipEnds);
27  }
static void PlotCubicSpline(int[] x, int[] y, Texture2D contourTex, Color contourColor, bool skipEnds=true)
Definition: BezierCurves.cs:19
static void SetPixel(int x, int y, Texture2D contourTex, Color contourColor, int rad=2)
Use a curried version of this method for the AddPoint action above. Invoke like (x,y) => SetPixel(x, y, localContourTex, localColor, 2);

◆ PlotCubicSpline() [2/2]

static void BGC.Mathematics.BezierCurves.PlotCubicSpline ( int []  x,
int []  y,
Action< int, int >  addPoint,
bool  skipEnds = true 
)
inlinestatic

From http://members.chello.at/easyfilter/bresenham.pdf

Definition at line 51 of file BezierCurves.cs.

54  {
55  int n = x.Length - 1;
56  /* plot cubic spline, destroys input arrays x,y */
57  const int M_MAX = 6;
58 
59  /* diagonal constants of matrix */
60  float mi = 0.25f;
61  float[] m = new float[M_MAX];
62  int x3 = x[n - 1];
63  int y3 = y[n - 1];
64  int x4 = x[n];
65  int y4 = y[n];
66  int i;
67  int x0;
68  int y0;
69  int x1;
70  int y1;
71  int x2;
72  int y2;
73 
74  /* need at least 4 points P[0]..P[n] */
75  Debug.Assert(n > 2);
76 
77  /* first row of matrix */
78  x0 = 12 * x[1] - 3 * x[0];
79  y0 = 12 * y[1] - 3 * y[0];
80  x[1] = x0;
81  y[1] = y0;
82  for (i = 2; i < n; i++)
83  {
84  /* foreward sweep */
85  if (i - 2 < M_MAX)
86  {
87  mi = 0.25f / (2f - mi);
88  m[i - 2] = mi;
89  }
90 
91  x0 = (int)(12 * x[i] - 2 * x0 * mi + 0.5);
92  y0 = (int)(12 * y[i] - 2 * y0 * mi + 0.5);
93  x[i] = x0;
94  y[i] = y0;
95  }
96 
97  /* correct last row */
98  x2 = (int)((x0 - 3 * x4) / (7 - 4 * mi) + 0.5);
99  y2 = (int)((y0 - 3 * y4) / (7 - 4 * mi) + 0.5);
100 
101  if (!skipEnds)
102  {
103  //The Last piece
105  x0: x3,
106  y0: y3,
107  x1: (x2 + x4) / 2,
108  y1: (y2 + y4) / 2,
109  x2: x4,
110  y2: y4,
111  x3: x4,
112  y3: y4,
113  addPoint: addPoint);
114  }
115 
116  if (n - 3 < M_MAX)
117  {
118  mi = m[n - 3];
119  }
120 
121  x1 = (int)((x[n - 2] - 2 * x2) * mi + 0.5);
122  y1 = (int)((y[n - 2] - 2 * y2) * mi + 0.5);
123 
124  for (i = n - 3; i > 0; i--)
125  {
126  /* back substitution */
127  if (i <= M_MAX)
128  {
129  mi = m[i - 1];
130  }
131 
132  x0 = (int)((x[i] - 2 * x1) * mi + 0.5);
133  y0 = (int)((y[i] - 2 * y1) * mi + 0.5);
134 
135  /* reconstruct P[i] */
136  x4 = (int)((x0 + 4 * x1 + x2 + 3) / 6.0);
137  y4 = (int)((y0 + 4 * y1 + y2 + 3) / 6.0);
138 
139  //Potentially skip the second-to-last piece
140  if (i != n - 3 || !skipEnds)
141  {
143  x0: x4,
144  y0: y4,
145  x1: (int)((2 * x1 + x2) / 3 + 0.5),
146  y1: (int)((2 * y1 + y2) / 3 + 0.5),
147  x2: (int)((x1 + 2 * x2) / 3 + 0.5),
148  y2: (int)((y1 + 2 * y2) / 3 + 0.5),
149  x3: x3,
150  y3: y3,
151  addPoint: addPoint);
152  }
153 
154  x3 = x4;
155  y3 = y4;
156  x2 = x1;
157  y2 = y1;
158  x1 = x0;
159  y1 = y0;
160  }
161 
162  x0 = x[0];
163  y0 = y[0];
164 
165  /* reconstruct P[1] */
166  x4 = (int)((3 * x0 + 7 * x1 + 2 * x2 + 6) / 12.0);
167  y4 = (int)((3 * y0 + 7 * y1 + 2 * y2 + 6) / 12.0);
168 
169  if (!skipEnds)
170  {
171  //The second piece
173  x0: x4,
174  y0: y4,
175  x1: (int)((2 * x1 + x2) / 3 + 0.5),
176  y1: (int)((2 * y1 + y2) / 3 + 0.5),
177  x2: (int)((x1 + 2 * x2) / 3 + 0.5),
178  y2: (int)((y1 + 2 * y2) / 3 + 0.5),
179  x3: x3,
180  y3: y3,
181  addPoint: addPoint);
182 
183  //The first piece
185  x0: x0,
186  y0: y0,
187  x1: x0,
188  y1: y0,
189  x2: (x0 + x1) / 2,
190  y2: (y0 + y1) / 2,
191  x3: x4,
192  y3: y4,
193  addPoint: addPoint);
194  }
195  }
static void PlotCubicBezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, Action< int, int > addPoint)
From http://members.chello.at/easyfilter/bresenham.pdf

◆ PlotCubicSplineClosedCurve() [1/2]

static void BGC.Mathematics.BezierCurves.PlotCubicSplineClosedCurve ( int []  x,
int []  y,
Texture2D  contourTex,
Color  contourColor 
)
inlinestatic

Definition at line 10 of file BezierCurves.cs.

14  {
16  addPoint: (x0, y0) => SetPixel(x0, y0, contourTex, contourColor));
17  }
static void SetPixel(int x, int y, Texture2D contourTex, Color contourColor, int rad=2)
Use a curried version of this method for the AddPoint action above. Invoke like (x,y) => SetPixel(x, y, localContourTex, localColor, 2);
static void PlotCubicSplineClosedCurve(int[] x, int[] y, Texture2D contourTex, Color contourColor)
Definition: BezierCurves.cs:10

◆ PlotCubicSplineClosedCurve() [2/2]

static void BGC.Mathematics.BezierCurves.PlotCubicSplineClosedCurve ( int []  x,
int []  y,
Action< int, int >  addPoint 
)
inlinestatic

Definition at line 30 of file BezierCurves.cs.

33  {
34  int[] newX = new int[x.Length + 5];
35  int[] newY = new int[y.Length + 5];
36 
37  for (int i = 0; i < newX.Length; i++)
38  {
39  newX[i] = x[i % x.Length];
40  newY[i] = y[i % x.Length];
41  }
42 
43  PlotCubicSpline(newX, newY,
44  addPoint: addPoint,
45  skipEnds: true);
46  }
static void PlotCubicSpline(int[] x, int[] y, Texture2D contourTex, Color contourColor, bool skipEnds=true)
Definition: BezierCurves.cs:19

◆ PlotLine()

static void BGC.Mathematics.BezierCurves.PlotLine ( int  x0,
int  y0,
int  x1,
int  y1,
Action< int, int >  addPoint 
)
inlinestatic

From http://members.chello.at/easyfilter/bresenham.pdf

Definition at line 699 of file BezierCurves.cs.

701  {
702  int dx = Abs(x1 - x0);
703  int sx = x0 < x1 ? 1 : -1;
704  int dy = -Abs(y1 - y0);
705  int sy = y0 < y1 ? 1 : -1;
706  int err = dx + dy;
707  /* error value e_xy */
708  int e2;
709 
710  while (true)
711  {
712  addPoint.Invoke(x0, y0);
713 
714  e2 = 2 * err;
715 
716  if (e2 >= dy)
717  {
718  /* e_xy+e_x > 0 */
719  if (x0 == x1)
720  {
721  break;
722  }
723 
724  err += dy; x0 += sx;
725  }
726 
727  if (e2 <= dx)
728  {
729  /* e_xy+e_y < 0 */
730  if (y0 == y1)
731  {
732  break;
733  }
734 
735  err += dx; y0 += sy;
736  }
737  }
738  }

◆ PlotQuadBezierSeg()

static void BGC.Mathematics.BezierCurves.PlotQuadBezierSeg ( int  x0,
int  y0,
int  x1,
int  y1,
int  x2,
int  y2,
Action< int, int >  addPoint 
)
inlinestatic

From http://members.chello.at/easyfilter/bresenham.pdf

Definition at line 584 of file BezierCurves.cs.

586  {
587  /* plot a limited quadratic Bezier segment */
588  int sx = x2 - x1;
589  int sy = y2 - y1;
590 
591  /* relative values for checks */
592  long xx = x0 - x1;
593  long yy = y0 - y1;
594  long xy;
595 
596  /* curvature */
597  double dx;
598  double dy;
599  double err;
600  double cur = xx * sy - yy * sx;
601 
602  /* sign of gradient must not change */
603  Debug.Assert(xx * sx <= 0 && yy * sy <= 0);
604 
605  if (sx * (long)sx + sy * (long)sy > xx * xx + yy * yy)
606  {
607  /* begin with longer part */
608  /* swap P0 P2 */
609  x2 = x0;
610  x0 = sx + x1;
611  y2 = y0;
612  y0 = sy + y1;
613  cur = -cur;
614  }
615 
616  if (cur != 0)
617  {
618  /* no straight line */
619  /* x step direction */
620  xx += sx;
621  sx = x0 < x2 ? 1 : -1;
622  xx *= sx;
623 
624  /* y step direction */
625  yy += sy;
626  sy = y0 < y2 ? 1 : -1;
627  yy *= sy;
628 
629  /* differences 2nd degree */
630  xy = 2 * xx * yy;
631  xx *= xx;
632  yy *= yy;
633 
634  if (cur * sx * sy < 0)
635  {
636  /* negated curvature? */
637  xx = -xx;
638  yy = -yy;
639  xy = -xy;
640  cur = -cur;
641  }
642 
643  /* differences 1st degree */
644  dx = 4.0 * sy * cur * (x1 - x0) + xx - xy;
645  dy = 4.0 * sx * cur * (y0 - y1) + yy - xy;
646 
647  /* error 1st step */
648  xx += xx;
649  yy += yy;
650  err = dx + dy + xy;
651  do
652  {
653  /* plot curve */
654  addPoint.Invoke(x0, y0);
655 
656  if (x0 == x2 && y0 == y2)
657  {
658  /* last pixel -> curve finished */
659  return;
660  }
661 
662  /* save value for test of y step */
663  bool yTrigger = 2 * err < dx;
664 
665  if (2 * err > dy)
666  {
667  /* x step */
668  x0 += sx;
669  dx -= xy;
670  dy += yy;
671  err += dy;
672  }
673 
674  if (yTrigger)
675  {
676  /* y step */
677  y0 += sy;
678  dy -= xy;
679  dx += xx;
680  err += dx;
681  }
682 
683  }
684  while (dy < dx); /* gradient negates -> algorithm fails */
685  }
686 
687  /* plot remaining part to end */
688  PlotLine(
689  x0: x0,
690  y0: y0,
691  x1: x2,
692  y1: y2,
693  addPoint: addPoint);
694  }
static void PlotLine(int x0, int y0, int x1, int y1, Action< int, int > addPoint)
From http://members.chello.at/easyfilter/bresenham.pdf

◆ SetPixel()

static void BGC.Mathematics.BezierCurves.SetPixel ( int  x,
int  y,
Texture2D  contourTex,
Color  contourColor,
int  rad = 2 
)
inlinestatic

Use a curried version of this method for the AddPoint action above. Invoke like (x,y) => SetPixel(x, y, localContourTex, localColor, 2);

Definition at line 744 of file BezierCurves.cs.

750  {
751  int rad_sq = rad * rad;
752 
753  for (int dx = -rad; dx <= rad; dx++)
754  {
755  for (int dy = -rad; dy <= rad; dy++)
756  {
757  if (dx * dx + dy * dy <= rad_sq)
758  {
759  if (x + dx >= 0 && x + dx < contourTex.width &&
760  y + dy >= 0 && y + dy < contourTex.height)
761  {
762  contourTex.SetPixel(x + dx, y + dy, contourColor);
763  }
764  }
765  }
766  }
767  }

The documentation for this class was generated from the following file: