0
votes

I just cannot figure out how to make an a point with a given velocity move around in cartesian space in my visualization while staying around a sphere (planet).

The input:

Many points with:

  1. A Vector3 position in XYZ (lat/lon coordinates transformed with spherical function below).
  2. A Vector3 velocity (eg. 1.0 m/s eastward, 0.0 m/s elevation change, 2.0 m/s northward). Note these are not degrees, just meters/second which are similar to my world space units.

Just adding the velocities to the point location will make the points fly of the sphere, which makes sense. Therefore the velocities need to be transformed so stay around the sphere.

Goal: The goal is to create some flowlines around a sphere, for example like this:

Example image of vectors around a globe

Example image of vectors around a globe

So, I have been trying variations on the basic idea of: Taking the normal to center of my sphere, get a perpendicular vector and multiply that again to get a tangent:

// Sphere is always at (0,0,0); but just to indicate for completeness:
float3 normal = objectposition - float3(0,0,0);

// Get perpendicular vector of our velocity.
float3 tangent = cross(normal,velocity);

// Calculate final vector by multiplying this with our original normal
float3 newVector = cross(normal, tangent);

// And then multiplying this with length (magnitude) of the velocity such that the speed is part of the velocity again.
float final_velocity = normalize(newVector) * length(velocity);

However, this only works for an area of the data, it looks like it only works on the half of the western hemisphere (say, USA). To get it (partially) working at the east-southern area (say, South-Africa) I had to switch U and V components.

The XYZ coordinates of the sphere are created using spherical coordinates:

x = radius * Math.Cos(lat) * Math.Cos(lon);
y = radius * Math.Sin(lat);
z = radius * Math.Cos(lat) * Math.Sin(lon);

Of course I have also tried all kinds of variations with multiplying different "Up/Right" vectors like float3(0,1,0) or float3(0,0,1), switching around U/V/W components, etc. to transform the velocity in something that works well. But after about 30 hours of making no progress, I hope that someone can help me with this and point me in the right direction. The problem is basically that only a part of the sphere is correct.

Considering that a part of the data visualizes just fine, I think it should be possible by cross and dot products. As performance is really important here I am trying to stay away from 'expensive' trigonometry operations - if possible.

I have tried switching the velocity components, and in all cases one area/hemisphere works fine, and others don't. For example, switching U and V around (ignoring W for a while) makes both Africa and the US work well. But starting halfway the US, things go wrong again.

To illustrate the issue a bit better, a couple of images. The large purple image has been generated using QGIS3, and shows how it should be:

Unfortunately I have a new SO account and cannot post images yet. Therefore a link, sorry.

Correct: Good result Good result

Incorrect: Bad result Bad result

Really hope that someone can shed some light on this issue. Do I need a rotation matrix to rotate the velocity vector? Or multiplying with (a correct) normal/tangent is enough? It looks like that to me, except for these strange oddities and somehow I have the feeling I am overlooking something trivial.

However, math is really not my thing and deciphering formula's are quite a challenge for me. So please bear with me and try to keep the language relative simple (Vector function names are much easier for me than scientific math notation). That I got this far is already quite an achievement for myself.

I tried to be as clear as possible, but if things are unclear, I am happy to elaborate them more.

1

1 Answers

0
votes

After quite some frustration I managed to get it done, and just posting the key information that was needed to solve this, after weeks of reading and trying things.

The most important thing is to convert the velocity using rotation matrix no. 6 from ECEF to ENU coordinates. I tried to copy the matrix from the site; but it does not really paste well. So, some code instead:

Matrix3x3:

-sinLon, cosLon, 0,
-cosLon * sinLat, -sinLon * sinLat, cosLat,
 cosLon * cosLat, sinLon * cosLat, sinLat

Lon/Lat has to be acquired through a Cartesian to polar coordinate conversion function for the given location where your velocity applies.

Would have preferred a method which required no sin/cos functions but I am not sure if that is possible after all.