Skip to content

Dual quaternions#64

Open
nanjizal wants to merge 15 commits intotbrosman:masterfrom
nanjizal:dualQuaternions
Open

Dual quaternions#64
nanjizal wants to merge 15 commits intotbrosman:masterfrom
nanjizal:dualQuaternions

Conversation

@nanjizal
Copy link

Just current Dual Quaternion changes

nanjizal and others added 12 commits May 7, 2020 04:04
@nanjizal
Copy link
Author

Still WIP no additional testing yet added.

@nanjizal
Copy link
Author

Stuff requested I action:

Cool, I'll try to add more documentation/references when I get time to work on this again. This is one of the more useful papers I found while refreshing my brain: https://www.cs.utah.edu/~ladislav/kavan06dual/kavan06dual.pdf It goes over how to set up the product for transforming points.

In the meantime there are a few things this PR needs:

Code style should match the rest of the library
Test for Quaternion.fromYawPitchRoll
Test for DualQuaternion.fromAxisAngle, fromTranslation (should match result of getTranslation())
Test for DualQuaternion.identity
One more thing I keep forgetting: if I include your name in contributors, haxelib associates the library with your username. It is easier for me to just credit you in the CHANGELOG.md (and class file). I found this out the hard way a year ago when someone updated my Haxe REST Client library and I tried to submit the change. Basically haxelib doesn't differentiate contributors and owners: https://lib.haxe.org/documentation/faq/

@nanjizal
Copy link
Author

Getting a strange edge case which I have omitted for now.
eee2323#diff-d019ead88319c7f5c2e86f45914ddc77R163
Still some more tests to add. For moment I have put all Quaternions stuff in new Test class but can move it back to Test3D once I am happier with it.

@nanjizal
Copy link
Author

@tbrosman Are these tests suitable or does it need more coverage? I am not yet sure how to deal with the one odd failure, I expect styling needs improvement I can move it back into Test3D and tidy styling if you feel the tests are suitable, and take another look at the edge case.

@nanjizal
Copy link
Author

Had quite a few problems with pushing to specific branches, but my current changes should all be there.

@nanjizal
Copy link
Author

I was going to ask do you use a plugin or something to apply styles, do you use the 'recommended' haxe styling, I think that has a plugin or similar but not tried it yet.

#if (sys && !EXIT_ON_FINISH)
Sys.stdin().readLine();
#else
#elseif !js
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be #elseif sys. I missed that case when I wrote the test driver.

* @param t The Vector4 ( translation )
* @return The DualQuaternion
*/
public static inline function fromAxisAngle( angleDegrees:Float
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: should match existing function style (in this case just put it all on the same line)

Spacing below should also match existing.

*/
public static inline function fromAxisAngle( angleDegrees:Float
, axis: Vector3
, vec4: Vector4 ):DualQuaternion
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be "t" or "translation" or something (also update documentation to match).

{
var cosHalfAngle = Math.cos(theta / 2.0);
var sinHalfAngle = Math.sin(theta / 2.0);
var real = new Quaternion(cosHalfAngle,sinHalfAngle * axis.x,sinHalfAngle * axis.y,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should live in Quaternion. Then you can call Quaternion.fromAxisRadian.

* @param a
* @return ~a
*/
@:op(~A)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I said in my previous comment, this might not make the most sense for choice of conjugate. Here's my reasoning:

  • Rotation by a unit length quaternion q is calculated as q * v * (~q) (where ~q is the complex conjugate).
  • With this convention, transformation by a dual quaternion q would be written q * v * (~q.dualConjugate()) which is kind of gross (also, dualConjugate doesn't exist yet, so you can't actually write this).

public inline function applyScale(s:Float):DualQuaternion
{
var cloned = clone();
cloned = cloned*DualQuaternion.scalar( s );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just call scaleMultiply? Unless scalar() is inlined, this will create an intermediate DualQuaternion.


private inline function get_normal():DualQuaternion
{
var mag = dot(this, this);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually the magnitude, but the magnitude squared. Just call .length.

private inline function get_normal():DualQuaternion
{
var mag = dot(this, this);
if( mag < 0 ) return null;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition is impossible to hit. Dot products are always >= 0 by definition (if it isn't, it's not a dot product). I think you want to check for when mag == 0. In that particular case you should just return the existing dual quaternion (it is the zero dual quaternion).

public inline function normalize(): DualQuaternion
{
var mag = dot( this, this );
if( mag < 0 ) return null;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicates code with get_normal. Suggestion: call .clone().normalize() in get_normal. I actually don't do this correctly in my Quaternion code, so normal does fail on 0-length quaternions (oops).

*/
public inline function rotate(u:Vector3):Vector3
{
normalize();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quaternion doesn't implicitly normalize on rotate, so neither should DualQuaternion. It is up to the caller to make the trade-off between precision and speed.

* @param b The other quaternion.
* @return The arccosine angle between this vector and the other in radians.
*/
public inline function angleWith(b:Quaternion):Float
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unnecessary. There's an angleWith on Quaternion, so the caller can just call dualQuaternion.real.angleWith(quaternion).

*
* @return The modified object.
*/
public inline function applyDualConjugate():DualQuaternion
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder: needs to be implemented.

// yaw (Z), pitch (Y), roll (X)
@:forward
abstract Euler( Vector3 ) from Vector3 to Vector3 {
public inline function new( roll: Float, pitch: Float, yaw: Float ){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: order fields like existing structures (properties on top, make setter/getter implementations private and put them on the bottom).

import hxmath.math.Matrix4x4;
import hxmath.math.Vector2;

#if !js
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be #if sys

@@ -0,0 +1,36 @@
-cmd echo 'js test'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not possible to reference hxml here? I admit I've never run this on a Mac. What's the difference? I see a lot of cd'ing into directories that doesn't happen on the "regular" hxml targets. Is it something to do with the path convention for running binaries/scripts?

@tbrosman
Copy link
Owner

Looking much better. I left a few more comments, mostly cleanup stuff (and the conjugate operator needs some work).

I'm not using haxecheckstyle or anything (I really should). One day I'll learn how to configure it to look the way I want it to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants