1 package fi.jyu.mit.graphics;
2 import static java.lang.Math.round;
3
4
10 public class Matrix {
11
12 protected final static int VSIZE = 4;
13 private double mat[][] = new double[VSIZE][VSIZE];
14 private Matrix inversion;
15
16
19 public Matrix() {
20 this.ident();
21 }
22
23
27 public Matrix(Matrix M) {
28 for (int r = 0; r < VSIZE; r++)
29 for (int s = 0; s < VSIZE; s++)
30 mat[r][s] = M.mat[r][s];
31 }
32
33
36 protected final void ident() {
37 this.inversion = null;
38 for (int r = 0; r < VSIZE; r++)
39 for (int s = 0; s < VSIZE; s++)
40 mat[r][s] = 0.0;
41 for (int r = 0; r < VSIZE; r++)
42 mat[r][r] = 1.0;
43 }
44
45
50 public Vector row(int r) { Vector v = new Vector(); for (int s = 0; s < VSIZE; s++) {
53 v.set(s, mat[r][s]);
54 }
55 return v;
56 }
57
58
63 public Vector column(int s) { Vector v = new Vector(); for (int r = 0; r < VSIZE; r++) {
66 v.set(r, mat[r][s]);
67 }
68 return v;
69 }
70
71
76 public void setRow(int r, Vector v) {
77 this.inversion = null;
78 for (int i = 0; i < VSIZE; i++)
79 mat[r][i] = v.a(i);
80 }
81
82
87 public void setColumn(int s, Vector v) {
88 this.inversion = null;
89 for (int i = 0; i < VSIZE; i++)
90 mat[i][s] = v.a(i);
91 }
92
93
99 public double m(int r, int s) { return mat[r][s];
101 }
102
103
109 protected void set(int r, int s, double d) {
110 this.inversion = null;
111 mat[r][s] = d;
112 }
113
114
119 public Matrix multiply(Matrix b) {
120 if ( b == null ) return this;
121 return multiply(b,new Matrix());
122 }
123
124
131 public Matrix multiply(Matrix b, Matrix c) {
132 for (int r = 0; r < VSIZE; r++)
134 for (int s = 0; s < VSIZE; s++) {
135 double sum = 0;
136 for (int i = 0; i < VSIZE; i++)
137 sum += mat[r][i] * b.mat[i][s];
138 c.mat[r][s] = sum;
139 }
140 return c;
141 }
142
143
148 public Matrix multiplyThis(Matrix b) {
149 this.inversion = null;
150 double row[] = {0,0,0,0};
151 for (int r = 0; r < VSIZE; r++) {
152 for (int s = 0; s < VSIZE; s++) {
153 double sum = 0;
154 for (int i = 0; i < VSIZE; i++)
155 sum += mat[r][i] * b.mat[i][s];
156 row[s] = sum;
157 }
158 for (int s = 0; s < VSIZE; s++)
159 mat[r][s] = row[s];
160 }
161 return this;
162 }
163
164
170 public Matrix multiplyThis(Matrix b,double row[]) {
171 this.inversion = null;
172 for (int r = 0; r < VSIZE; r++) {
174 for (int s = 0; s < VSIZE; s++) {
175 double sum = 0;
176 for (int i = 0; i < VSIZE; i++)
177 sum += mat[r][i] * b.mat[i][s];
178 row[s] = sum;
179 }
180 for (int s = 0; s < VSIZE; s++)
181 mat[r][s] = row[s];
182 }
183 return this;
184 }
185
186
191 public Vector multiply(Vector b) { Vector y = new Vector(); for (int r = 0; r < VSIZE; r++) {
194 double sum = 0;
195 for (int s = 0; s < VSIZE; s++)
196 sum += mat[r][s] * b.a(s);
197 y.set(r, sum );
198 }
199 return y;
200 }
201
202
208 public Vector multiply(Vector b, Vector y) { for (int r = 0; r < VSIZE; r++) {
210 double sum = 0;
211 for (int s = 0; s < VSIZE; s++)
212 sum += mat[r][s] * b.a(s);
213 y.set(r, sum );
214 }
215 return y;
216 }
217
218
226 public SPoint transform(Vector b, SPoint iy) { double sum0 = 0, sum1 = 0;
228 for (int s = 0; s < VSIZE; s++) sum0 += mat[0][s] * b.a(s);
229 for (int s = 0; s < VSIZE; s++) sum1 += mat[1][s] * b.a(s);
230 return iy.set((int)round(sum0), (int)round(sum1));
234 }
235
236
244 public RPoint transform(Vector b, RPoint iy) { double sum0 = 0, sum1 = 0;
246 for (int s = 0; s < VSIZE; s++) sum0 += mat[0][s] * b.a(s);
247 for (int s = 0; s < VSIZE; s++) sum1 += mat[1][s] * b.a(s);
248 iy.set(sum0,sum1,0);
252 return iy;
253 }
254
255
263 public Vector transform(Vector b, Vector iy) { double sum0 = 0, sum1 = 0;
265 for (int s = 0; s < VSIZE; s++) sum0 += mat[0][s] * b.a(s);
266 for (int s = 0; s < VSIZE; s++) sum1 += mat[1][s] * b.a(s);
267 return iy.set(sum0, sum1);
271 }
272
273
280 public SPoint transform(double x, double y, double z) {
281 Vector vr = new Vector(x, y, z); SPoint sp = new SPoint(0,0);
283 return this.transform(vr,sp);
284 }
285
286
296 public SPoint transform(double x, double y, double z, Vector vr, SPoint sp) { return this.transform(vr.set(x,y,z),sp);
298 }
299
300
301
311 public Vector transform(double x, double y, double z, Vector vr, Vector sp) { return this.transform(vr.set(x,y,z),sp);
313 }
314
315
316
321 public SPoint transform(RPoint p) {
322 SPoint sp = new SPoint(0,0);
323 return this.transform(p,sp);
324 }
325
326
331 public RPoint transformR(RPoint p) {
332 RPoint rp = new RPoint(0,0);
333 return this.transform(p,rp);
334 }
335
336
342 public Matrix getInversion() {
343 if (this.inversion == null) {
344 Matrix temp = new Matrix(this);
345 Matrix tempInversion = new Matrix();
346 double multiplier = 0;
347
348 for (int i = 0; i < VSIZE; i++) {
350 for (int j = i + 1; j < VSIZE; j++) {
351 multiplier = -(temp.m(j, i) / temp.m(i, i));
352 temp.setRow(j, temp.row(j).sum(
353 temp.row(i).scalarProduct(multiplier)));
354 tempInversion.setRow(j, tempInversion.row(j).sum(
355 tempInversion.row(i).scalarProduct(multiplier)));
356 }
357 }
358
359 for (int i = VSIZE - 1; i >= 0; i--) {
361 for (int j = i - 1; j >= 0; j--) {
362 multiplier = -(temp.m(j, i) / temp.m(i, i));
363 temp.setRow(j, temp.row(j).sum(
364 temp.row(i).scalarProduct(multiplier)));
365 tempInversion.setRow(j, tempInversion.row(j).sum(
366 tempInversion.row(i).scalarProduct(multiplier)));
367 }
368 }
369
370 for (int i = 0; i < VSIZE; i++) {
372 multiplier = 1 / temp.m(i, i);
373 tempInversion.setRow(i, tempInversion.row(i).scalarProduct(
374 multiplier));
375 }
376 this.inversion = tempInversion;
377 }
378 return this.inversion;
379 }
380
381
385 @Override
386 public String toString() {
387 StringBuilder sb = new StringBuilder();
388 for (int r = 0; r < VSIZE; r++) {
389 sb.append("( ");
390 for (int s = 0; s < VSIZE; s++)
391 sb.append(" " + mat[r][s]);
392 sb.append(" )\n");
393 }
394 return sb.toString();
395 }
396
397 }
398
399