Refactor CoordTransform
This commit is contained in:
parent
ea59b9d012
commit
c38d5f59a6
@ -4,10 +4,46 @@ package net.sf.openrocket.file.wavefrontobj;
|
||||
* Representation of an axis in 3D space.
|
||||
*/
|
||||
public enum Axis {
|
||||
X,
|
||||
X_MIN, // Negative x
|
||||
Y,
|
||||
Y_MIN, // Negative y
|
||||
Z,
|
||||
Z_MIN // Negative z
|
||||
X ("X"),
|
||||
X_MIN ("-X"),
|
||||
Y ("Y"),
|
||||
Y_MIN ("-Y"),
|
||||
Z ("Z"),
|
||||
Z_MIN ("-Z");
|
||||
|
||||
private final String label;
|
||||
|
||||
Axis(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public static Axis fromString(String label) {
|
||||
for (Axis axis : values()) {
|
||||
if (axis.label.equals(label)) {
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown axis: " + label);
|
||||
}
|
||||
|
||||
public boolean isSameAxis(Axis other) {
|
||||
return this == other || this == getOppositeAxis(other);
|
||||
}
|
||||
|
||||
public static Axis getOppositeAxis(Axis axis) {
|
||||
return switch (axis) {
|
||||
case X -> X_MIN;
|
||||
case X_MIN -> X;
|
||||
case Y -> Y_MIN;
|
||||
case Y_MIN -> Y;
|
||||
case Z -> Z_MIN;
|
||||
case Z_MIN -> Z;
|
||||
default -> throw new IllegalArgumentException("Unknown axis: " + axis);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.file.wavefrontobj;
|
||||
|
||||
import com.sun.istack.NotNull;
|
||||
import de.javagl.obj.FloatTuple;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
@ -11,7 +12,73 @@ import net.sf.openrocket.util.Coordinate;
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public interface CoordTransform {
|
||||
public class CoordTransform {
|
||||
// OpenRocket coordinate system axes mapping
|
||||
protected final Axis xAxis;
|
||||
protected final Axis yAxis;
|
||||
protected final Axis zAxis;
|
||||
protected final Axis axialAxis;
|
||||
|
||||
// Origin offsets
|
||||
protected final double origXOffs;
|
||||
protected final double origYOffs;
|
||||
protected final double origZOffs;
|
||||
|
||||
/**
|
||||
* Create a new coordinate system converter.
|
||||
* @param xAxis the OpenRocket axis that corresponds to the transformed x-axis
|
||||
* @param yAxis the OpenRocket axis that corresponds to the transformed y-axis
|
||||
* @param zAxis the OpenRocket axis that corresponds to the transformed z-axis
|
||||
* Example: you want the transformed coordinate system to have the z-axis as the longitudinal axis (= OpenRocket x-axis)
|
||||
* and want its direction to be from the bottom of the rocket to the tip of the rocket (opposite direction
|
||||
* of the OpenRocket x-axis), then you must pass Axis.X_MIN as the xAxis parameter.
|
||||
* You must also add an offset to the origin of the transformed coordinate system, so that it starts
|
||||
* at the bottom of the rocket => set origZOffs to the length of the rocket.
|
||||
* @param axialAxis the axial/longitudinal axis <b>in the transformed coordinate system, with the direction
|
||||
* relative to the OpenRocket x-axis !!</b>
|
||||
* From the previous example, the longitudinal axis would be Axis.Z_MIN.
|
||||
* @param origXOffs the x-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
* @param origYOffs the y-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
* @param origZOffs the z-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
*/
|
||||
public CoordTransform(@NotNull Axis xAxis, @NotNull Axis yAxis, @NotNull Axis zAxis, @NotNull Axis axialAxis,
|
||||
double origXOffs, double origYOffs, double origZOffs) {
|
||||
if (xAxis == null || yAxis == null || zAxis == null || axialAxis == null) {
|
||||
throw new IllegalArgumentException("Axes cannot be null");
|
||||
}
|
||||
|
||||
if (xAxis.isSameAxis(yAxis) || xAxis.isSameAxis(zAxis) || yAxis.isSameAxis(zAxis)) {
|
||||
throw new IllegalArgumentException("Axes must be different");
|
||||
}
|
||||
|
||||
this.xAxis = xAxis;
|
||||
this.yAxis = yAxis;
|
||||
this.zAxis = zAxis;
|
||||
this.axialAxis = axialAxis;
|
||||
|
||||
this.origXOffs = origXOffs;
|
||||
this.origYOffs = origYOffs;
|
||||
this.origZOffs = origZOffs;
|
||||
}
|
||||
|
||||
|
||||
private FloatTuple convertLoc(double x, double y, double z,
|
||||
double origXOffs, double origYOffs, double origZOffs) {
|
||||
final double xTrans = getTransformedCoordinate(xAxis, x, y, z);
|
||||
final double yTrans = getTransformedCoordinate(yAxis, x, y, z);
|
||||
final double zTrans = getTransformedCoordinate(zAxis, x, y, z);
|
||||
|
||||
final double origXTrans = getTransformedOriginOffset(xAxis, origXOffs, origYOffs, origZOffs);
|
||||
final double origYTrans = getTransformedOriginOffset(yAxis, origXOffs, origYOffs, origZOffs);
|
||||
final double origZTrans = getTransformedOriginOffset(zAxis, origXOffs, origYOffs, origZOffs);
|
||||
|
||||
return new DefaultFloatTuple(
|
||||
(float) (xTrans + origXTrans),
|
||||
(float) (yTrans + origYTrans),
|
||||
(float) (zTrans + origZTrans)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location coordinates from OpenRocket to OBJ coordinates.
|
||||
* The returned coordinates will also be shifted towards the origin of the OBJ coordinate system.
|
||||
@ -22,7 +89,9 @@ public interface CoordTransform {
|
||||
* @param z OpenRocket z-coordinate
|
||||
* @return the location coordinates in OBJ coordinates
|
||||
*/
|
||||
FloatTuple convertLoc(double x, double y, double z);
|
||||
public FloatTuple convertLoc(double x, double y, double z) {
|
||||
return convertLoc(x, y, z, origXOffs, origYOffs, origZOffs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location coordinates from OpenRocket to OBJ coordinates.
|
||||
@ -32,7 +101,9 @@ public interface CoordTransform {
|
||||
* @param coordinate OpenRocket coordinate
|
||||
* @return the location coordinates in OBJ coordinates
|
||||
*/
|
||||
FloatTuple convertLoc(Coordinate coordinate);
|
||||
public FloatTuple convertLoc(Coordinate coordinate) {
|
||||
return convertLoc(coordinate.x, coordinate.y, coordinate.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location coordinates from OpenRocket to OBJ coordinates, without the offset of the origin.
|
||||
@ -49,16 +120,24 @@ public interface CoordTransform {
|
||||
* @param z OpenRocket z-coordinate
|
||||
* @return the location coordinates in OBJ coordinates, with the origin set to the OpenRocket origin (the tip of the rocket)
|
||||
*/
|
||||
FloatTuple convertLocWithoutOriginOffs(double x, double y, double z);
|
||||
public FloatTuple convertLocWithoutOriginOffs(double x, double y, double z) {
|
||||
return convertLoc(x, y, z, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the rotation coordinates from OpenRocket to OBJ coordinates.
|
||||
* @param x OpenRocket rotation in radians around the x-axis
|
||||
* @param y OpenRocket rotation in radians around the y-axis
|
||||
* @param z OpenRocket rotation in radians around the z-axis
|
||||
* @param xRot OpenRocket rotation in radians around the x-axis
|
||||
* @param yRot OpenRocket rotation in radians around the y-axis
|
||||
* @param zRot OpenRocket rotation in radians around the z-axis
|
||||
* @return the rotation coordinates in OBJ coordinates
|
||||
*/
|
||||
FloatTuple convertRot(double x, double y, double z);
|
||||
public FloatTuple convertRot(double xRot, double yRot, double zRot) {
|
||||
final double xRotTrans = getTransformedRotation(xAxis, xRot, yRot, zRot);
|
||||
final double yRotTrans = getTransformedRotation(yAxis, xRot, yRot, zRot);
|
||||
final double zRotTrans = getTransformedRotation(zAxis, xRot, yRot, zRot);
|
||||
|
||||
return new DefaultFloatTuple((float) xRotTrans, (float) yRotTrans, (float) zRotTrans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the equivalent axis for the x-axis in the OpenRocket coordinate system (axial axis).
|
||||
@ -67,5 +146,62 @@ public interface CoordTransform {
|
||||
* must return Axis.Z_MIN.
|
||||
* @return the equivalent axis for the x-axis in the OpenRocket coordinate system (axial axis)
|
||||
*/
|
||||
Axis getAxialAxis();
|
||||
public Axis getAxialAxis() {
|
||||
return axialAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transformed coordinate for the given axis.
|
||||
* @param axis the OpenRocket axis to transform
|
||||
* @param x the x-coordinate in the OpenRocket coordinate system
|
||||
* @param y the y-coordinate in the OpenRocket coordinate system
|
||||
* @param z the z-coordinate in the OpenRocket coordinate system
|
||||
* @return the coordinate in the transformed OBJ coordinate system
|
||||
*/
|
||||
private double getTransformedCoordinate(Axis axis, double x, double y, double z) {
|
||||
return switch (axis) {
|
||||
case X -> x;
|
||||
case X_MIN -> -x;
|
||||
case Y -> y;
|
||||
case Y_MIN -> -y;
|
||||
case Z -> z;
|
||||
case Z_MIN -> -z;
|
||||
default -> throw new IllegalStateException("Unknown axis");
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the origin of the OBJ coordinate system for the given axis.
|
||||
* @param axis the axis to get the offset for
|
||||
* @return the offset of the origin of the OBJ coordinate system for the given axis
|
||||
*/
|
||||
private double getTransformedOriginOffset(Axis axis, double origXOffs, double origYOffs, double origZOffs) {
|
||||
return switch (axis) {
|
||||
case X, X_MIN -> origXOffs;
|
||||
case Y, Y_MIN -> origYOffs;
|
||||
case Z, Z_MIN -> origZOffs;
|
||||
default -> throw new IllegalStateException("Unknown axis");
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transformed rotation for the given axis.
|
||||
* @param axis the OpenRocket axis to transform
|
||||
* @param rotX the rotation in radians around the OpenRocket x-axis
|
||||
* @param rotY the rotation in radians around the OpenRocket y-axis
|
||||
* @param rotZ the rotation in radians around the OpenRocket z-axis
|
||||
* @return the rotation in radians around the transformed OBJ axis
|
||||
*/
|
||||
private double getTransformedRotation(Axis axis, double rotX, double rotY, double rotZ) {
|
||||
// OpenRocket uses left-handed coordinate system, we'll use right-handed
|
||||
return switch (axis) {
|
||||
case X -> -rotX;
|
||||
case X_MIN -> rotX;
|
||||
case Y -> -rotY;
|
||||
case Y_MIN -> rotY;
|
||||
case Z -> -rotZ;
|
||||
case Z_MIN -> rotZ;
|
||||
default -> throw new IllegalStateException("Unknown axis");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
package net.sf.openrocket.file.wavefrontobj;
|
||||
|
||||
import de.javagl.obj.FloatTuple;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
/**
|
||||
* Default OpenRocket coordinate system to OBJ coordinate system converter.
|
||||
* OpenRocket uses a left-handed coordinate system with the y-axis pointing up, the z-axis pointing away from the viewer,
|
||||
@ -12,59 +9,8 @@ import net.sf.openrocket.util.Coordinate;
|
||||
* - side view is in the z-x plane, with the x-axis pointing up
|
||||
* - y-axis is pointing away from the viewer
|
||||
*/
|
||||
public class DefaultCoordTransform implements CoordTransform {
|
||||
private final double rocketLength;
|
||||
|
||||
public class DefaultCoordTransform extends CoordTransform {
|
||||
public DefaultCoordTransform(double rocketLength) {
|
||||
this.rocketLength = rocketLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location coordinates from OpenRocket to OBJ coordinates.
|
||||
* @param x OpenRocket x-coordinate (! careful, when translating the component location, some components need an extra
|
||||
* offset here, such as the component length !)
|
||||
* @param y OpenRocket y-coordinate
|
||||
* @param z OpenRocket z-coordinate
|
||||
* @return the location coordinates in OBJ coordinates
|
||||
*/
|
||||
@Override
|
||||
public FloatTuple convertLoc(double x, double y, double z) {
|
||||
return convertLocToOBJCoord(x, y, z, this.rocketLength, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatTuple convertLoc(Coordinate coordinate) {
|
||||
return convertLocToOBJCoord(coordinate.x, coordinate.y, coordinate.z, this.rocketLength, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location coordinates from OpenRocket to OBJ coordinates, with the offset of the origin.
|
||||
* @param x OpenRocket x-coordinate
|
||||
* @param y OpenRocket y-coordinate
|
||||
* @param z OpenRocket z-coordinate
|
||||
* @param origXOffs the x-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
* @param origYOffs the y-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
* @param origZOffs the z-offset of the origin of the OBJ coordinate system, <b>in the OpenRocket coordinate system</b>
|
||||
* @return the location coordinates in OBJ coordinates
|
||||
*/
|
||||
private FloatTuple convertLocToOBJCoord(double x, double y, double z,
|
||||
double origXOffs, double origYOffs, double origZOffs) {
|
||||
return new DefaultFloatTuple((float) (y + origYOffs), (float) (z + origZOffs), (float) (origXOffs - x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatTuple convertLocWithoutOriginOffs(double x, double y, double z) {
|
||||
return convertLocToOBJCoord(x, y, z, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatTuple convertRot(double x, double y, double z) {
|
||||
// OpenRocket uses left-handed rotations, we need right-handed
|
||||
return new DefaultFloatTuple((float) -y, (float) -z, (float) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getAxialAxis() {
|
||||
return Axis.Z_MIN;
|
||||
super(Axis.Y, Axis.Z, Axis.X_MIN, Axis.Z_MIN, 0, 0, rocketLength);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user