Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Perl and Quaternions

by kcott (Archbishop)
on May 08, 2014 at 11:37 UTC ( [id://1085445]=note: print w/replies, xml ) Need Help??


in reply to Perl and Quaternions

G'day Fair Strides,

Some sample input data, actual results and expected results would have helped. A short script that reproduced your problem would have helped even more: we could have run it, tweaked it and suggested modifications. The guidelines in "How do I post a question effectively?" explain how to do this.

"Here's the code I have for reading the info from a hash-of-hashes ..."

As I already alluded to, you provide no indication of the structure of this "hash-of-hashes" nor what data populates it. In the code, you have variables with no indication of how they were declared or what values they might hold. In order to troubleshoot this, we'd need to make many guesses regarding data, context and the value of variables: guessing is not a good way to proceed.

"and the code that takes the measure of degrees ..."

Much the same comments apply here also. It looks like Tk code but you don't specify this. It contains non-essential, distracting clutter like font families and sizes; but important information, such as variable declarations, is missing.

Here's a few comments on what you have provided:

  • Use the strict pragma in all your scripts; I do! It will alert you to many little mistakes that you often won't notice: typos in variable names; missing or incorrect sigils; missing or duplicate declarations; and so on. In the code you posted, there are multiple places where such alerts would be raised.
  • Use the warnings pragma in all your scripts; I do! This will alert you to a huge number of potential problems. I can see four places in your posted code where you'll not only receive a warning but also actual code to replace what you've written (e.g. "your_code" better written as "better_code").
  • Was there a reason you commented out "my $pi = 4*atan2(1,1)" and used a hard-coded value instead?
  • "# Read in from the Hash. The function that reads from the file returns an anon Array, so I have to access as a scalar, then turn it into an Array.": Comments like this don't help at all! There's no function, no file, no filehandle and an intermediary variable is unnecessary: just use my @arrayname = @{ expression_evaluating_to_arrayref };.
  • Learn about Slices. Use @arrayname[@indexes] for an array slice and $arrayname[$single_index] for a single array element.
  • When you have an array and want to access single elements, just do it. Don't assign array elements to $element1, $element2, ..., $elementN.

See also: Math::Trig (for pi constants and functions such as deg2rad); Math::Quaternion (for the creation and manipulation of quaternions); SecondLife::Rotation (for an example of how to subclass Math::Quaternion, should you need that).

"The game has a built-in scripting language, ..."

[The following (in the spoiler) has nothing at all to do with Perl; it's about NWScript. Of interest to the OP, but of little or no interest to others.]

-- Ken

Replies are listed 'Best First'.
Re^2: Perl and Quaternions
by Fair Strides (Acolyte) on May 08, 2014 at 13:39 UTC

    I apologize for the terrible formatting of the question, everyone.

    I'm not used to posting here, and actually am more used to people knowing where my code is coming from(this familiarity coming from my time at Holowan Labs, at LucasForums). This is not an excuse, merely a statement about my own ignorance.

    To address everything in your post, Ken, and hopefully everything else, let me try this again.

    I'm trying to convert between radians and degrees from a given degree, for use in a quaternion format, particularly in translation between Quaternion values and Euler angles. I took another look at how the games I mod, Star Wars Knights of the Old Republic it's sequel, use Quaternions. And it looks like I messed up:

    Z = sin (angle/2) Y = 0.0 X = 0.0 Q = cos (angle/2)

    In my eyes, it was a simple mistake, though you guys might judge differently. I had always assumed that the values I needed were X and Y because that was how the game referenced them in it's files.

    So, some example code was asked for. This code can be run from the commandline and will ask for an input value. Be sure to input it in degrees.

    use strict; use warnings; use Math::Complex; my $pi = 4*atan2(1,1); sub deg_to_rad { ($_[0]/180) * $pi; } sub rad_to_deg { ($_[0]/$pi) * 180; } print "Enter a value: "; my $value = <STDIN>; my $radvalue = deg_to_rad($value); my $degvalue = rad_to_deg($radvalue); my $quat1 = sin($radvalue); my $quat1_deg = rad_to_deg($quat1); my $quat2 = cos($radvalue); my $quat2_deg = rad_to_deg($quat2); print "Original value: $value\n"; print "Radian value: $radvalue\n"; print "Degree value: $degvalue\n\n"; print "Quaternion first value: \t$quat1\n"; print "Quaternion first value(in degrees): \t$quat1_deg\n"; print "Quaternion fourth value: \t$quat2\n"; print "Quaternion fourth value(in degrees): \t$quat2_deg\n";

    Inputting 90 degrees should bring up the radian value, 1.570796 blahblahblah, but it doesn't. I'm using the Math::Complex module, so that might be the difference between the expected results, but I'm not sure...

    About the example code I posted that the game uses, yes it is NWScript. And I'm known for being accurate when I script in it, but on this occasion I didn't copy-and-paste correctly, so now feel kinda stupid for that. Also, I posted it for the sole reason of showing anybody who might care to know how the game calculates the values, which might help me do the opposite and calculate the facing from the values.

    I admit that the spinbox widget isn't really optimal for this; it was more of a test on that part. It's easy enough to switch it to an entry widget with a binding to the Enter key, though, so I'm not too worried about it. However, thanks for pointing it out, Ken.

    I tend to not use the strict pragma because it interferes with the TK code, in that when it forces me to put quotes around certain text, the options aren't accepted by TK... However, warnings should definitely have been used. Sorry about that, Ken.

    I alternated between either value of Pi to see if there was any functional difference in the conversion subroutines.

    Sorry about the clutter in the code samples. I was trying to give you guys enough info without chucking the whole script in, and without leaving out something that might be important and then get me flamed for not adding it in when it was so essential for the people answering to know that ahead of time...

    Also, could you please be more specific about what you meant when you mentioned Array slices? You mentioned them, but never where in my code samples they might be used...

    And I found Math::Quaternion myself while doing research, but I have no clue how to interpret it's 3x3 or 4x4 output, given that I just need four values...

    I apologize, Ken, and wish I could elaborate more and get some more help, but I need to head off to school now. I'll be checking back in at lunch, see if anything's new. Thanks for the helpful comments, Ken!

      "So, some example code was asked for. This code can be run from the commandline and will ask for an input value. Be sure to input it in degrees."

      Thanks. That looks like a much better sample that we can work with.

      "Inputting 90 degrees should bring up the radian value, 1.570796 blahblahblah, but it doesn't."

      Actually, it does when I run it.

      Enter a value: 90 Original value: 90 Radian value: 1.5707963267949 Degree value: 90 Quaternion first value: 1 Quaternion first value(in degrees): 57.2957795130823 Quaternion fourth value: 6.12323399573677e-17 Quaternion fourth value(in degrees): 3.50835464926744e-15

      And, just to confirm that's the correct result:

      $ perl -E 'say(4*atan2(1,1) / 2)' 1.5707963267949

      I suggest you run this again and check the output. Also check that you're running exactly the same code that you posted.

      "I'm using the Math::Complex module, so that might be the difference between the expected results, but I'm not sure..."

      Although you've loaded the Math::Complex module, I don't see any code that uses its functionality. In fact, if I comment out "use Math::Complex;", the output remains exactly the same.

      However, even if you were using Math::Complex's constants or functions, I can't see how you'd get anything different. Here's some fragments from its source code:

      ... sub pi () { 4 * CORE::atan2(1, 1) } ... sub cos { my ($z) = @_ ? @_ : $_; return CORE::cos($z) unless ref $z; ... } ... sub sin { my ($z) = @_ ? @_ : $_; return CORE::sin($z) unless ref $z; ... } ...

      And repeating the confirmation using pi from Math::Complex:

      $ perl -MMath::Complex -E 'say(pi / 2)' 1.5707963267949
      "I tend to not use the strict pragma because it interferes with the TK code, in that when it forces me to put quotes around certain text, the options aren't accepted by TK..."

      Frankly, that's a poor reason to remove all strictures from your entire script. If quoting right and x in

      ...->pack(-side=>right); ... ...->pack(-expand=>1, -fill=>x);

      is really such a burden, write them like this:

      ...->pack(qw{-side right}); ... ...->pack(qw{-expand 1 -fill x});

      On the rare occasions when you really do need to turn off a stricture, turn off just one and do it the smallest scope possible. For example

      use strict; ... # all strictures on here { no strict 'refs'; # 'vars' and 'subs' strictures still on here ...; # <--- minimal code requiring "no strict 'refs'" } # all strictures on here ...
      "However, warnings should definitely have been used."

      I'm not certain whether you're saying they weren't used or weren't shown. Had they been used, you would have received multiple messages like this:

      $ perl -Mwarnings -E 'my @x = qw{1 2 3}; my $y = @x[1]' Scalar value @x[1] better written as $x[1] at -e line 1.

      This is what I was referring to in my previous post with: "I can see four places in your posted code where you'll not only receive a warning but also actual code to replace what you've written (e.g. "your_code" better written as "better_code")."; although, I've now spotted two more.

      "Also, could you please be more specific about what you meant when you mentioned Array slices? You mentioned them, but never where in my code samples they might be used..."

      Don't use slices like this (as per my previous point):

      my $qx = @cam_quats[0]; my $qy = @cam_quats[1];

      You didn't show how you were intending to use $qx or $qy. If they were just for their values, you don't need them at all: you can use $cam_quats[0] and $cam_quats[1]. If, on the other hand, you wanted to modify these values without changing @cam_quats, you could have used a slice like this:

      my ($qx, $qy) = @cam_quats[0,1];

      However, when I originally made that point, I was thinking more about this code:

      my $cam_ori1 = @cam_ori[0]; # X-orientation my $cam_ori2 = @cam_ori[1]; # Always 0 my $cam_ori3 = @cam_ori[2]; # Always 0 my $cam_ori4 = @cam_ori[3]; # Y-orientation # Debugging print-out print "Orientation:\n\t$cam_ori1\n\t$cam_ori2\n\t$cam_ori3\n\t$cam +_ori4\n\n"; # The orientation values are stored as radians, so # calc_quatcam returns the degree equivalent, or should... my @cam_quats = calc_quatcam($cam_ori1, $cam_ori4);

      which you could've written like this using slices:

      # Debugging print-out print join("\n\t", 'Orientation:', @cam_ori[0..3]), "\n\n"; # The orientation values are stored as radians, so # calc_quatcam returns the degree equivalent, or should... my @cam_quats = calc_quatcam(@cam_ori[0,3]);

      As you can see, you no longer need any of: $cam_ori1, $cam_ori2, $cam_ori3 or $cam_ori4. Refer back to the dot point following the one about slices.

      Regarding "am more used to people knowing where my code is coming from", "Sorry about the clutter in the code samples." (and a few other related points), take a look at "I know what I mean. Why don't you?" which should address most of these.

      This is only your second post so don't concern yourself too much about mistakes you've made. Mistakes are good: we all make them and, hopefully, all learn from them. :-)

      -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1085445]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-26 00:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found