KSP-KOS / KOS

Fully programmable autopilot mod for KSP. Originally By Nivekk
Other
691 stars 229 forks source link

Enhance VANG with optional 3rd arg to allow signed result #3065

Open darthgently opened 2 years ago

darthgently commented 2 years ago

Add a 3rd optional position vector arg to VANG that when flattened into the plane of the 1st two args would act as a zero reference point for signing the result such that the order of the 1st two args along with the 3rd arg would determine sign of result.

Dunbaratu commented 2 years ago

Let me re-phrase it to see if I understand what you mean. Tell me if this is right:

So are you proposing that the following thing be do-able directly by kOS instead of in script code:

  function singed_vang {
    parameter v1, v2, v3.

    // The uses of the ":normalized" suffix below wouldn't be relevant in pure math.
    // But with vectors made of the very big floating point numbers you can get in KSP,
    // vector operations accumulate a huge amount of error.  (The result vector of VCRS
    // can be aimed as much as 2 or 3 degrees off when working on vectors with
    // magnitude measured in billions.)  So when you don't care about the magnitude of
    // the vector (like when finding the normal to a plane), squashing the vectors down
    // to unit vectors first can prevent these enormous errors.

    local
        v1_unit is v1:normalized,
        v2_unit is v2:normalized,
        v3_unit is v3:normalized.

    local angle is vang(v1_unit, v2_unit).

    // This is a check to keep the math from bombing the script if
    // V1 and V2 are pointing the same way and thus don't define
    // a plane:
    if angle = 0 {
        return angle.
    }

    // Turn v3 into something exactly perpendicular to v1 in the (v1,v2) plane:
    local plane_normal is vcrs(v1_unit, v2_unit).
    local v3_plane_project is vxcl(plane_normal, v3_unit).
    local v3_perpendicular is vxcl(v1_unit, v3_plane_project).

    if VDOT(v3_perpendicular, v2_unit) >= 0 {
        return angle.
    } else {
        return -angle.
    }  
  }

is that generally what you were thinking of having the 3-arg VANG do (but in C# code, not kerboscript like that)?

Dunbaratu commented 2 years ago

(I just edited the example - I had said v2 in a few places I should have said v1.)

darthgently commented 2 years ago

Yes, that nails it

darthgently commented 2 years ago

Well, the =zero VANG check to protect against collinear vectors looks too exact to succeed, but the planar ops look right

Dunbaratu commented 2 years ago

Well, the =zero VANG check to protect against collinear vectors looks too exact to succeed, but the planar ops look right

The usual "don't compare floats exactly" rule of thumb often doesn't apply to certain specific small magnitude integer values like zero or one. For those, values that are meant to land exactly on the value usually will.

In this case the problem is literally only a problem when the vectors are exactly the same. direction so there is no angle between them from which to form a plane. I'm basically trying to avoid the singularity of a vector of zero length having no defined direction it points, and a vector of zero length is what you get for the normal to the "plane" defined by two vectors with zero angle between them. As long as there is even the smallest little bit of angle between the vectors, that singularity condition is avoided.

nuggreat commented 2 years ago

shouldn't that be looking fro 0 or 180 as the parallel check not just 0

Dunbaratu commented 2 years ago

shouldn't that be looking fro 0 or 180 as the parallel check not just 0

Good point.

Alternatively, it could go ahead and run the VCRS() operation anyway, but check if the resulting "normal" is V(0,0,0) and put the abort check there.