Jump to content

ME script: determine position x degrees offset from a unit


GusPT

Recommended Posts

Hi,

 

I'm currently working on a A2A training mission, using lua and MIST, and would like to be able to spawn units in a position between 9 and 3' o clock in front of a given unit.

I got the spawning and all that figured down, but I'm struggling with the math to determine the new unit position.

 

Something like this:

 

-- positionVec3: reference unit getPosition().p
 
function cloneGroup(groupNamepositionVec3)
 
    ... transform position to a place point between 9 and 3' o clock in front of the reference unit
 
    local teleportVars = {
      groupName = groupName,
      newGroupName = newGroupName,
      point = positionVec3,
      action = "clone",
      innerRadius = 4000,
      radius = 5000
    }

    local _group = mist.teleportToPoint(teleportVars)
    local group = Group.getByName(_group.name)
    group:activate()
    return group
  end
 

 

 

I'd truly appreciate if anyone could provide an example or point me in the right direction.

 

Thanks!

Link to comment
Share on other sites

I looked into offset points a couple of years ago, @funkyfranky was kind enough to assist and he ended up creating a MOOSE function that returns a vec3 point, offset from a chosen unit by a desired distance in all three axes.  

You basically introduce the desired offset in meters for each axis, the function will take care of the math. 

Most of it is standard Lua, you should have no trouble adapting it to MIST. 

 

Note that :GetOrientationX():GetOrientationY() and :GetOrientationZ()  are the MOOSE way of accessing the DCS orientation tables returned by :getPosition()
(x, y and z subtables only, not the p subtable).


Here's the function.

function POSITIONABLE:GetOffsetCoordinate(x,y,z)

  -- Default if nil.
  x=x or 0
  y=y or 0
  z=z or 0

  -- Vectors making up the coordinate system.
  local X=self:GetOrientationX()
  local Y=self:GetOrientationY()
  local Z=self:GetOrientationZ()

  -- Offset vector: x meters ahead, z meters starboard, y meters above.
  local A={x=x, y=y, z=z}

  -- Scale components of orthonormal coordinate vectors.
  local x={x=X.x*A.x, y=X.y*A.x, z=X.z*A.x}
  local y={x=Y.x*A.y, y=Y.y*A.y, z=Y.z*A.y}
  local z={x=Z.x*A.z, y=Z.y*A.z, z=Z.z*A.z}

  -- Add up vectors in the unit coordinate system ==> this gives the offset vector relative the the origin of the map.
  local a={x=x.x+y.x+z.x, y=x.y+y.y+z.y, z=x.z+y.z+z.z}

  -- Vector from the origin of the map to the unit.
  local u=self:GetVec3()

  -- Translate offset vector from map origin to the unit: v=u+a.
  local v={x=a.x+u.x, y=a.y+u.y, z=a.z+u.z}

  local coord=COORDINATE:NewFromVec3(v)

  -- Return the offset coordinate.
  return coord
end



Here's a version of this script that I made for a test mission, using variables rather than tables, perhaps you'll find it easier to work with:
 

function()

   local Cargo = UNIT:FindByName("Cargo")

  -- Vectors making up the coordinate system.
   local CargoXX = Cargo:GetOrientationX().x
   local CargoXY = Cargo:GetOrientationX().y
   local CargoXZ = Cargo:GetOrientationX().z

   local CargoYX = Cargo:GetOrientationY().x
   local CargoYY = Cargo:GetOrientationY().y
   local CargoYZ = Cargo:GetOrientationY().z

   local CargoZX = Cargo:GetOrientationZ().x
   local CargoZY = Cargo:GetOrientationZ().y
   local CargoZZ = Cargo:GetOrientationZ().z

 
  -- Offset vector: 24 m ahead, 5 meters above, 0 meters starboard (variable format)

   local Offset_X = 24
   local Offset_Y = 5
   local Offset_Z = 0 -- I've set it to 0 because the cargo containers are aligned with the ship's Z origin

 
  -- Scale components (variable format)

   local Scale_XX = CargoXX * Offset_X
   local Scale_XY = CargoXY * Offset_X
   local Scale_XZ = CargoXZ * Offset_X

   local Scale_YX = CargoYX * Offset_Y
   local Scale_YY = CargoYY * Offset_Y
   local Scale_YZ = CargoYZ * Offset_Y

   local Scale_ZX = CargoZX * Offset_Z
   local Scale_ZY = CargoZY * Offset_Z
   local Scale_ZZ = CargoZZ * Offset_Z

  -- Add up the relevant scale components to get the final offset values

   local Addition_X = Scale_XX + Scale_YX + Scale_ZX
   local Addition_Y = Scale_XY + Scale_YY + Scale_ZY
   local Addition_Z = Scale_XZ + Scale_YZ + Scale_ZZ


 -- Get PointVec3 and add up vectors in the unit coordinate system ==> this gives the offset vector relative the the origin of the map (variable format)

   local Cargo_Offset_PointVec3 = Cargo:GetPointVec3():AddX(Addition_X):AddY(Addition_Y):AddZ(Addition_Z)

 -- Flare

   Cargo_Offset_PointVec3:FlareRed()
 
