|
@@ -1 +1,655 @@
|
|
|
-class DMatrix {}
|
|
|
+import 'dart:math' as math;
|
|
|
+
|
|
|
+import 'point.dart';
|
|
|
+import 'sr_segment_infos.dart';
|
|
|
+import 'vector.dart';
|
|
|
+
|
|
|
+enum MatrixTypes {
|
|
|
+ transformIsIdentity,
|
|
|
+ transformIsTranslation,
|
|
|
+ transformIsScaling,
|
|
|
+ placeholder3,
|
|
|
+ transformIsUnknown,
|
|
|
+}
|
|
|
+
|
|
|
+extension _MatrixTypesExt on MatrixTypes {
|
|
|
+ MatrixTypes operator |(MatrixTypes other) {
|
|
|
+ final idx = index | other.index;
|
|
|
+ return MatrixTypes.values[idx];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class DMatrix {
|
|
|
+ static DMatrix identity = DMatrix()
|
|
|
+ ..setMatrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, MatrixTypes.transformIsIdentity);
|
|
|
+
|
|
|
+ /* Private Fields */
|
|
|
+
|
|
|
+ double _m11 = 0.0;
|
|
|
+ double _m12 = 0.0;
|
|
|
+ double _m21 = 0.0;
|
|
|
+ double _m22 = 0.0;
|
|
|
+ double _offsetX = 0.0;
|
|
|
+ double _offsetY = 0.0;
|
|
|
+ MatrixTypes _type = MatrixTypes.transformIsIdentity;
|
|
|
+ int _padding = 0;
|
|
|
+
|
|
|
+/* Contructions */
|
|
|
+
|
|
|
+ DMatrix();
|
|
|
+
|
|
|
+ factory DMatrix.fill(
|
|
|
+ double m11,
|
|
|
+ double m12,
|
|
|
+ double m21,
|
|
|
+ double m22,
|
|
|
+ double offsetX,
|
|
|
+ double offsetY,
|
|
|
+ ) {
|
|
|
+ final m = DMatrix();
|
|
|
+ m._m11 = m11;
|
|
|
+ m._m12 = m12;
|
|
|
+ m._m21 = m21;
|
|
|
+ m._m22 = m22;
|
|
|
+ m._offsetX = offsetX;
|
|
|
+ m._offsetY = offsetY;
|
|
|
+ m._type = MatrixTypes.transformIsUnknown;
|
|
|
+ m._padding = 0;
|
|
|
+ m._deriveMatrixType();
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+/* Properties */
|
|
|
+
|
|
|
+ bool get _isDistinguishedIdentity => _type == MatrixTypes.transformIsIdentity;
|
|
|
+ bool get isIdentity {
|
|
|
+ if ((_type == MatrixTypes.transformIsIdentity)) return true;
|
|
|
+ final idM1 = (_m11 == 1.0) && (_m12 == 0.0);
|
|
|
+ final idM2 = (_m21 == 0.0) && (_m22 == 1.0);
|
|
|
+ return (idM1 && idM2) && (_offsetX == 0.0) && (_offsetY == 0.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ double get m11 {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 1.0;
|
|
|
+ }
|
|
|
+ return _m11;
|
|
|
+ }
|
|
|
+
|
|
|
+ set m11(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(value, 0.0, 0.0, 1.0, 0.0, 0.0, MatrixTypes.transformIsScaling);
|
|
|
+ } else {
|
|
|
+ _m11 = value;
|
|
|
+ if (_type != MatrixTypes.transformIsUnknown) {
|
|
|
+ _type = _type |= MatrixTypes.transformIsScaling;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get m12 {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return _m12;
|
|
|
+ }
|
|
|
+
|
|
|
+ set m12(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(1.0, value, 0.0, 1.0, 0.0, 0.0, MatrixTypes.transformIsUnknown);
|
|
|
+ } else {
|
|
|
+ _m12 = value;
|
|
|
+ _type = MatrixTypes.transformIsUnknown;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get m21 {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return _m21;
|
|
|
+ }
|
|
|
+
|
|
|
+ set m21(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(1.0, 0.0, value, 1.0, 0.0, 0.0, MatrixTypes.transformIsUnknown);
|
|
|
+ } else {
|
|
|
+ _m21 = value;
|
|
|
+ _type = MatrixTypes.transformIsUnknown;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get m22 {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 1.0;
|
|
|
+ }
|
|
|
+ return _m22;
|
|
|
+ }
|
|
|
+
|
|
|
+ set m22(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(1.0, 0.0, 0.0, value, 0.0, 0.0, MatrixTypes.transformIsScaling);
|
|
|
+ } else {
|
|
|
+ _m22 = value;
|
|
|
+ if (_type != MatrixTypes.transformIsUnknown) {
|
|
|
+ _type |= MatrixTypes.transformIsScaling;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get offsetX {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return _offsetX;
|
|
|
+ }
|
|
|
+
|
|
|
+ set offsetX(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(
|
|
|
+ 1.0, 0.0, 0.0, 1.0, value, 0.0, MatrixTypes.transformIsTranslation);
|
|
|
+ } else {
|
|
|
+ _offsetX = value;
|
|
|
+ if (_type != MatrixTypes.transformIsUnknown) {
|
|
|
+ _type |= MatrixTypes.transformIsTranslation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get offsetY {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return _offsetY;
|
|
|
+ }
|
|
|
+
|
|
|
+ set offsetY(double value) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(
|
|
|
+ 1.0, 0.0, 0.0, 1.0, 0.0, value, MatrixTypes.transformIsTranslation);
|
|
|
+ } else {
|
|
|
+ _offsetY = value;
|
|
|
+ if (_type != MatrixTypes.transformIsUnknown) {
|
|
|
+ _type |= MatrixTypes.transformIsTranslation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get determinant {
|
|
|
+ switch (_type) {
|
|
|
+ case MatrixTypes.transformIsIdentity:
|
|
|
+ case MatrixTypes.transformIsTranslation:
|
|
|
+ return 1.0;
|
|
|
+
|
|
|
+ case MatrixTypes.transformIsScaling:
|
|
|
+ case MatrixTypes.placeholder3:
|
|
|
+ //(MatrixTypes.TRANSFORM_IS_SCALING | MatrixTypes.TRANSFORM_IS_TRANSLATION)
|
|
|
+ return (_m11 * _m22);
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return (_m11 * _m22) - (_m12 * _m21);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool get hasInverse {
|
|
|
+ return !_DoubleUtil.isZero(determinant);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Public Methods */
|
|
|
+
|
|
|
+ void invert() {
|
|
|
+ if (_DoubleUtil.isZero(determinant)) {
|
|
|
+ throw Exception("Transform_NotInvertible");
|
|
|
+ }
|
|
|
+ switch (_type) {
|
|
|
+ case MatrixTypes.transformIsIdentity:
|
|
|
+ break;
|
|
|
+ case MatrixTypes.transformIsTranslation:
|
|
|
+ _offsetX = -_offsetX;
|
|
|
+ _offsetY = -_offsetY;
|
|
|
+ return;
|
|
|
+ case MatrixTypes.transformIsScaling:
|
|
|
+ _m11 = 1.0 / _m11;
|
|
|
+ _m22 = 1.0 / _m22;
|
|
|
+ return;
|
|
|
+ case MatrixTypes.placeholder3:
|
|
|
+ //(MatrixTypes.TRANSFORM_IS_SCALING | MatrixTypes.TRANSFORM_IS_TRANSLATION)
|
|
|
+ _m11 = 1.0 / _m11;
|
|
|
+ _m22 = 1.0 / _m22;
|
|
|
+ _offsetX = -_offsetX * _m11;
|
|
|
+ _offsetY = -_offsetY * _m22;
|
|
|
+ return;
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ double num2 = 1.0 / determinant;
|
|
|
+ setMatrix(
|
|
|
+ _m22 * num2,
|
|
|
+ -_m12 * num2,
|
|
|
+ -_m21 * num2,
|
|
|
+ _m11 * num2,
|
|
|
+ ((_m21 * _offsetY) - (_offsetX * _m22)) * num2,
|
|
|
+ ((_offsetX * _m12) - (_m11 * _offsetY)) * num2,
|
|
|
+ MatrixTypes.transformIsUnknown,
|
|
|
+ );
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void multiplyVector(DVector vector) {
|
|
|
+ double x = vector.x;
|
|
|
+ double y = vector.y;
|
|
|
+ switch (_type) {
|
|
|
+ case MatrixTypes.transformIsIdentity:
|
|
|
+ case MatrixTypes.transformIsTranslation:
|
|
|
+ return;
|
|
|
+
|
|
|
+ case MatrixTypes.transformIsScaling:
|
|
|
+ case MatrixTypes
|
|
|
+ .placeholder3: // MatrixTypes.transformIsScaling | MatrixTypes.transformIsTranslation;
|
|
|
+ x *= _m11;
|
|
|
+ y *= _m22;
|
|
|
+ return;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ double num = y * _m21;
|
|
|
+ double num2 = x * _m12;
|
|
|
+ x *= _m11;
|
|
|
+ x += num;
|
|
|
+ y *= _m22;
|
|
|
+ y += num2;
|
|
|
+ vector.x = x;
|
|
|
+ vector.y = y;
|
|
|
+ }
|
|
|
+
|
|
|
+ void multiplyPoint(DPoint point) {
|
|
|
+ double x = point.x;
|
|
|
+ double y = point.y;
|
|
|
+ switch (_type) {
|
|
|
+ case MatrixTypes.transformIsIdentity:
|
|
|
+ return;
|
|
|
+
|
|
|
+ case MatrixTypes.transformIsTranslation:
|
|
|
+ x += _offsetX;
|
|
|
+ y += _offsetY;
|
|
|
+ return;
|
|
|
+
|
|
|
+ case MatrixTypes.transformIsScaling:
|
|
|
+ x *= _m11;
|
|
|
+ y *= _m22;
|
|
|
+ return;
|
|
|
+
|
|
|
+ case MatrixTypes
|
|
|
+ .placeholder3: // MatrixTypes.transformIsScaling | MatrixTypes.transformIsTranslation;
|
|
|
+ x *= _m11;
|
|
|
+ x += _offsetX;
|
|
|
+ y *= _m22;
|
|
|
+ y += _offsetY;
|
|
|
+ return;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ double num = (y * _m21) + _offsetX;
|
|
|
+ double num2 = (x * _m12) + _offsetY;
|
|
|
+ x *= _m11;
|
|
|
+ x += num;
|
|
|
+ y *= _m22;
|
|
|
+ y += num2;
|
|
|
+ point.x = x;
|
|
|
+ point.y = y;
|
|
|
+ }
|
|
|
+
|
|
|
+ void setMatrix(
|
|
|
+ double m11,
|
|
|
+ double m12,
|
|
|
+ double m21,
|
|
|
+ double m22,
|
|
|
+ double offsetX,
|
|
|
+ double offsetY,
|
|
|
+ MatrixTypes type,
|
|
|
+ ) {
|
|
|
+ _m11 = m11;
|
|
|
+ _m12 = m12;
|
|
|
+ _m21 = m21;
|
|
|
+ _m22 = m22;
|
|
|
+ _offsetX = offsetX;
|
|
|
+ _offsetY = offsetY;
|
|
|
+ _type = type;
|
|
|
+ }
|
|
|
+
|
|
|
+ void copyFrom(DMatrix other) {
|
|
|
+ setMatrix(
|
|
|
+ other.m11,
|
|
|
+ other.m12,
|
|
|
+ other.m21,
|
|
|
+ other.m22,
|
|
|
+ other.offsetX,
|
|
|
+ other.offsetY,
|
|
|
+ other._type,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ void skew(double skewX, double skewY) {
|
|
|
+ skewX = skewX % 360.0;
|
|
|
+ skewY = skewY % 360.0;
|
|
|
+ final radians = createSkewRadians(
|
|
|
+ skewX * 0.017453292519943295,
|
|
|
+ skewY * 0.017453292519943295,
|
|
|
+ );
|
|
|
+ final outcome = this * radians;
|
|
|
+ copyFrom(outcome);
|
|
|
+ }
|
|
|
+
|
|
|
+ void apppend(DMatrix matrix) {
|
|
|
+ final outcome = this * matrix;
|
|
|
+ copyFrom(outcome);
|
|
|
+ }
|
|
|
+
|
|
|
+ void rotateAt(double angle, double centerX, double centerY) {
|
|
|
+ angle = angle % 360.0;
|
|
|
+ final outcome = this *
|
|
|
+ createRotationRadiansAt(
|
|
|
+ angle * 0.017453292519943295,
|
|
|
+ centerX,
|
|
|
+ centerY,
|
|
|
+ );
|
|
|
+ copyFrom(outcome);
|
|
|
+ }
|
|
|
+
|
|
|
+ void scale(double scaleX, double scaleY) {
|
|
|
+ final outcome = this * createScaling(scaleX, scaleY);
|
|
|
+ copyFrom(outcome);
|
|
|
+ }
|
|
|
+
|
|
|
+ void scaleAt(
|
|
|
+ double scaleX,
|
|
|
+ double scaleY,
|
|
|
+ double centerX,
|
|
|
+ double centerY,
|
|
|
+ ) {
|
|
|
+ final outcome = this * createScalingAt(scaleX, scaleY, centerX, centerY);
|
|
|
+ copyFrom(outcome);
|
|
|
+ }
|
|
|
+
|
|
|
+ void translate(double offsetX, double offsetY) {
|
|
|
+ if (_type == MatrixTypes.transformIsIdentity) {
|
|
|
+ setMatrix(
|
|
|
+ 1.0,
|
|
|
+ 0.0,
|
|
|
+ 0.0,
|
|
|
+ 1.0,
|
|
|
+ offsetX,
|
|
|
+ offsetY,
|
|
|
+ MatrixTypes.transformIsTranslation,
|
|
|
+ );
|
|
|
+ } else if (_type == MatrixTypes.transformIsUnknown) {
|
|
|
+ _offsetX += offsetX;
|
|
|
+ _offsetY += offsetY;
|
|
|
+ } else {
|
|
|
+ _offsetX += offsetX;
|
|
|
+ _offsetY += offsetY;
|
|
|
+ _type |= MatrixTypes.transformIsTranslation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DPoint transformWidthPoint(DPoint point) {
|
|
|
+ DPoint point2 = point;
|
|
|
+ multiplyPoint(point2);
|
|
|
+ return point2;
|
|
|
+ }
|
|
|
+
|
|
|
+ VecPoint transformWithVecPoint(VecPoint point) {
|
|
|
+ final vPoint = VecPoint();
|
|
|
+ final dPoint = DPoint(point.x, point.y);
|
|
|
+ multiplyPoint(dPoint);
|
|
|
+ final ddPoint = DPoint(point.x + point.dx, point.y + point.dy);
|
|
|
+ multiplyPoint(ddPoint);
|
|
|
+ vPoint.x = dPoint.x;
|
|
|
+ vPoint.y = dPoint.y;
|
|
|
+ vPoint.dx = ddPoint.x - dPoint.x;
|
|
|
+ vPoint.dy = ddPoint.y - dPoint.y;
|
|
|
+ return vPoint;
|
|
|
+ }
|
|
|
+
|
|
|
+ void transformWithPoints(List<DPoint>? points) {
|
|
|
+ if (points != null) {
|
|
|
+ for (int i = 0; i < points.length; i++) {
|
|
|
+ multiplyPoint(points[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DVector transformWithVector(DVector vector) {
|
|
|
+ DVector vector2 = vector;
|
|
|
+ multiplyVector(vector2);
|
|
|
+ return vector2;
|
|
|
+ }
|
|
|
+
|
|
|
+ void transformWithVectors(List<DVector>? vectors) {
|
|
|
+ if (vectors != null) {
|
|
|
+ for (int i = 0; i < vectors.length; i++) {
|
|
|
+ multiplyVector(vectors[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Public Static Methods */
|
|
|
+
|
|
|
+ static DMatrix createRotationRadians(double angle) {
|
|
|
+ return createRotationRadiansAt(angle, 0.0, 0.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ static DMatrix createRotationRadiansAt(
|
|
|
+ double angle,
|
|
|
+ double centerX,
|
|
|
+ double centerY,
|
|
|
+ ) {
|
|
|
+ DMatrix matrix = DMatrix();
|
|
|
+ double num = math.sin(angle);
|
|
|
+ double num2 = math.cos(angle);
|
|
|
+ double offsetX = (centerX * (1.0 - num2)) + (centerY * num);
|
|
|
+ double offsetY = (centerY * (1.0 - num2)) - (centerX * num);
|
|
|
+ matrix.setMatrix(
|
|
|
+ num2,
|
|
|
+ num,
|
|
|
+ -num,
|
|
|
+ num2,
|
|
|
+ offsetX,
|
|
|
+ offsetY,
|
|
|
+ MatrixTypes.transformIsUnknown,
|
|
|
+ );
|
|
|
+ return matrix;
|
|
|
+ }
|
|
|
+
|
|
|
+ static DMatrix createScalingAt(
|
|
|
+ double scaleX,
|
|
|
+ double scaleY,
|
|
|
+ double centerX,
|
|
|
+ double centerY,
|
|
|
+ ) {
|
|
|
+ DMatrix matrix = DMatrix();
|
|
|
+ matrix.setMatrix(
|
|
|
+ scaleX,
|
|
|
+ 0.0,
|
|
|
+ 0.0,
|
|
|
+ scaleY,
|
|
|
+ centerX - (scaleX * centerX),
|
|
|
+ centerY - (scaleY * centerY),
|
|
|
+ MatrixTypes.transformIsScaling | MatrixTypes.transformIsTranslation,
|
|
|
+ );
|
|
|
+ return matrix;
|
|
|
+ }
|
|
|
+
|
|
|
+ static DMatrix createScaling(double scaleX, double scaleY) {
|
|
|
+ DMatrix matrix = DMatrix();
|
|
|
+ matrix.setMatrix(
|
|
|
+ scaleX,
|
|
|
+ 0.0,
|
|
|
+ 0.0,
|
|
|
+ scaleY,
|
|
|
+ 0.0,
|
|
|
+ 0.0,
|
|
|
+ MatrixTypes.transformIsScaling,
|
|
|
+ );
|
|
|
+ return matrix;
|
|
|
+ }
|
|
|
+
|
|
|
+ static DMatrix createSkewRadians(double skewX, double skewY) {
|
|
|
+ final matrix = DMatrix()
|
|
|
+ ..setMatrix(
|
|
|
+ 1.0,
|
|
|
+ math.tan(skewY),
|
|
|
+ math.tan(skewX),
|
|
|
+ 1.0,
|
|
|
+ 0.0,
|
|
|
+ 0.0,
|
|
|
+ MatrixTypes.transformIsUnknown,
|
|
|
+ );
|
|
|
+ return matrix;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Operators & Override methods */
|
|
|
+
|
|
|
+ DMatrix operator *(DMatrix other) {
|
|
|
+ MatrixUtil.multiplyMatrix(this, other);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool operator ==(Object other) {
|
|
|
+ if (other is DMatrix) {
|
|
|
+ if (_isDistinguishedIdentity || other._isDistinguishedIdentity) {
|
|
|
+ return (isIdentity == other.isIdentity);
|
|
|
+ }
|
|
|
+ final m1Equals = (m11 == other.m11) && (m12 == other.m12);
|
|
|
+ final m2Equals = (m21 == other.m21) && (m22 == other.m22);
|
|
|
+ return (m1Equals && m2Equals) &&
|
|
|
+ (offsetX == other.offsetX) &&
|
|
|
+ (offsetY == other.offsetY);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ int get hashCode {
|
|
|
+ if (_isDistinguishedIdentity) return 0;
|
|
|
+ return (((((m11.hashCode ^ m12.hashCode) ^ m21.hashCode) ^ m22.hashCode) ^
|
|
|
+ offsetX.hashCode) ^
|
|
|
+ offsetY.hashCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ void _deriveMatrixType() {
|
|
|
+ _type = MatrixTypes.transformIsIdentity;
|
|
|
+ if ((_m21 != 0.0) || (_m12 != 0.0)) {
|
|
|
+ _type = MatrixTypes.transformIsUnknown;
|
|
|
+ } else {
|
|
|
+ if ((_m11 != 1.0) || (_m22 != 1.0)) {
|
|
|
+ _type = MatrixTypes.transformIsScaling;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((_offsetX != 0.0) || (_offsetY != 0.0)) {
|
|
|
+ var typeIdx = _type.index;
|
|
|
+ typeIdx |= MatrixTypes.transformIsTranslation.index;
|
|
|
+ _type = MatrixTypes.values[typeIdx];
|
|
|
+ }
|
|
|
+ if ((_type.index &
|
|
|
+ (MatrixTypes.transformIsScaling.index |
|
|
|
+ MatrixTypes.transformIsTranslation.index)) ==
|
|
|
+ MatrixTypes.transformIsIdentity.index) {
|
|
|
+ _type = MatrixTypes.transformIsIdentity;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class MatrixUtil {
|
|
|
+ static void multiplyMatrix(DMatrix matrix1, DMatrix matrix2) {
|
|
|
+ MatrixTypes types = matrix1._type;
|
|
|
+ MatrixTypes types2 = matrix2._type;
|
|
|
+ if (types2 != MatrixTypes.transformIsIdentity) {
|
|
|
+ if (types == MatrixTypes.transformIsIdentity) {
|
|
|
+ matrix1 = matrix2;
|
|
|
+ } else if (types2 == MatrixTypes.transformIsTranslation) {
|
|
|
+ matrix1._offsetX += matrix2._offsetX;
|
|
|
+ matrix1._offsetY += matrix2._offsetY;
|
|
|
+ if (types != MatrixTypes.transformIsUnknown) {
|
|
|
+ matrix1._type |= MatrixTypes.values[1];
|
|
|
+ //*((int*)&matrix1._type) |= 1;
|
|
|
+ }
|
|
|
+ } else if (types == MatrixTypes.transformIsTranslation) {
|
|
|
+ double num2 = matrix1._offsetX;
|
|
|
+ double num3 = matrix1._offsetY;
|
|
|
+ matrix1 = matrix2;
|
|
|
+ matrix1._offsetX =
|
|
|
+ ((num2 * matrix2._m11) + (num3 * matrix2._m21)) + matrix2._offsetX;
|
|
|
+ matrix1._offsetY =
|
|
|
+ ((num2 * matrix2._m12) + (num3 * matrix2._m22)) + matrix2._offsetY;
|
|
|
+ if (types2 == MatrixTypes.transformIsUnknown) {
|
|
|
+ matrix1._type = MatrixTypes.transformIsUnknown;
|
|
|
+ } else {
|
|
|
+ matrix1._type = MatrixTypes.transformIsUnknown |
|
|
|
+ MatrixTypes.transformIsTranslation;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ final typeIdx = (types.index << 4) | types2.index;
|
|
|
+ switch (typeIdx) {
|
|
|
+ case 0x22:
|
|
|
+ matrix1._m11 *= matrix2._m11;
|
|
|
+ matrix1._m22 *= matrix2._m22;
|
|
|
+ return;
|
|
|
+
|
|
|
+ case 0x23:
|
|
|
+ matrix1._m11 *= matrix2._m11;
|
|
|
+ matrix1._m22 *= matrix2._m22;
|
|
|
+ matrix1._offsetX = matrix2._offsetX;
|
|
|
+ matrix1._offsetY = matrix2._offsetY;
|
|
|
+ matrix1._type = MatrixTypes.transformIsScaling |
|
|
|
+ MatrixTypes.transformIsTranslation;
|
|
|
+ return;
|
|
|
+
|
|
|
+ case 0x24:
|
|
|
+ case 0x34:
|
|
|
+ case 0x42:
|
|
|
+ case 0x43:
|
|
|
+ case 0x44:
|
|
|
+ matrix1 = DMatrix.fill(
|
|
|
+ (matrix1._m11 * matrix2._m11) + (matrix1._m12 * matrix2._m21),
|
|
|
+ (matrix1._m11 * matrix2._m12) + (matrix1._m12 * matrix2._m22),
|
|
|
+ (matrix1._m21 * matrix2._m11) + (matrix1._m22 * matrix2._m21),
|
|
|
+ (matrix1._m21 * matrix2._m12) + (matrix1._m22 * matrix2._m22),
|
|
|
+ ((matrix1._offsetX * matrix2._m11) +
|
|
|
+ (matrix1._offsetY * matrix2._m21)) +
|
|
|
+ matrix2._offsetX,
|
|
|
+ ((matrix1._offsetX * matrix2._m12) +
|
|
|
+ (matrix1._offsetY * matrix2._m22)) +
|
|
|
+ matrix2._offsetY,
|
|
|
+ );
|
|
|
+ return;
|
|
|
+
|
|
|
+ case 50:
|
|
|
+ matrix1._m11 *= matrix2._m11;
|
|
|
+ matrix1._m22 *= matrix2._m22;
|
|
|
+ matrix1._offsetX *= matrix2._m11;
|
|
|
+ matrix1._offsetY *= matrix2._m22;
|
|
|
+ return;
|
|
|
+
|
|
|
+ case 0x33:
|
|
|
+ matrix1._m11 *= matrix2._m11;
|
|
|
+ matrix1._m22 *= matrix2._m22;
|
|
|
+ matrix1._offsetX =
|
|
|
+ (matrix2._m11 * matrix1._offsetX) + matrix2._offsetX;
|
|
|
+ matrix1._offsetY =
|
|
|
+ (matrix2._m22 * matrix1._offsetY) + matrix2._offsetY;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class _DoubleUtil {
|
|
|
+ static bool isZero(double value) {
|
|
|
+ return (value.abs() < 2.2204460492503131E-15);
|
|
|
+ }
|
|
|
+}
|