@@ -54,25 +54,99 @@ class Rectangle {
54
54
}
55
55
}
56
56
57
- initFromMatrixRadius ( m , r ) {
58
- // const v0 = r;
59
- // const v1 = r;
60
- // const v2 = r;
57
+ /**
58
+ * Initialize a Rectangle to a 1 unit square transformed by a model matrix.
59
+ * @param {Array.<number> } m A 4x4 matrix to transform the rectangle by.
60
+ */
61
+ initFromModelMatrix ( m ) {
62
+ // Treat this function like we are transforming a vector with each
63
+ // component set to 0.5 by a matrix m.
64
+ // const v0 = 0.5;
65
+ // const v1 = 0.5;
66
+ // const v2 = 0.5;
67
+
68
+ // Of the matrix to do this in 2D space, instead of the 3D provided by
69
+ // the matrix, we need the 2x2 "top left" that represents the scale and
70
+ // rotation ...
61
71
const m00 = m [ ( 0 * 4 ) + 0 ] ;
62
72
const m01 = m [ ( 0 * 4 ) + 1 ] ;
63
73
const m10 = m [ ( 1 * 4 ) + 0 ] ;
64
74
const m11 = m [ ( 1 * 4 ) + 1 ] ;
75
+ // ... and the 1x2 "top right" that represents position.
65
76
const m30 = m [ ( 3 * 4 ) + 0 ] ;
66
77
const m31 = m [ ( 3 * 4 ) + 1 ] ;
67
- // var d = v0 * m03 + v1 * m13 + v2 * m23 + m33;
68
- // dst[0] = (
69
- const x = Math . abs ( r * m00 ) + Math . abs ( r * m10 ) ;
70
- // + v2 * m20 + m30) / d;
71
- // dst[1] = (
72
- const y = Math . abs ( r * m01 ) + Math . abs ( r * m11 ) ;
73
- // + v2 * m21 + m31) / d;
74
- // dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / d;
75
78
79
+ // This is how we would normally transform the vector by the matrix.
80
+ // var determinant = v0 * m03 + v1 * m13 + v2 * m23 + m33;
81
+ // dst[0] = (v0 * m00 + v1 * m10 + v2 * m20 + m30) / determinant;
82
+ // dst[1] = (v0 * m01 + v1 * m11 + v2 * m21 + m31) / determinant;
83
+ // dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / determinant;
84
+
85
+ // We can skip the v2 multiplications and the determinant.
86
+
87
+ // Alternatively done with 4 vectors, those vectors would be reflected
88
+ // on the x and y axis. We can build those 4 vectors by transforming the
89
+ // parts of one vector and reflecting them on the axises after
90
+ // multiplication.
91
+
92
+ // const x0 = 0.5 * m00;
93
+ // const x1 = 0.5 * m10;
94
+ // const y0 = 0.5 * m01;
95
+ // const y1 = 0.5 * m11;
96
+
97
+ // const p0x = x0 + -x1;
98
+ // const p0y = y0 + y1;
99
+ // const p1x = -x0 + -x1;
100
+ // const p1y = -y0 + y1;
101
+ // const p2x = -x0 + x1;
102
+ // const p2y = -y0 + -y1;
103
+ // const p3x = x0 + x1;
104
+ // const p3y = y0 + -y1;
105
+
106
+ // Since we want to reduce those 4 points to a min and max for each
107
+ // axis, we can use those multiplied components to build the min and max
108
+ // values without comparing the points.
109
+
110
+ // We can start by getting the min and max for each of all the points.
111
+ // const left = Math.min(x0 + -x1, -x0 + -x1, -x0 + x1, x0 + x1);
112
+ // const right = Math.max(x0 + -x1, -x0 + -x1, -x0 + x1, x0 + x1);
113
+ // const top = Math.max(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
114
+ // const bottom = Math.min(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
115
+
116
+ // Each of those can be replaced with min and max operations on the 0
117
+ // and 1 matrix output components.
118
+ // const left = Math.min(x0, -x0) + Math.min(x1, -x1);
119
+ // const right = Math.max(x0, -x0) + Math.max(x1, -x1);
120
+ // const top = Math.max(y0, -y0) + Math.max(y1, -y1);
121
+ // const bottom = Math.min(y0, -y0) + Math.min(y1, -y1);
122
+
123
+ // And they can be replaced with absolute values.
124
+ // const left = -Math.abs(x0) + -Math.abs(x1);
125
+ // const right = Math.abs(x0) + Math.abs(x1);
126
+ // const top = Math.abs(y0) + Math.abs(y1);
127
+ // const bottom = -Math.abs(y0) + -Math.abs(y1);
128
+
129
+ // And those with positive and negative sums of the absolute values.
130
+ // const left = -(Math.abs(x0) + Math.abs(x1));
131
+ // const right = +(Math.abs(x0) + Math.abs(x1));
132
+ // const top = +(Math.abs(y0) + Math.abs(y1));
133
+ // const bottom = -(Math.abs(y0) + -Math.abs(y1));
134
+
135
+ // We can perform those sums once and reuse them for the bounds.
136
+ // const x = Math.abs(x0) + Math.abs(x1);
137
+ // const y = Math.abs(y0) + Math.abs(y1);
138
+ // const left = -x;
139
+ // const right = x;
140
+ // const top = y;
141
+ // const bottom = -y;
142
+
143
+ // Building those absolute sums for the 0.5 vector components by the
144
+ // matrix components ...
145
+ const x = Math . abs ( 0.5 * m00 ) + Math . abs ( 0.5 * m10 ) ;
146
+ const y = Math . abs ( 0.5 * m01 ) + Math . abs ( 0.5 * m11 ) ;
147
+
148
+ // And adding them to the position components in the matrices
149
+ // initializes our Rectangle.
76
150
this . left = - x + m30 ;
77
151
this . right = x + m30 ;
78
152
this . top = y + m31 ;
0 commit comments