end

 


Edited by Hardcard
  • Like 1
Link to comment
Share on other sites

6 hours ago, GusPT said:

... transform position to a place point between 9 and 3' o clock in front of the reference unit

 

Hi, as a supplementary option, here is code I use to do that, just slightly modified to use your terms and values (so not tested but should work, "positionVec3" is a point placed 4 to 5 km away in front of "reference_unit", and between its 9 to 3 o'clock) :

 

Spoiler

local refPoint = reference_unit.getPoint()
local dir1 = mist.getHeading(reference_unit)
local dir3 = mist.utils.round(dir1, 1)
repeat
unitSpawnPoint = mist.getRandPointInCircle(refPoint, 5000, 4000)
positionVec3 = mist.utils.makeVec3GL(unitSpawnPoint) -- mist.utils.makeVec3(unitSpawnPoint, refPoint.y) if you want point at reference_unit's altitude instead of ground level
vec = {x = positionVec3.x - refPoint.x, y = positionVec3.y - refPoint.y, z = positionVec3.z - refPoint.z}
dir4 = mist.utils.getDir(vec, refPoint)
dir2 = mist.utils.round(dir4, 1)
until dir2 < dir3 + 1.57 and dir2 > dir3 - 1.57

 

  • Like 1
Link to comment
Share on other sites

Thanks for the quick responses guys. 💪

 

If I understand correctly @Hardcard approach is deterministic while @toutenglisse tries to get a position within the angle restrictions, which might have a performance impact for what I want to do.

However both approaches are useful and come to think of it, I can probably extract the mist.getRandPointInCircle code   (also looking for some randomness here for the radius) and change it to limit it to the angles I'm looking for. Then transform the result to a vec3 using mist.utils.makeVec3.

 

Wish I had paid more attention to my algebra classes.. 😅

 

I'll post back the results when I'm done.

Link to comment
Share on other sites

@GusPT

Doesn't need to be deterministic,  you can randomize the offsets at your convenience, ofc.

 

As long as the x offset is a positive number, the spawn point will be ahead of the chosen aircraft (regardless of its orientation).
As for the z offset, it can be either positive (right side relative to aircraft) or negative (left side relative to aircraft).

Y offset is for altitude, + = above, - = below.

The offset point doesn't even have to be the actual spawn point, you can use it as the center of a spawn zone instead (from which you can get a random spawn point). 


Think of it like a big ass Cartesian graph, with your aircraft at the origin.
 

12 o'clock? x = positive number, z = 0

9 o'clock?  x = 0, z = negative number

3 o'clock? x = 0, z = positive number

 

45º right?  x = z ( as long as the value is greater than 0 )

45º left? z = x * -1 ( x needs to be a positive number greater than 0 )

etc.


Edited by Hardcard
Link to comment
Share on other sites

Ah crap. I apparently forgot to update the documentation. mist.getRandPointInCircle has the ability to limit the range of angles used to generate a point since 2017. So you can make the possible area pacman shaped if you wanted to. Should be something like this. 

 

local u = Unit.getByName('whatever')

local heading = mist.getHeading(u, true)

local headingDeg = math.deg(heading)

local newPoint = mist.getRandPointInCircle(u:getPoint(), 20000, 10000, headingDeg +90, headingDeg - 90)

 

Might have to switch the headingDeg values since I kinda forgot how its supposed to work. Big oof. 

 

Edit; updated the wiki documentation and confirmed that the above example is correct. 

Screen_210603_170356.jpg


Edited by Grimes
New information has come to light man
  • Like 1
  • Thanks 2

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Link to comment
Share on other sites

@Hardcard absolutely. I meant deterministic in the sense that there are no retries, just need to input the proper values. Perhaps I chose the wrong word.

 

@Grimes I've been using mist 4.3.74, didn't even know there was a new version, thought the project was dead and replaced by Moose. Good stuff!!

Will have a look to see what else is new, but it seems this version does exactly what I want. 

 

Thanks!

 

Link to comment
Share on other sites

Not dead, but certainly slowed down. I'm rather content with it being the lightweight option and have always preferred adding other scripts that use it to handle specific things like CTLD, my old IADScript, and others. Doesn't help that DCS patches aren't exactly a treasure trove of new scripting functions, so there isn't a constant need to add functionality. I'll typically add stuff whenever I delve into mission making as I'll end up making something useful that could be adapted for mist. The functions added back in November are a result of that for example. 

 

I also have a habit of only using the development branch on github and only merge it to the main branch rarely. 

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Link to comment
Share on other sites

Totally agree. I've been kept using Mist due to its lightweight, MOOSE is too cumbersome for the most stuff I've been working on. It's nice to know Mist we'll be still be around for some time.

 

Thanks for your work @Grimes

 

edit: BTW, the new parameters work great!


Edited by GusPT
Feedback on new getRandPointInCircle
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...