From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Chris_12345

Member

06-13-2016 11:29 AM

Options

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

I am using a VI in the LV 2014 distribution called "NI_AALPro.lvlib:3D Coordinate Conversion (Scalar).vi". This uses DBL inputs and outputs, and has several Build Array functions in it as well as a Call Library Function. I need to perform a massive number of Cartesian to Spherical conversions with SGL values, and so I would like to re-write this VI using LV primitives in the most efficiant manner possible.

The math appears to be quite simple, and I have attached a VI that does this. However, there is an issue with calculating the polar angle. From what I read online, it is just arctan (y/x), yet I get incorrect values when x is negative (but not when y is negative).

From what I read on the Wolfram site, "the inverse tangent must be suitably defined to take the correct quadrant of (x/y) into account". I have searched online for more detail on the calculation, but I am lost. Any trig whizzes out there who can help me?

Solved! Go to Solution.

Darin.K

Trusted Enthusiast

06-13-2016 01:46 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Use atan2(y,x) instead

altenbach

Knight of NI

06-13-2016 02:15 PM - edited 06-13-2016 02:26 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Use simple complex math. Seems to work and gives the same result as "cartesian to spherical".

Please test and see if it is correct.

(Works equally well with SGL, DBL and arrays of any dimension.)

Solution

Accepted by topic author Chris_12345

Bob_Schor

Knight of NI

06-13-2016 05:20 PM - edited 06-13-2016 05:20 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Definitions are extremely important in defining coordinate systems. The documents that you include with your Cart_to_Sph VI contain numerous mistakes and inconsistencies.

Here is a convention that I use and that seems to have a reasonably wide acceptance (I'm not sure that this is the Wolfram convention, however).

Let X, Y, and Z be a right-hand coordinate system. Let P be a point whose X, Y, Z coordinates we know. Define a Spherical Polar Coordinate (SPC) system as follows:

- Project a line from the Origin to P.
- Radius (rho) -- Length of the line from the Origin to P.
- Project the line onto the X-Y Plane.
- Azimuth (theta) -- Angle measured counterclockwise from the X axis to this Projected Line. By convention, theta ranges from minus pi (radians) to pi.
- Polar angle (phi) -- the angle between the Z Axis (or "pole") and the line from the Origin to P. By convention, phi ranges from 0 to pi.

Under this coordinate system, the following code (very similar to Altenbach's, which uses a slightly different coordinate system) maps X, Y, Z into Rho, Theta, Phi:

Let's check some "known quantities". Start with the Unit X axis, [1, 0, 0]. This clearly has length, Rho = 1. The X axis lies in the XY plane, so the angle between it and the Z axis is 90°, so Phi should be pi/2. Finally, the projection of the X axis in the XY plane lies along the X axis, so the angle between the two X axes is 0, so Theta should be 0. The first Re/Im to Polar will give 1, 0, so Theta = 0. The second will give 1, pi/2, so Rho = 1 and Phi = pi/2.

How about Unit Z, [0, 0, 1]? Again, the length, Rho, is 1. Technically, since the Z axis projects onto the origin, the azimuthal angle cannot be properly defined (as both X and Y coordinates are 0), so we'll do a "math cop-out" and just say it's zero. The Polar angle is easy -- the angle between the Z axis and the pole, the Z axis, is 0, so Phi = 0. Now "do the math". Putting [0, 0] into the first Re/Im to Polar gives [0, 0], so Theta = 0. The second Re/Im to Polar takes [1, 0] into [1, 0], so Rho = 1 and Phi = 0.

It is easy to show (especially by coding this up and putting in test numbers) that negative quantities work properly. Rho is always non-negative, Phi is always in the range 0 .. pi, and Theta is always -pi .. pi, with the sign dependent on the sign of Y (as it should be).

Bob "Just Do the Math" Schor

P.S. -- if you think __this__ is fun, just try 3-D rotation matrices ...

altenbach

Knight of NI

06-13-2016 05:30 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Bob_Schor

Knight of NI

06-13-2016 05:40 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Defining (and understanding the definition of) the coordinate system is definitely key here. However, it is __so__ easy to make silly mistakes (just check out the printed material the OP included with the Cart_to_Sph VI, and the mixing of names and Greek letters). I'd say we are in complete agreement ...

BS

altenbach

Knight of NI

06-15-2016 09:53 AM - edited 06-15-2016 10:54 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

@Darin.K wrote:Use atan2(y,x) instead

Of course "atan2" and "RE/IM to Polar" give you the identical result for the angle, but with the complex primitive we also get r for free, which we need here anyway.

Some quick benchmarking shows that the complex version is only a few % slower* (but it also caclulates r!). If we use atan2 and calculate r seperately, we are slower than the complex version.

Complex also wastes less diagram space. 😄

* note that these speed differences are irrelevant and many other code changes have similar subtle effects. Unless we get at least a factor of two, I don't worry and go with the cleaner code. 🙂

06-17-2016 04:52 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Thank you everyone for all your help. Attached are my final pair of VIs.

Download All

Virus scan in progress. Please wait to download attachments.

07-06-2016 04:42 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator

Continuing on with this discussion, I found some unexpected behavior while comparing the efficiency of the algorithms. See attached VIs (LV-2014).

The first one, SpeedTest1.vi, allows you to compare three different Cartesian-to-Spherical conversion methods. It behaves as expected, with the Real/Imag algorithm running the fastest. All well and good. Then I decided to see what effect using SGL vs DBL would have, so I put a case structure in to try these, SpeedTest2.vi.

Strangely, despite both VIs using the same algorithm, Real/Imag, and both with SGL inputs, the efficiency is vastly different. The only code difference is the presence of the SGL/DBL case structure, which seems to slows things down by a factor of 20x

Any ideas on why there would be such a huge slowdown just from the presence of the case structure?

Download All

Virus scan in progress. Please wait to download attachments.

07-06-2016 05:11 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report to a Moderator