--- a/Bezier.st Wed Feb 12 15:17:03 1997 +0100
+++ b/Bezier.st Wed Feb 12 19:15:05 1997 +0100
@@ -222,64 +222,206 @@
addPointsFromStartX:p1X y:p1Y control1X:p2X y:p2Y control2X:p3X y:p3Y endX:p4X y:p4Y to:aCollection
"actual workHorse for point computation"
- |x0 y0 x1 y1 x2 y2 t d dist dx3 dy3
- midX01 midY01 midX12 midY12 x1p y1p xm ym|
+ |x1 y1 x2 y2 x3 y3 t d dist dx3 dy3
+ midX12 midY12 midX23 midY23 x1p y1p xm ym|
+
+%{ /* OPTIONAL */
+
+ /*
+ * easy inlining; all math is done in smallIntegers
+ */
+ if (__bothSmallInteger(p1X, p1Y)
+ && __bothSmallInteger(p2X, p2Y)
+ && __bothSmallInteger(p3X, p3Y)
+ && __bothSmallInteger(p4X, p4Y)
+ && __isSmallInteger(@global(ScaledFlatness))
+ && __isFloat(@global(InverseScale))
+ ) {
+ int _x1 = __intVal(p1X);
+ int _y1 = __intVal(p1Y);
+ int _x2 = __intVal(p2X);
+ int _y2 = __intVal(p2Y);
+ int _x3 = __intVal(p3X);
+ int _y3 = __intVal(p3Y);
+ int _p4X = __intVal(p4X);
+ int _p4Y = __intVal(p4Y);
+ int _flatness = __intVal(@global(ScaledFlatness));
+ double _flatnessD = (double)_flatness;
+ double _invScaleD = __floatVal(@global(InverseScale));
+
+ for (;;) {
+ int _midX12, _midY12, _midX23, _midY23;
+ int _x1p, _y1p, _xm, _ym;
+ extern double sqrt(), ceil(), floor();
+# define round(x) (((x) < 0) ? ceil((x) - 0.5) : floor((x) + 0.5))
+
+ if (_p4X == _x1) {
+ int _dX1, _dX2;
+
+ _dX1 = _x2 - _x1; if (_dX1 < 0) _dX1 = -_dX1;
+ _dX2 = _x3 - _x1; if (_dX2 < 0) _dX2 = -_dX2;
+ if ((_dX1 <= _flatness) && (_dX2 <= _flatness)) break;
+ } else {
+ int _dX3, _dY3, _dX3Abs, _dY3Abs;
+
+ _dX3 = _dX3Abs = (_p4X - _x1); if (_dX3 < 0) _dX3Abs = -_dX3Abs;
+ _dY3 = _dY3Abs = (_p4Y - _y1); if (_dY3 < 0) _dY3Abs = -_dY3Abs;
+
+ if (_dX3Abs >= _dY3Abs) {
+ double _slope = (double)_dY3 / (double)_dX3;
+ double _t;
+ int _d, _dist;
+
+ _t = _slope*_slope + 1.0;
+ _t = sqrt(_t) * _flatnessD;
+ _t = round(_t);
+ _d = _t;
+
+ _t = _slope * (_x2-_x1);
+ _t = round(_t);
+ _dist = _t;
+ _dist -= (_y2-_y1);
+ if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) {
+ _t = _slope * (_x3-_x1);
+ _t = round(_t);
+ _dist = _t;
+ _dist -= (_y3-_y1);
+ if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) break;
+ }
+ } else {
+ double _slope = (double)_dX3 / (double)_dY3;
+ double _t;
+ int _d, _dist;
- x0 := p1X. y0 := p1Y.
- x1 := p2X. y1 := p2Y.
- x2 := p3X. y2 := p3Y.
+ _t = _slope*_slope + 1.0;
+ _t = sqrt(_t) * _flatnessD;
+ _t = round(_t);
+ _d = _t;
+
+ _t = _slope * (_y2-_y1);
+ _t = round(_t);
+ _dist = _t;
+ _dist -= (_x2-_x1);
+ if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) {
+ _t = _slope * (_y3-_y1);
+ _t = round(_t);
+ _dist = _t;
+ _dist -= (_x3-_x1);
+ if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) break;
+ }
+ }
+ }
+
+# undef round
+
+ _midX12 = (_x1 + _x2) / 2;
+ _midY12 = (_y1 + _y2) / 2;
+ _midX23 = (_x2 + _x3) / 2;
+ _midY23 = (_y2 + _y3) / 2;
+
+ _x3 = (_x3 + _p4X) / 2;
+ _y3 = (_y3 + _p4Y) / 2;
+ _x1p = (_midX12 + _midX23) / 2;
+ _y1p = (_midY12 + _midY23) / 2;
+ _x2 = (_midX23 + _x3) / 2;
+ _y2 = (_midY23 + _y3) / 2;
+ _xm = (_x1p + _x2) / 2;
+ _ym = (_y1p + _y2) / 2;
+
+ {
+ static struct inlineCache addPoints = __ILC9(@line);
+
+ (*addPoints.ilc_func)(self,
+ @symbol(addPointsFromStartX:y:control1X:y:control2X:y:endX:y:to:),
+ nil,
+ &addPoints,
+ __MKSMALLINT(_x1), __MKSMALLINT(_y1),
+ __MKSMALLINT(_midX12), __MKSMALLINT(_midY12),
+ __MKSMALLINT(_x1p), __MKSMALLINT(_y1p),
+ __MKSMALLINT(_xm), __MKSMALLINT(_ym),
+ aCollection
+ );
+ }
+
+ _x1 = _xm;
+ _y1 = _ym;
+ }
+ {
+ static struct inlineCache add = __ILC1(@line);
+ OBJ newPoint;
+ double d_x, d_y;
+
+ d_x = _p4X * _invScaleD;
+ d_y = _p4Y * _invScaleD;
+ newPoint = __MKPOINT_DOUBLE( d_x, d_y);
+
+ (*add.ilc_func)(aCollection,
+ @symbol(add:),
+ nil,
+ &add,
+ newPoint
+ );
+ }
+ RETURN (self);
+ }
+%}.
+
+ x1 := p1X. y1 := p1Y.
+ x2 := p2X. y2 := p2Y.
+ x3 := p3X. y3 := p3Y.
[
- p4X = x0 ifTrue:[
- "p4X = x0, i.e. dx = 0"
- (x1 - x0) abs <= ScaledFlatness and: [(x2 - x0) abs <= ScaledFlatness]
+ p4X = x1 ifTrue:[
+ "p4X = x1, i.e. dx = 0"
+ (x2 - x1) abs <= ScaledFlatness and: [(x3 - x1) abs <= ScaledFlatness]
] ifFalse:[
- dx3 := p4X - x0.
- dy3 := p4Y - y0.
+ dx3 := p4X - x1.
+ dy3 := p4Y - y1.
(dx3 >= 0 ifTrue: [dx3] ifFalse: [0 - dx3]) >=
(dy3 >= 0 ifTrue: [dy3] ifFalse: [0 - dy3])
ifTrue:[
t := dy3 asFloat / dx3.
d := ((1.0 + (t * t)) sqrt * ScaledFlatness) rounded.
- dist := (t * (x1 - x0)) rounded - (y1 - y0).
+ dist := (t * (x2 - x1)) rounded - (y2 - y1).
(dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0])
- and:[dist := (t * (x2 - x0)) rounded - (y2 - y0).
+ and:[dist := (t * (x3 - x1)) rounded - (y3 - y1).
dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]]
] ifFalse:[
t := dx3 asFloat / dy3.
d := ((1.0 + (t * t)) sqrt * ScaledFlatness) rounded.
- dist := (t * (y1 - y0)) rounded - (x1 - x0).
+ dist := (t * (y2 - y1)) rounded - (x2 - x1).
(dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0])
- and:[dist := (t * (y2 - y0)) rounded - (x2 - x0).
+ and:[dist := (t * (y3 - y1)) rounded - (x3 - x1).
dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]]
]
]
] whileFalse:[
- midX01 := (x0 + x1) // 2.
- midY01 := (y0 + y1) // 2.
midX12 := (x1 + x2) // 2.
midY12 := (y1 + y2) // 2.
+ midX23 := (x2 + x3) // 2.
+ midY23 := (y2 + y3) // 2.
- x2 := (x2 + p4X) // 2.
- y2 := (y2 + p4Y) // 2.
- x1p := (midX01 + midX12) // 2.
- y1p := (midY01 + midY12) // 2.
- x1 := (midX12 + x2) // 2.
- y1 := (midY12 + y2) // 2.
- xm := (x1p + x1) // 2.
- ym := (y1p + y1) // 2.
+ x3 := (x3 + p4X) // 2.
+ y3 := (y3 + p4Y) // 2.
+ x1p := (midX12 + midX23) // 2.
+ y1p := (midY12 + midY23) // 2.
+ x2 := (midX23 + x3) // 2.
+ y2 := (midY23 + y3) // 2.
+ xm := (x1p + x2) // 2.
+ ym := (y1p + y2) // 2.
self
- addPointsFromStartX:x0 y:y0
- control1X:midX01 y:midY01
+ addPointsFromStartX:x1 y:y1
+ control1X:midX12 y:midY12
control2X:x1p y:y1p
endX:xm y:ym
to:aCollection.
- x0 := xm.
- y0 := ym.
+ x1 := xm.
+ y1 := ym.
].
+
aCollection add: (p4X asFloat * InverseScale) @ (p4Y asFloat * InverseScale)
"Created: 12.2.1997 / 15:05:52 / cg"
@@ -367,6 +509,6 @@
!Bezier class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/Bezier.st,v 1.1 1997-02-12 14:17:03 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/Bezier.st,v 1.2 1997-02-12 18:15:05 cg Exp $'
! !
Bezier initialize!