From 5eddfe791b40850447a662783731ad1779b2ec87 Mon Sep 17 00:00:00 2001 From: Hailong <hailong.zhu@tu-dresden.de> Date: Fri, 10 Dec 2021 14:52:12 +0100 Subject: [PATCH] - added SRSConversion --- .../SRSConversion/Quaternion_math.java | 250 ++++++++++++++++++ .../SRSConversion/SRSConversion.java | 89 +++++++ .../SRSConversion/TestSRSConverter.java | 73 +++++ .../SRSConversion/Vector_math.java | 69 +++++ 4 files changed, 481 insertions(+) create mode 100644 src/main/java/ipos/project/Functionality/SRSConversion/Quaternion_math.java create mode 100644 src/main/java/ipos/project/Functionality/SRSConversion/SRSConversion.java create mode 100644 src/main/java/ipos/project/Functionality/SRSConversion/TestSRSConverter.java create mode 100644 src/main/java/ipos/project/Functionality/SRSConversion/Vector_math.java diff --git a/src/main/java/ipos/project/Functionality/SRSConversion/Quaternion_math.java b/src/main/java/ipos/project/Functionality/SRSConversion/Quaternion_math.java new file mode 100644 index 0000000..79b2ab5 --- /dev/null +++ b/src/main/java/ipos/project/Functionality/SRSConversion/Quaternion_math.java @@ -0,0 +1,250 @@ +package ipos.project.Functionality.SRSConversion; + +public class Quaternion_math { + private float x; + private float y; + private float z; + private float w; + //private float[] matrixs; + + public Quaternion_math(final Quaternion_math q) { + this(q.x, q.y, q.z, q.w); + } + + public Quaternion_math(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + public void set(final Quaternion_math q) { + //matrixs = null; + this.x = q.x; + this.y = q.y; + this.z = q.z; + this.w = q.w; + } + + public Quaternion_math(Vector_math axis, float angle) { + set(axis, angle); + } + + public float norm() { + return (float) Math.sqrt(dot(this)); + } + + public float getW() { + return w; + } + + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public float getZ() { + return z; + } + + /** + * @param axis + * rotation axis, unit vector + * @param angle + * the rotation angle + * @return this + */ + public Quaternion_math set(Vector_math axis, float angle) { + //matrixs = null; + angle = (float) Math.toRadians(angle); + float s = (float) Math.sin(angle); + w = (float) Math.cos(angle); + x = axis.getX() * s; + y = axis.getY() * s; + z = axis.getZ() * s; + //System.out.println("angle set: " + angle); + return this; + } + + public Quaternion_math mulThis(Quaternion_math q) { + //matrixs = null; + float nw = w * q.w - x * q.x - y * q.y - z * q.z; + float nx = w * q.x + x * q.w + y * q.z - z * q.y; + float ny = w * q.y + y * q.w + z * q.x - x * q.z; + z = w * q.z + z * q.w + x * q.y - y * q.x; + w = nw; + x = nx; + y = ny; + return this; + } + + public Quaternion_math scaleThis(float scale) { + if (scale != 1) { + //matrixs = null; + w *= scale; + x *= scale; + y *= scale; + z *= scale; + } + return this; + } + + public Quaternion_math divThis(float scale) { + if (scale != 1) { + //matrixs = null; + w /= scale; + x /= scale; + y /= scale; + z /= scale; + } + return this; + } + + public float dot(Quaternion_math q) { + return x * q.x + y * q.y + z * q.z + w * q.w; + } + + public boolean equals(Quaternion_math q) { + return x == q.x && y == q.y && z == q.z && w == q.w; + } + + public Quaternion_math interpolateThis(Quaternion_math q, float t) { + if (!equals(q)) { + float d = dot(q); + float qx, qy, qz, qw; + + if (d < 0f) { + qx = -q.x; + qy = -q.y; + qz = -q.z; + qw = -q.w; + d = -d; + } else { + qx = q.x; + qy = q.y; + qz = q.z; + qw = q.w; + } + + float f0, f1; + + if ((1 - d) > 0.1f) { + float angle = (float) Math.acos(d); + float s = (float) Math.sin(angle); + float tAngle = t * angle; + f0 = (float) Math.sin(angle - tAngle) / s; + f1 = (float) Math.sin(tAngle) / s; + } else { + f0 = 1 - t; + f1 = t; + } + + x = f0 * x + f1 * qx; + y = f0 * y + f1 * qy; + z = f0 * z + f1 * qz; + w = f0 * w + f1 * qw; + } + + return this; + } + + public Quaternion_math inverse() { + float norm = norm(); + if (norm > 0.0) { + float invNorm = 1.0f / norm; + return new Quaternion_math(-x * invNorm, -y * invNorm, -z * invNorm, w + * invNorm); + } + // return an invalid result to flag the error + return null; + } + public Quaternion_math normalizeThis() { + return divThis(norm()); + } + + public Quaternion_math interpolate(Quaternion_math q, float t) { + return new Quaternion_math(this).interpolateThis(q, t); + } + + + + + /** + * Converts this Quaternion_math into a matrix, returning it as a float array. + */ + public float[] toMatrix() { + float[] matrixs = new float[16]; + toMatrix(matrixs); + return matrixs; + } + /** Conjugate the Quaternion_math. + * + * @return This Quaternion_math for chaining */ + public Quaternion_math conjugate () { + x = -x; + y = -y; + z = -z; + return this; + } + + /** Multiplies this Quaternion_math with another one + * + * @param q Quaternion_math to multiply with + * @return This Quaternion_math for chaining */ + public Quaternion_math mul (Quaternion_math q) { + float newX = w * q.x + x * q.w + y * q.z - z * q.y; + float newY = w * q.y + y * q.w + z * q.x - x * q.z; + float newZ = w * q.z + z * q.w + x * q.y - y * q.x; + float newW = w * q.w - x * q.x - y * q.y - z * q.z; + x = newX; + y = newY; + z = newZ; + w = newW; + return this; + } + + /** Multiplies this Quaternion_math with another one in the form of q * this + * + * @param q Quaternion_math to multiply with + * @return This Quaternion_math for chaining */ + public Quaternion_math mulLeft (Quaternion_math q) { + float newX = q.w * x + q.x * w + q.y * z - q.z * y; + float newY = q.w * y + q.y * w + q.z * x - q.x * z; + float newZ = q.w * z + q.z * w + q.x * y - q.y * x; + float newW = q.w * w - q.x * x - q.y * y - q.z * z; + x = newX; + y = newY; + z = newZ; + w = newW; + return this; + } + + /** + * Converts this Quaternion_math into a matrix, placing the values into the given array. + * @param matrixs 16-length float array. + */ + public final void toMatrix(float[] matrixs) { + matrixs[3] = 0.0f; + matrixs[7] = 0.0f; + matrixs[11] = 0.0f; + matrixs[12] = 0.0f; + matrixs[13] = 0.0f; + matrixs[14] = 0.0f; + matrixs[15] = 1.0f; + + matrixs[0] = (float) (1.0f - (2.0f * ((y * y) + (z * z)))); + matrixs[1] = (float) (2.0f * ((x * y) - (z * w))); + matrixs[2] = (float) (2.0f * ((x * z) + (y * w))); + + matrixs[4] = (float) (2.0f * ((x * y) + (z * w))); + matrixs[5] = (float) (1.0f - (2.0f * ((x * x) + (z * z)))); + matrixs[6] = (float) (2.0f * ((y * z) - (x * w))); + + matrixs[8] = (float) (2.0f * ((x * z) - (y * w))); + matrixs[9] = (float) (2.0f * ((y * z) + (x * w))); + matrixs[10] = (float) (1.0f - (2.0f * ((x * x) + (y * y)))); + } +} diff --git a/src/main/java/ipos/project/Functionality/SRSConversion/SRSConversion.java b/src/main/java/ipos/project/Functionality/SRSConversion/SRSConversion.java new file mode 100644 index 0000000..7962b92 --- /dev/null +++ b/src/main/java/ipos/project/Functionality/SRSConversion/SRSConversion.java @@ -0,0 +1,89 @@ +package ipos.project.Functionality.SRSConversion; +import org.eclipse.emf.common.util.EList; + +import ipos.project.DataModellntegration.iPos_Datamodel.*; + +/* +This class contains methods to convert the coordinate system of positions. +All reference Systems should be defined in the ROOT system. +*/ +public class SRSConversion { + /* + This function converts the coordinate system of a position to a desired coordinate system. + p1 is the coordinate of the position in the original coordinate system + ref_1 is the origin point of the original coordinate system (A Point3D in ROOT) + ref_2 is the origin point of the desired coordinate system (A Point3D in ROOT) + quat_1 is the rotation of the original coordinate system (against ROOT) + quat_2 is the rotation of the desired coordinate system (against ROOT) + */ + public static void positionInOtherSystem(Position pos, ReferenceSystem ref){ + IPos_DatamodelFactory datamodelFactory = IPos_DatamodelFactory.eINSTANCE; + + Point3D P = (Point3D) pos.getPoint(); + Point3D R1 = (Point3D) pos.getReferenceSystem().getOrigin().getPosition().getPoint(); + Point3D R2 = (Point3D) ref.getOrigin().getPosition().getPoint(); + Quaternion Q1 = (Quaternion) pos.getReferenceSystem().getOrigin().getOrientation(); + Quaternion Q2 = (Quaternion) ref.getOrigin().getOrientation(); + + Vector_math p1 = new Vector_math(P.getX(), P.getY(), P.getZ()); + Vector_math ref_1 = new Vector_math(R1.getX(), R1.getY(), R1.getZ()); + Vector_math ref_2 = new Vector_math(R2.getX(), R2.getY(), R2.getZ()); + Quaternion_math quat_1 = new Quaternion_math(Q1.getX(), Q1.getY(), Q1.getZ(), Q1.getW()); + Quaternion_math quat_2 = new Quaternion_math(Q2.getX(), Q2.getY(), Q2.getZ(), Q2.getW()); + //System.out.println("Quaterion_1: " + quat_1.getX() + ", "+ quat_1.getY() + ", "+ quat_1.getZ() + ", " + quat_1.getW()); + //System.out.println("Quaterion_2: " + quat_2.getX() + ", "+ quat_2.getY() + ", "+ quat_2.getZ() + ", " + quat_2.getW()); + + //System.out.println("inversed Quaterion_1: " + quat_1.inverse().getX() + ", "+ quat_1.inverse().getY() + ", "+ quat_1.inverse().getZ() + ", " + quat_1.inverse().getW()); + p1.transform(quat_1.inverse()); + + //System.out.println("phase 1 transfrom: " + p1.getX() + ", "+ p1.getY() + ", "+ p1.getZ()); + p1.transform(quat_2); + p1.add(ref_1); + p1.substract(ref_2); + + P.setX(p1.getX()); + P.setY(p1.getY()); + P.setZ(p1.getZ()); + pos.setPoint(P); + pos.setReferenceSystem(ref); + } + public static void zoneInOtherSystem(Zone zone, ReferenceSystem ref){ + IPos_DatamodelFactory datamodelFactory = IPos_DatamodelFactory.eINSTANCE; + EList spaceList = zone.getSpace(); + for (int i = 0; i < spaceList.size(); i++) { + Space S = (Space)spaceList.get(i); + Placing P = S.getCentrePoint(); + Position Pos = P.getPosition(); + positionInOtherSystem(Pos, ref); + Quaternion Q1 = (Quaternion) P.getOrientation(); + Quaternion Q2 = (Quaternion) ref.getOrigin().getOrientation(); + + Quaternion_math quat_1 = new Quaternion_math(Q1.getX(), Q1.getY(), Q1.getZ(), Q1.getW()); + Quaternion_math quat_2 = new Quaternion_math(Q2.getX(), Q2.getY(), Q2.getZ(), Q2.getW()); + quat_1.mulLeft(quat_2); + Q1.setX(quat_1.getX()); + Q1.setY(quat_1.getY()); + Q1.setZ(quat_1.getZ()); + Q1.setW(quat_1.getW()); + P.setOrientation(Q1); + P.setPosition(Pos); + S.setCentrePoint(P); + spaceList.set(i, S); + } + } + public float[] getCordInOtherSystem (float[] cod, float[] ref, float[] quaternion){ + float[] new_cod = new float[3]; + //float[] conv_vec = new float[16]; + Vector_math cod_vec = new Vector_math(cod[0], cod[1], cod[2]); + Vector_math ref_new = new Vector_math(ref[0], ref[1], ref[2]); + Quaternion_math quaternion_new = new Quaternion_math(quaternion[0], quaternion[1], quaternion[2], quaternion[3]); + //conv_vec = quaternion_new.toMatrix(); + //float[][] conv_matrix = new float[][]{{conv_vec[0], conv_vec[1], conv_vec[2]}, {conv_vec[3], conv_vec[4], conv_vec[5]}, {conv_vec[6], conv_vec[7], conv_vec[8]}}; + cod_vec.transform(quaternion_new); + cod_vec.add(ref_new); + new_cod[0] = cod_vec.getX(); + new_cod[1] = cod_vec.getY(); + new_cod[2] = cod_vec.getZ(); + return new_cod; + } +} diff --git a/src/main/java/ipos/project/Functionality/SRSConversion/TestSRSConverter.java b/src/main/java/ipos/project/Functionality/SRSConversion/TestSRSConverter.java new file mode 100644 index 0000000..0407054 --- /dev/null +++ b/src/main/java/ipos/project/Functionality/SRSConversion/TestSRSConverter.java @@ -0,0 +1,73 @@ +package ipos.project.Functionality.SRSConversion; + +import ipos.project.DataModellntegration.iPos_Datamodel.*; +import ipos.project.Functionality.SRSConversion.SRSConversion; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class TestSRSConverter { + public static void test() throws ParseException { + IPos_DatamodelFactory datamodelFactory = IPos_DatamodelFactory.eINSTANCE; + Vector_math axis = new Vector_math(1, 0,0); + Point3D testPoint3D = datamodelFactory.createPoint3D(); + Position testPosition = datamodelFactory.createPosition(); + + testPoint3D.setX((float) 0); + testPoint3D.setY((float) 1); + testPoint3D.setZ((float) 0); + + ReferenceSystem testRef_1 = datamodelFactory.createReferenceSystem(); + Placing refPlacing_1 = datamodelFactory.createPlacing(); + Position refPosition_1 = datamodelFactory.createPosition(); + Point3D ref_1 = datamodelFactory.createPoint3D(); + Quaternion rot_1 = datamodelFactory.createQuaternion(); + Quaternion_math rot_1_math = new Quaternion_math(axis, 90); + rot_1.setX(rot_1_math.getX()); + rot_1.setY(rot_1_math.getY()); + rot_1.setZ(rot_1_math.getZ()); + rot_1.setW(rot_1_math.getW()); + ref_1.setX(1); + ref_1.setY(1); + ref_1.setZ(1); + refPosition_1.setPoint(ref_1); + refPlacing_1.setPosition(refPosition_1); + refPlacing_1.setOrientation(rot_1); + testRef_1.setId("CITI"); + testRef_1.setOrigin(refPlacing_1); + testPosition.setPoint(testPoint3D); + testPosition.setReferenceSystem(testRef_1); + + + ReferenceSystem testRef_2 = datamodelFactory.createReferenceSystem(); + Placing refPlacing_2 = datamodelFactory.createPlacing(); + Position refPosition_2 = datamodelFactory.createPosition(); + Point3D ref_2 = datamodelFactory.createPoint3D(); + Quaternion rot_2 = datamodelFactory.createQuaternion(); + Quaternion_math rot_2_math = new Quaternion_math(axis, 0); + rot_2.setX(rot_2_math.getX()); + rot_2.setY(rot_2_math.getY()); + rot_2.setZ(rot_2_math.getZ()); + rot_2.setW(rot_2_math.getW()); + ref_2.setX(0); + ref_2.setY(0); + ref_2.setZ(0); + refPosition_2.setPoint(ref_2); + refPlacing_2.setPosition(refPosition_2); + refPlacing_2.setOrientation(rot_2); + testRef_2.setId("ROOT"); + testRef_2.setOrigin(refPlacing_2); + + + System.out.println("Position: refID " + ": " + testPosition.getReferenceSystem().getId()); + System.out.println("Position: coord " + ": " + testPosition.getPoint()); + + SRSConversion.positionInOtherSystem(testPosition, testRef_2); + System.out.println("Position: refID " + ": " + testPosition.getReferenceSystem().getId()); + System.out.println("Position: coord " + ": " + testPosition.getPoint()); + + + + } +} diff --git a/src/main/java/ipos/project/Functionality/SRSConversion/Vector_math.java b/src/main/java/ipos/project/Functionality/SRSConversion/Vector_math.java new file mode 100644 index 0000000..d43b7d7 --- /dev/null +++ b/src/main/java/ipos/project/Functionality/SRSConversion/Vector_math.java @@ -0,0 +1,69 @@ +package ipos.project.Functionality.SRSConversion; + +public final class Vector_math { + private static Quaternion_math tmp1 = new Quaternion_math(0, 0, 0, 0); + private static Quaternion_math tmp2 = new Quaternion_math(0, 0, 0, 0); + private float x,y,z; + + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public float getZ() { + return z; + } + + public Vector_math(float ix, float iy, float iz) { + x = ix; + y = iy; + z = iz; + } + + public void set(float ix, float iy, float iz) { + x = ix; + y = iy; + z = iz; + } + + public double magnitude() { + return Math.sqrt(x*x+y*y+z*z); + } + + public void multiply(float f) { + x *= f; + y *= f; + z *= f; + } + + public void normalise() { + double mag = magnitude(); + x /= mag; + y /= mag; + z /= mag; + } + public void add(Vector_math v) { + x += v.x; + y += v.y; + z += v.z; + } + public void substract(Vector_math v) { + x -= v.x; + y -= v.y; + z -= v.z; + } + public void transform (Quaternion_math q) { + tmp2.set(q); + tmp2.conjugate(); + tmp1 = new Quaternion_math(x, y, z, 0); + tmp2.mulLeft(tmp1); + //tmp2.mulLeft(tmp2); + + x = tmp2.getX(); + y = tmp2.getY(); + z = tmp2.getZ(); + } +} -- GitLab