Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualJM33

Posted 18 November 2012 - 09:34 PM

OK, yes I was very confused, and I never needed to solve for i,j,k in the first place.

The code you gave me works as often as the original code I had with angle/axis, however with the opposite effect. Basically if my plane is upside down I hit the target, otherwise not. If I remove the lines to negate the quaternion when q.real() is less than 0, I get the original results (plane upside down = miss & plane right side up = hit).

If you have any suggestion or insight please let me know. I feel like this is really close to the right solution as the rotation is being correctly limited to the maximum rotation, but still needs to be inverted properly. I am wondering if there is anything that can be referenced to determine when to negate the quaternion, such as the up vectors of the rocket and target?

Here is my code as-is:
[source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]);Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]);Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]);Vector3D newtargvec = targvec.subtract(R1pos);newtargvec = newtargvec.normalize();R1head = R1head.normalize();Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize();Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize();Quaternion rot = head.rotBetween(newvec).normalize();float turn_threshold = 0.9998477f; // cos(maxrot/2) = cos(1)Quaternion newq = rot.limit_rotation(rot, turn_threshold); // see Quaternion code belowfloat[] qmat = newq.toMatrix(); Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0);[/source]

And my relative Quaternion functions:
[source lang="java"]public Quaternion limit_rotation(Quaternion q, float min_real_part) {if (q.real() <= -min_real_part || q.real() >= min_real_part) return q;if(q.real() < 0){ q = q.multF(-1); // negate quaternion}float desired_unreal_length = FloatMath.sqrt(1 - min_real_part * min_real_part);float old_unreal_length = q.unreal().abs(); Quaternion limit = new Quaternion(min_real_part, q.x * (desired_unreal_length / old_unreal_length), q.y * (desired_unreal_length / old_unreal_length), q.z * (desired_unreal_length / old_unreal_length));Log.i("QuatLimit", "Result = w: " + Float.toString(min_real_part) + ", x:" + Float.toString(limit.x) + ", y:" + Float.toString(limit.y) + ", z:"+ Float.toString(limit.z)); return limit;}public Quaternion(float real) { this.w = real; this.x = 0; this.y = 0; this.z = 0;}public float real() { return this.w;}public Quaternion unreal() { return new Quaternion(0, this.x, this.y, this.z);}public float abs() { return FloatMath.sqrt(x * x + y * y + z * z + w * w);}public Quaternion (float w, float x, float y, float z) { this.set(w, x, y, z);}public Quaternion multF(float scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this;}[/source]

#3JM33

Posted 18 November 2012 - 09:34 PM

OK, yes I was very confused, and I never needed to solve for i,j,k in the first place.

The code you gave me works as often as the original code I had with angle/axis, however with the opposite effect. Basically if my plane is upside down I hit the target, otherwise not. If I remove the lines to negate the quaternion when q.real() is less than 0, I get the original results (plane upside down = miss &amp; plane right side up = hit).

If you have any suggestion or insight please let me know. I feel like this is really close to the right solution as the rotation is being correctly limited to the maximum rotation, but still needs to be inverted properly. I am wondering if there is anything that can be referenced to determine when to negate the quaternion, such as the up vectors of the rocket and target?

Here is my code as-is:
[source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]);Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]);Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]);Vector3D newtargvec = targvec.subtract(R1pos);newtargvec = newtargvec.normalize();R1head = R1head.normalize();Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize();Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize();Quaternion rot = head.rotBetween(newvec).normalize();float turn_threshold = 0.9998477f; // cos(maxrot/2) = cos(1)Quaternion newq = rot.limit_rotation(rot, turn_threshold); // see Quaternion code belowfloat[] qmat = newq.toMatrix(); Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0);[/source]

And my relative Quaternion functions:
[source lang="java"]public Quaternion limit_rotation(Quaternion q, float min_real_part) {if (q.real() <= -min_real_part || q.real() >= min_real_part) return q;if(q.real() < 0){ q = q.multF(-1); // negate quaternion}float desired_unreal_length = FloatMath.sqrt(1 - min_real_part * min_real_part);float old_unreal_length = q.unreal().abs(); Quaternion limit = new Quaternion(min_real_part, q.x * (desired_unreal_length / old_unreal_length), q.y * (desired_unreal_length / old_unreal_length), q.z * (desired_unreal_length / old_unreal_length));Log.i("QuatLimit", "Result = w: " + Float.toString(min_real_part) + ", x:" + Float.toString(limit.x) + ", y:" + Float.toString(limit.y) + ", z:"+ Float.toString(limit.z)); return limit;}public Quaternion(float real) { this.w = real; this.x = 0; this.y = 0; this.z = 0;}public float real() { return this.w;}public Quaternion unreal() { return new Quaternion(0, this.x, this.y, this.z);}public float abs() { return FloatMath.sqrt(x * x + y * y + z * z + w * w);}public Quaternion (float w, float x, float y, float z) { this.set(w, x, y, z);}public Quaternion multF(float scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this;}[/source]

#2JM33

Posted 18 November 2012 - 09:34 PM

OK, yes I was very confused, and I never needed to solve for i,j,k in the first place.

The code you gave me works as often as the original code I had with angle/axis, however with the opposite effect. Basically if my plane is upside down I hit the target, otherwise not. If I remove the lines to negate the quaternion when q.real() is less than 0, I get the original results (plane upside down = miss &amp; plane right side up = hit).

If you have any suggestion or insight please let me know. I feel like this is really close to the right solution as the rotation is being correctly limited to the maximum rotation, but still needs to be inverted properly. I am wondering if there is anything that can be referenced to determine when to negate the quaternion, such as the up vectors of the rocket and target?

Here is my code as-is:
[source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]);Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]);Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]);Vector3D newtargvec = targvec.subtract(R1pos);newtargvec = newtargvec.normalize();R1head = R1head.normalize();Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize();Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize();Quaternion rot = head.rotBetween(newvec).normalize();float turn_threshold = 0.9998477f; // cos(maxrot/2) = cos(1)Quaternion newq = rot.limit_rotation(rot, turn_threshold); // see Quaternion code belowfloat[] qmat = newq.toMatrix(); Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0);[/source]

