-
-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathAffineTransformation.java
More file actions
95 lines (77 loc) · 3.25 KB
/
AffineTransformation.java
File metadata and controls
95 lines (77 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package net.countercraft.movecraft.util;
import net.countercraft.movecraft.MovecraftLocation;
import net.countercraft.movecraft.MovecraftRotation;
import org.bukkit.block.structure.Mirror;
import org.ejml.simple.SimpleMatrix;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public final class AffineTransformation {
public static @NotNull AffineTransformation UNIT = new AffineTransformation(SimpleMatrix.identity(4), MovecraftRotation.NONE);
private final SimpleMatrix backingMatrix;
private final MovecraftRotation rotation;
private AffineTransformation(SimpleMatrix backingMatrix, MovecraftRotation rotation) {
this.backingMatrix = backingMatrix;
this.rotation = rotation;
}
public static @NotNull AffineTransformation of(MovecraftLocation translation) {
var ret = SimpleMatrix.identity(4);
ret.set(3, 0, translation.getX());
ret.set(3, 1, translation.getY());
ret.set(3, 2, translation.getZ());
return new AffineTransformation(ret, MovecraftRotation.NONE);
}
public static @NotNull AffineTransformation of(MovecraftRotation rotation) {
var ret = SimpleMatrix.identity(4);
switch (rotation) {
case NONE:
break;
case CLOCKWISE:
ret.set(0, 0, 0);
ret.set(1, 1, 0);
ret.set(0, 1, -1);
ret.set(1, 0, 1);
break;
case ANTICLOCKWISE:
ret.set(0, 0, 0);
ret.set(1, 1, 0);
ret.set(0, 1, 1);
ret.set(1, 0, -1);
break;
}
return new AffineTransformation(ret, rotation);
}
public @NotNull AffineTransformation mult(AffineTransformation other) {
// Currently, MovecraftRotation does not support 180 degree rotations
// To work around this, we simply prefer the other transformations rotation
// TODO: Implement 180 degree MovecraftRotation
return new AffineTransformation(backingMatrix.mult(other.backingMatrix), other.rotation == MovecraftRotation.NONE ? rotation : other.rotation);
}
public @NotNull MovecraftLocation apply(MovecraftLocation location) {
var transformed = backingMatrix.mult(new SimpleMatrix(new double[]{location.getX(), location.getY(), location.getZ(), 1}));
return new MovecraftLocation((int) transformed.get(0), (int) transformed.get(1), (int) transformed.get(2));
}
public @NotNull MovecraftRotation extractRotation() {
return rotation;
}
public @NotNull Mirror extractMirror() {
return Mirror.NONE;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (AffineTransformation) obj;
return Objects.equals(this.backingMatrix, that.backingMatrix) &&
Objects.equals(this.rotation, that.rotation);
}
@Override
public int hashCode() {
return Objects.hash(backingMatrix, rotation);
}
@Override
public String toString() {
return "AffineTransformation[" +
"backingMatrix=" + backingMatrix + ", " +
"rotation=" + rotation + ']';
}
}