Jump to content

Getting distance to the terrain from a ship's coordinates. Help!


ummwut

Recommended Posts

I've been playing with various bits of information available during flight, but nothing seems to give very conclusive or consistent results (or behavior; one seems to stick to the value of -1 after fluctuating wildly during launch).

I have no idea how I should go about doing this.

Link to comment
Share on other sites

Take a look at this image I just created.

qDPHKv0.png

In this instance, let's assume:

- That you are at A

- You want to be at C

- Up is the Y Axis

Now that we have assumed those things, lets clear some other things up.

- L, W, and H are the distance between your targets X, Y and Z co-ords

- a is the distance between You/A and the air above C, which is also the same as your Up/Y co-ords

- b is the distance between You/A and your target

Use Pythagorean formula to find a, using the forward and sideways co-ords

a = sqr[ (L*L) + (W*W) ]

With sqr representing Square Root.

Now you have the distance from your co-ords to the Up/Y co-ords above your target, C.

Since we have a, we can now move on to the grey plane. The grey plane is neither the Sideway/X, Up/Y, or Forward/Z planes, but a mixture of the three, with the Up/Y plane being the major one.

Another thing to note is that we want to find c, which is the distance between A and C.

This is easy, as it is just another Pythagorean formula.

c = sqr[ (a*a) + (b*B) ]

After going through with that formula, you will have c. c is the distance between You/A and Your Target/C

I hope this helped, and if anyone sees anything wrong with this, tell me. I'm just going by memory.

Link to comment
Share on other sites

I'm looking for a way to determine the exact distance between me and a planet's collision mesh so I'm not taken by surprise when I crash into it. Distance to the ground itself, not the altitude reading.

Edited by ummwut
Because.
Link to comment
Share on other sites

@tetriswizard: I know. Relax. It wouldn't be hard to extend it to 4-D or 5-D or 5.2-D either. I didn't major in math for nothing :P

@shand: I guess I'll have to crawl through the source for Engineer Redux to get answers, something I hope I didn't need to do, as I fully expected a simple solution. Oh well!

Link to comment
Share on other sites

Share some of my code here, which you can also find in HydroTech RCS Autopilot

Method #1: Physics contact, i.e. go down from a point and see how far it can go until hitting the ground

        protected bool PhysicsContactMethod(
Vector3 origin,
Vector3 direction,
float maxDistance, // the max distance of detection, to pass into Physics.Raycast
out float result
)
{
RaycastHit sfc;
if (Physics.Raycast(origin, direction, out sfc, maxDistance, 1 << 15))
{
result = sfc.distance;
return true;
}
else
{
result = 0.0F;
return false;
}
}

Method #2: Load main body terrain information and get terrain height of given latitude/longitude

        protected bool MainBodyTerrainMethod(Vector3 origin, out float result)
{
if (MainBody.pqsController != null)
{
result = (float)(
altASL - (MainBody.pqsController.GetSurfaceHeight(
QuaternionD.AngleAxis(MainBody.GetLongitude(origin), Vector3d.down)
* QuaternionD.AngleAxis(MainBody.GetLatitude(origin),
Vector3d.forward) * Vector3d.right
) - MainBody.pqsController.radius)
);
return true;
}
else
{
result = 0.0F;
return false;
}
}

where

altASL = (float)MainBody.GetAltitude(origin);
/* EDIT: forgot this */ CelestialBody MainBody { get { return FlightGlobals.ActiveVessel.mainBody; } }

Also, if you want the true altitude (distance to terrain OR sea), make sure to pick the smaller one.

BTW, MechJeb has done almost everything, and its code is available online, so it's a good idea to learn things from it if you're new.

Edited by Michael Kim
Link to comment
Share on other sites

I fully expected a simple solution. Oh well!

Height above terrain is easy enough, it's vessel.heightFromTerrain. If you want your height about your predicated landing spot the difficult bit is predicting it - especially with atmosphere. Once you have it then you can use GetSurfaceHeight.

I believe Mechjeb's landing autopilot does landing predictions, so that's probably the code to look at.

Link to comment
Share on other sites

Height above terrain is easy enough, it's vessel.heightFromTerrain.

It doesn't work when the vessel is high above the surface. I did look at MechJeb, and what it does is exactly using the two methods I listed above (or more precisely speaking, I learned them from MechJeb but wrote the code in my own way). Don't use heightFromTerrain when in orbit, seriously.

Edited by Michael Kim
Link to comment
Share on other sites

It doesn't work when the vessel is high above the surface.

Well no, it obviously won't work when there's no terrain loaded below you. I'm slightly surprised it doesn't fall back to height from surface automatically but it should be easy to do it manually if it does give junk data.

Link to comment
Share on other sites

Well no, it obviously won't work when there's no terrain loaded below you. I'm slightly surprised it doesn't fall back to height from surface automatically but it should be easy to do it manually if it does give junk data.

Well anyway MechJeb doesn't use it. I'm not saying MechJeb is god here, but at least it means heightFromTerrain is not the best choice.

Link to comment
Share on other sites

@Michael Kim: Can you go through the first PHP code box and tell me about what each item is and what it's doing? There's very little documentation on the Assembly-CSharp library.

Also, HeightFromTerrain and HeightFromSurface do not work. Or if they do, their output is indecipherable to me.

Link to comment
Share on other sites

@Michael Kim: Can you go through the first PHP code box and tell me about what each item is and what it's doing? There's very little documentation on the Assembly-CSharp library.

Physics.Raycast is a unity function, not a KSP one:

http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html

All it's doing is hitting the first collision box along the distance vector specified. It's likely to return no hit or the spherical surface if you're too far away for the terrain to load.

Also, HeightFromTerrain and HeightFromSurface do not work. Or if they do, their output is indecipherable to me.

I haven't used them recently but I'd expect to get height in meters. What values are you getting?

Link to comment
Share on other sites

Physics.Raycast is a unity function, not a KSP one:

http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html

All it's doing is hitting the first collision box along the distance vector specified. It's likely to return no hit or the spherical surface if you're too far away for the terrain to load.

I haven't used them recently but I'd expect to get height in meters. What values are you getting?

Raycast I understand; it's pretty straightforward.

HFT and HFS both give a value of -1 above 20k meters, but below that, HeightFromTerrain gives what I assume is exactly what it says on the tin, in meters.

For CelestialBody, what's SurfaceNVector? I assume it's a point tangent to the terrain pointing north, but does it assume the Body is a perfect sphere?

Link to comment
Share on other sites

HFT and HFS both give a value of -1 above 20k meters, but below that, HeightFromTerrain gives what I assume is exactly what it says on the tin, in meters.

HFS isn't the altitude reading? Just use something like

(this.transform.position - body.transform.position).magnitude - body.radius

when HFT is returning -1.

For CelestialBody, what's SurfaceNVector? I assume it's a point tangent to the terrain pointing north, but does it assume the Body is a perfect sphere?

I'd assumed it was a normal vector. It does seem to go by a perfect sphere though.

Link to comment
Share on other sites

What is transform and what is this doing? I'm really not familiar with game programming or 3D calculations.

Every GameObject has a Transform component attached to it, this holds the position, rotation and scale of the object. In this case we're grabbing the position.

The line as a whole subtracts the position of the vessel from the position of the centre of the planet, which gives you the vector between planet and vessel. It then takes the length of this vector (aka distance from vessel to center of planet) and subtracts the radius of the planet giving you the distance to the mean level.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...