From 804b8a800ef4cfe664e20f3342fb4a8d4374ea1e Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Sun, 10 Jun 2018 01:46:22 +0200 Subject: [PATCH 1/3] Added basic offset support to ZoneUnit --- Moose Development/Moose/Core/Zone.lua | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 72317d2ba..fd65dcf2d 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -961,7 +961,7 @@ end --- # ZONE_UNIT class, extends @{Zone#ZONE_RADIUS} -- --- The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius. +-- The ZONE_UNIT class defined by a zone attached to a @{Unit#UNIT} with a radius and optional x and y offsets. -- This class implements the inherited functions from @{#ZONE_RADIUS} taking into account the own zone format and properties. -- -- @field #ZONE_UNIT @@ -969,14 +969,21 @@ ZONE_UNIT = { ClassName="ZONE_UNIT", } ---- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius. +--- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius and optional offsets in X and Y directions. -- @param #ZONE_UNIT self -- @param #string ZoneName Name of the zone. -- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone. -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. +-- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. +-- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius ) +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy ) + + self.dy = dy or 0.0 + self.dx = dx or 0.0 + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) + self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) self.ZoneUNIT = ZoneUNIT @@ -988,12 +995,18 @@ end --- Returns the current location of the @{Unit#UNIT}. -- @param #ZONE_UNIT self --- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location. +-- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location and the offset, if any. function ZONE_UNIT:GetVec2() self:F2( self.ZoneName ) local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then + env.info(self.dx .. " " .. self.dy) + + -- update the zone position with the offsets. + ZoneVec2.x = ZoneVec2.x + self.dx + ZoneVec2.y = ZoneVec2.y + self.dy + self.LastVec2 = ZoneVec2 return ZoneVec2 else From ec0b32321a95c757900d76fe35b119b2d9c6ab2f Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Fri, 15 Jun 2018 19:58:26 +0200 Subject: [PATCH 2/3] Added Rho/Theta offset handling to ZoneUnit --- Moose Development/Moose/Core/Zone.lua | 34 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index fd65dcf2d..b1893213f 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -976,12 +976,24 @@ ZONE_UNIT = { -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. -- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. -- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. +-- @param Dcs.DCSTypes#Distance rho The distance of the zone from the unit +-- @param Dcs.DCSTypes#Angle theta The azimuth of the zone relative to unit +-- @param Dcs.DCSTypes#Boolean relative_to_unit if true, theta is measured clockwise from unit's direction else clockwise from north. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy ) +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy, rho, theta, relative_to_unit) self.dy = dy or 0.0 self.dx = dx or 0.0 + self.rho = rho or 0.0 + self.theta = theta * math.pi / 180.0 or 0.0 + self.relative_to_unit = relative_to_unit or false + -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. + + if (dx or dy) and (rho or theta) then + error("Cannot use arguments (dx, dy) with (rho, theta)") + end + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) @@ -1001,11 +1013,23 @@ function ZONE_UNIT:GetVec2() local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then - env.info(self.dx .. " " .. self.dy) - -- update the zone position with the offsets. - ZoneVec2.x = ZoneVec2.x + self.dx - ZoneVec2.y = ZoneVec2.y + self.dy + if (self.dx or self.dy) then + ZoneVec2.x = ZoneVec2.x + self.dx + ZoneVec2.y = ZoneVec2.y + self.dy + end + + if (self.rho or self.theta) then + -- check if theta is relative to unit or relative to north + if self.relative_to_unit then + heading = self.ZoneUNIT:GetHeading() * math.pi / 180.0 or 0.0 + else + heading = 0.0 + end + + ZoneVec2.x = ZoneVec2.x + self.rho * math.cos( self.theta + heading ) + ZoneVec2.y = ZoneVec2.y + self.rho * math.sin( self.theta + heading ) + end self.LastVec2 = ZoneVec2 return ZoneVec2 From 58e5ffa2834e204db5c1442d4ac0e6b58b17000b Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Sat, 16 Jun 2018 15:33:59 +0200 Subject: [PATCH 3/3] Changed offsets argument to use a table for clarity. --- Moose Development/Moose/Core/Zone.lua | 63 +++++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index b1893213f..27741c2a3 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -974,26 +974,27 @@ ZONE_UNIT = { -- @param #string ZoneName Name of the zone. -- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone. -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. --- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. --- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. --- @param Dcs.DCSTypes#Distance rho The distance of the zone from the unit --- @param Dcs.DCSTypes#Angle theta The azimuth of the zone relative to unit --- @param Dcs.DCSTypes#Boolean relative_to_unit if true, theta is measured clockwise from unit's direction else clockwise from north. +-- @param #table Offset A table specifying the offset. The offset table may have the following elements: +-- dx The offset in X direction, +x is north. +-- dy The offset in Y direction, +y is east. +-- rho The distance of the zone from the unit +-- theta The azimuth of the zone relative to unit +-- relative_to_unit If true, theta is measured clockwise from unit's direction else clockwise from north. If using dx, dy setting this to true makes +x parallel to unit heading. +-- dx, dy OR rho, theta may be used, not both. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy, rho, theta, relative_to_unit) - - self.dy = dy or 0.0 - self.dx = dx or 0.0 - self.rho = rho or 0.0 - self.theta = theta * math.pi / 180.0 or 0.0 - self.relative_to_unit = relative_to_unit or false +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset) - -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. - - if (dx or dy) and (rho or theta) then - error("Cannot use arguments (dx, dy) with (rho, theta)") + -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. + if (Offset.dx or Offset.dy) and (Offset.rho or Offset.theta) then + error("Cannot use (dx, dy) with (rho, theta)") end - + + self.dy = Offset.dy or 0.0 + self.dx = Offset.dx or 0.0 + self.rho = Offset.rho or 0.0 + self.theta = (Offset.theta or 0.0) * math.pi / 180.0 + self.relative_to_unit = Offset.relative_to_unit or false + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) @@ -1013,20 +1014,24 @@ function ZONE_UNIT:GetVec2() local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then - -- update the zone position with the offsets. - if (self.dx or self.dy) then - ZoneVec2.x = ZoneVec2.x + self.dx - ZoneVec2.y = ZoneVec2.y + self.dy - end - - if (self.rho or self.theta) then - -- check if theta is relative to unit or relative to north - if self.relative_to_unit then - heading = self.ZoneUNIT:GetHeading() * math.pi / 180.0 or 0.0 + + if self.relative_to_unit then + heading = ( self.ZoneUNIT:GetHeading() or 0.0 ) * math.pi / 180.0 else heading = 0.0 - end - + end + + -- update the zone position with the offsets. + if (self.dx or self.dy) then + + -- use heading to rotate offset relative to unit using rotation matrix in 2D. + -- see: https://en.wikipedia.org/wiki/Rotation_matrix + ZoneVec2.x = ZoneVec2.x + self.dx * math.cos( -heading ) + self.dy * math.sin( -heading ) + ZoneVec2.y = ZoneVec2.y - self.dx * math.sin( -heading ) + self.dy * math.cos( -heading ) + end + + -- if using the polar coordinates + if (self.rho or self.theta) then ZoneVec2.x = ZoneVec2.x + self.rho * math.cos( self.theta + heading ) ZoneVec2.y = ZoneVec2.y + self.rho * math.sin( self.theta + heading ) end