This alternative implementation is slightly slower due to the presence of an extra subtraction. It is based on what is described here. This version can produce a different integer sequence to the previous version due to the different decision variable scheme (values are effectively rounded differently); it still produces an evenly distributed scaled range however.
template <typename T>
class bresenham_counter_alt
{
/* operator T() returns x[0..N-1] = 0 .. R, i.e. x[n] = (R / (N-1)) * n, without
using floating point or multiplication/division each iteration */
public:
bresenham_counter_alt(T range, T number) :
n(number-1),
partInt(n > 0 ? range / n : 0),
partFract(n > 0 ? range % n : 0),
e(0),
incrCounter(partInt),
incrCounterPlus1(n > 0 ? incrCounter+1 : 0),
counter(0) {}
bresenham_counter_alt(T rangeStart, T rangeEnd, T number) :
n(number-1),
partInt(n > 0 ? rangeEnd > rangeStart ?
(rangeEnd - rangeStart) / n : (rangeStart - rangeEnd) / n : 0),
partFract(n > 0 ? rangeEnd > rangeStart ?
(rangeEnd - rangeStart) % n : (rangeStart - rangeEnd) % n: 0),
e(0),
incrCounter(rangeEnd > rangeStart ? partInt : -partInt),
incrCounterPlus1(n > 0 ? rangeEnd > rangeStart ? incrCounter+1 : incrCounter-1 :
0),
counter(rangeStart) {}
operator T()
{
e += partFract;
if (e < n)
{
T v = counter;
counter += incrCounter;
return v;
}
else
{
e -= n;
T v = counter;
counter += incrCounterPlus1;
return v;
}
}
private:
T n, partInt, partFract, e;
T incrCounter;
T incrCounterPlus1;
T counter;
};
The following test program illustrates the differences between the two versions:
int main()
{
int a=1, b=123, n=75;
bresenham_counter<int> bc1(a, b, n);
bresenham_counter_alt<int> bc2(a, b, n);
for (int i = 0; i<n; ++i)
std::cout << i << ": " << bc1 << " " << bc2 << " " << (double)(b-a)*i/(n-1)+a<<
std::endl;
return 0;
}
The output of which is:
0: 1 1 1
1: 3 2 2.64865
2: 4 4 4.2973
3: 6 5 5.94595
4: 8 7 7.59459
5: 9 9 9.24324
6: 11 10 10.8919
7: 13 12 12.5405
8: 14 14 14.1892
9: 16 15 15.8378
10: 17 17 17.4865
11: 19 19 19.1351
12: 21 20 20.7838
13: 22 22 22.4324
14: 24 24 24.0811
15: 26 25 25.7297
16: 27 27 27.3784
17: 29 29 29.027
18: 31 30 30.6757
19: 32 32 32.3243
20: 34 33 33.973
21: 36 35 35.6216
22: 37 37 37.2703
23: 39 38 38.9189
24: 41 40 40.5676
25: 42 42 42.2162
26: 44 43 43.8649
27: 46 45 45.5135
28: 47 47 47.1622
29: 49 48 48.8108
30: 50 50 50.4595
31: 52 52 52.1081
32: 54 53 53.7568
33: 55 55 55.4054
34: 57 57 57.0541
35: 59 58 58.7027
36: 60 60 60.3514
37: 62 62 62
38: 64 63 63.6486
39: 65 65 65.2973
40: 67 66 66.9459
41: 69 68 68.5946
42: 70 70 70.2432
43: 72 71 71.8919
44: 74 73 73.5405
45: 75 75 75.1892
46: 77 76 76.8378
47: 78 78 78.4865
48: 80 80 80.1351
49: 82 81 81.7838
50: 83 83 83.4324
51: 85 85 85.0811
52: 87 86 86.7297
53: 88 88 88.3784
54: 90 90 90.027
55: 92 91 91.6757
56: 93 93 93.3243
57: 95 94 94.973
58: 97 96 96.6216
59: 98 98 98.2703
60: 100 99 99.9189
61: 102 101 101.568
62: 103 103 103.216
63: 105 104 104.865
64: 107 106 106.514
65: 108 108 108.162
66: 110 109 109.811
67: 111 111 111.459
68: 113 113 113.108
69: 115 114 114.757
70: 116 116 116.405
71: 118 118 118.054
72: 120 119 119.703
73: 121 121 121.351
74: 123 123 123