[HELP] Finding a Random Location on a Straight Line Between Two Object

Anyone know how to cost this:

Given two objects in the same area, I need to find a random location on a straight line between them. I’ve been playing around with this for several hours and can’t get my head around how to do it.

This is what I have so far:

// Gets a random location on a straight line between two objects

#include "x0_i0_position"

void main()
{
    object oOrig = GetObjectByTag("ORIGIN");
    object oDest = GetObjectByTag("DESTINATION");

    location lOrig = GetLocation(oOrig);
    location lDest = GetLocation(oDest);

    float fAngle = GetAngleBetweenLocations(lOrig, lDest);
    float fDist  = GetDistanceBetweenLocations(lOrig, lDest);

    int nDist = Random(FloatToInt(fDist));
    if (nDist == 0) nDist = 1;

    fDist = IntToFloat(nDist);

    GenerateNewLocationFromLocation(lOrig, fDist, fAngle, 90.0); 

    //orientation set to 90 deg. so icon appears rightside up
    CreateObject(OBJECT_TYPE_PLACEABLE, "tent", lSpawn, FALSE, "WP_CAMPSITE_ICON"); 
}

It generates the random location between the two objects but when I use it, the angle to the target object is wrong. For example, if the angle between the objects is 100 deg., the campsite icon is not created at a location that is 100 deg. angled from the origin.

Geometry is my specialty, so I can answer this.

Math: x + (y - x) * r where r in [0, 1].

Code:

void main()
{
    // PC jumps to a point on line between FIRST and SECOND
    object oPC = GetFirstPC();

    // positions of line ends
    vector vOne = GetPosition(GetObjectByTag("FIRST"));
    vector vTwo = GetPosition(GetObjectByTag("SECOND"));

    // vector from one to two
    vector vDelta = vTwo - vOne;

    // random float between 0 and 1 (both inclusive)
    float fRatio = IntToFloat(Random(32768)) / 32767.0;

    // multiply delta's components by ratio
    vDelta.x *= fRatio;
    vDelta.y *= fRatio;
    vDelta.z *= fRatio;

    // jump to one + modified delta
    AssignCommand(oPC, JumpToLocation(Location(GetArea(oPC), vOne + vDelta, 0.0)));
}

This code is robust and invariant to relative positions of endpoints. They need to be in the same area, of course, but if they aren’t PC should just jump to FIRST.

EDIT: added more comments.

EDIT2: BTW someone (@NWShacker) made a whole library for dealing with this kind stuff.

3 Likes