And my relative Quaternion functions:
[source lang="java"]public Quaternion limit_rotation(Quaternion q, float min_real_part) {if (q.real() <= -min_real_part || q.real() >= min_real_part) return q;if(q.real() < 0){ q = q.multF(-1); // negate quaternion}float desired_unreal_length = FloatMath.sqrt(1 - min_real_part * min_real_part);float old_unreal_length = q.unreal().abs(); Quaternion limit = new Quaternion(min_real_part, q.x * (desired_unreal_length / old_unreal_length), q.y * (desired_unreal_length / old_unreal_length), q.z * (desired_unreal_length / old_unreal_length));Log.i("QuatLimit", "Result = w: " + Float.toString(min_real_part) + ", x:" + Float.toString(limit.x) + ", y:" + Float.toString(limit.y) + ", z:"+ Float.toString(limit.z)); return limit;}public Quaternion(float real) { this.w = real; this.x = 0; this.y = 0; this.z = 0;}public float real() { return this.w;}public Quaternion unreal() { return new Quaternion(0, this.x, this.y, this.z);}public float abs() { return FloatMath.sqrt(x * x + y * y + z * z + w * w);}public Quaternion (float w, float x, float y, float z) { this.set(w, x, y, z);}public Quaternion multF(float scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this;}[/source]

#1JM33

Posted 18 November 2012 - 09:30 PM

OK, yes I was very confused, and I never needed to solve for i,j,k in the first place.

The code you gave me works as often as the original code I had with angle/axis, however with the opposite effect. Basically if my plane is upside down I hit the target, otherwise not. If I remove the lines to negate the quaternion when q.real() is less than 0, I get the original results (plane upside down = miss & plane right side up = hit).

If you have any suggestion or insight please let me know. I feel like this is really close to the right solution as the rotation is being correctly limited to the maximum rotation, but still needs to be inverted properly. I am wondering if there is anything that can be referenced to determine when to negate the quaternion, such as the up vectors of the rocket and target?

Here is my code as-is:
[source lang="java"]Vector3D targvec = new Vector3D(targetmatrix[12], targetmatrix[13], targetmatrix[14]);Vector3D R1pos = new Vector3D(R1Matrix[12], R1Matrix[13], R1Matrix[14]);Vector3D R1head = new Vector3D(R1Matrix[8], R1Matrix[9], R1Matrix[10]); Vector3D newtargvec = targvec.subtract(R1pos);newtargvec = newtargvec.normalize();R1head = R1head.normalize(); Quaternion head = new Quaternion(0, R1head.getX(), R1head.getY(), R1head.getZ()).normalize(); Quaternion newvec = new Quaternion(0, newtargvec.getX(), newtargvec.getY(), newtargvec.getZ()).normalize(); Quaternion rot = head.rotBetween(newvec).normalize(); float turn_threshold = 0.9998477f; // cos(maxrot/2) = cos(1) Quaternion newq = rot.limit_rotation(rot, turn_threshold); // see Quaternion code below float[] qmat = newq.toMatrix(); Matrix.multiplyMM(R1Matrix, 0, R1Matrix, 0, qmat, 0);[/source]
And my Quaternion functions:
[source lang="java"]public Quaternion limit_rotation(Quaternion q, float min_real_part) { if (q.real() <= -min_real_part || q.real() >= min_real_part) return q; if(q.real() < 0){ q = q.multF(-1); // negate quaternion } float desired_unreal_length = FloatMath.sqrt(1 - min_real_part * min_real_part); float old_unreal_length = q.unreal().abs(); Quaternion limit = new Quaternion(min_real_part, q.x * (desired_unreal_length / old_unreal_length), q.y * (desired_unreal_length / old_unreal_length), q.z * (desired_unreal_length / old_unreal_length)); Log.i("QuatLimit", "Result = w: " + Float.toString(min_real_part) + ", x:" + Float.toString(limit.x) + ", y:" + Float.toString(limit.y) + ", z:"+ Float.toString(limit.z)); return limit; } public Quaternion(float real) { this.w = real; this.x = 0; this.y = 0; this.z = 0; } public float real() { return this.w; } public Quaternion unreal() { return new Quaternion(0, this.x, this.y, this.z); }public float abs() { return FloatMath.sqrt(x * x + y * y + z * z + w * w); }public Quaternion (float w, float x, float y, float z) { this.set(w, x, y, z); }public Quaternion multF(float scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this; }[/source]

PARTNERS