HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Simple Math - Cone

06-17-2009, 07:14 PM#1
Silvenon
Well, I'm trying to make a function that checks if the unit is in a certain cone. Here's how I started, but it doesn't work:

Collapse JASS:
function IsUnitInCone takes unit u1, unit u2, real w returns boolean
    local real x1 = GetUnitX(u1)
    local real y1 = GetUnitY(u1)
    local real x2 = GetUnitX(u2)
    local real y2 = GetUnitY(u2)
    local real a = GetUnitFacing(u1)
    local real a1 = (a + w/2) * bj_DEGTORAD
    local real a2 = (a - w/2) * bj_DEGTORAD
    local real k1 = Sin(a1) / Cos(a1)
    local real k2 = Sin(a2) / Cos(a2)
    local real l1 = y1 - k1 * x1
    local real l2 = y1 - k2 * x1
    
    return y2 < k1 * x2 + l1 and y2 > k2 * x2 + l2
endfunction

This is made specially for my map, so the parameters are a bit weird:
  • u1 - unit from which the cone goes
  • u2 - unit that needs to be checked if it is inside the cone
  • w - width of the code, in degrees

Here's a quick drawing that I made for easier understanding:

Click image for larger version

Name:	ConeZ.jpg
Views:	24
Size:	66.6 KB
ID:	43843

I need the cone to be infinite, so no need for adding distance too.

So I tried making two...what do call them in english? Anyways, y = kx + l, you know what I mean. I displayed both equations with BJDebugMsg and they seem fine. But the last line is the problem, where the value is returned.

I figured out another problem with this function, where the units behind the u1 are also registered, that's because those two straight lines intersect and go behind the unit....well, it's a bit complicated...

Anyone wants to help?
Attached Images
File type: jpgConeZ.jpg (66.6 KB)
06-17-2009, 07:24 PM#2
Themerion
In the intersection point, make a third line which is orthogonal to the bisection line. Then make sure units are at the right side of that line.

Like...

Code:
k3 = (-1) * (a / facing)
06-17-2009, 07:29 PM#3
moyack
sin(a)/cos(a) = tan(a)
06-17-2009, 07:32 PM#4
0zyx0
It is more simple than that. Just set a variable to Atan2(y2-y1, x2-x1), and check if that value is greater than the facing angle of the unit - w/2 and less than face + w/2.

And check if face + w/2 is greater than 360 degrees, or 2PI radians. If it is, subtract 360 or 2PI from the value.
06-17-2009, 07:35 PM#5
Opossum
This should do it:
Collapse JASS:
    function IsUnitInCone takes unit u1, unit u2, real w returns boolean
        // angle between units:
        local real a = bj_RADTODEG*Atan2(GetUnitY(u2)-GetUnitY(u1), GetUnitX(u2)-GetUnitX(u1))
        // facing angle:
        local real b = GetUnitFacing(u1) // not sure if it returns degrees
        
        // delta angle:
        set a = b-a
        
        // norming angle:
        if a < 0 then
            set a = -a
        endif
        if a > 180 then
            set a = 360-a
        endif
        
        return a <= w 
    endfunction
06-18-2009, 09:17 AM#6
Silvenon
Thanks 0zxy0 and Opossum! That's an awesome solution :D

Quote:
local real b = GetUnitFacing(u1) // not sure if it returns degrees

Yeah, it returns degrees.