• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Help with function for Steiner Circumellipse

Status
Not open for further replies.
Level 31
Joined
Jul 10, 2007
Messages
6,306
Given a triangle ABC (ax, ay, bx, by, cx, cy) that may be rotated any which way about the origin and a point P (px, py), determine

whether or not P is in the Steiner Circum Ellipse for triangle ABC limited to Trigonometry and using as little steps as possible.

Retrieve the coordinates for both foci and the major/minor axes extrema relative to centroid g of triangle abc and graph the

ellipse using the standard equation for an ellipse.

Where
Q = a^2+b^2+c^2-ab-ac-bc
Sw = (a^2+b^2+c^2)/2

a (major axis) = 2/9*SquareRoot(Q+Sw)
b (minor axis) = 2/9*SquareRoot(Q-Sw)
c (foci) = 2/3*SquareRoot(Q)

(x-h)^2/a^2+(y-k)^2/b^2 = 1

I got the lengths below... the length of foci, all of it.

I converted everything into vectors, lol....

So now I'm wondering how to get the coordinates back : p..

The reason I had to convert everything into vectors was because of a case where a right triangle would cause everything to cancel out along minor axis. The vectors seem to actually have the right values...

Now, I don't necessarily needs the coords back.. i just need a way to check to see if a point is inside of the thing >.<

I can't even figure out how to get the angle of rotation...

Thinking of this
Code:
Sw = (a^2+b^2+c^2)/2

2*sw = a^2+b^2+c^2

sw^2 = swx^2+swy^2

swx^2 = ax^2+bx^2+cx^2
swy^2 = ay^2+by^2+cy^2
swy^2+swx^2==sw^2

JASS:
library IsPointInSteinerCircumellipse
    //is point p in steiner circumellipse for triangle abc
    
    /*
        Q = a^2+b^2+c^2-b*c-c*a-a*b

        Sw = S*cot(W) = (a^2+b^2+c^2)/2

        Q^2=Sw^2-3*S^2

        y (foci dist) = (2/3)*sqrt(Q)
        b = sqrt((2/9)(Sw-Q))
        a = sqrt((2/9)(Sw+Q))
    */
    
    /*
        A point P is in an Ellipse if |P-F1|+|P-F2|<=2*a
        
        Where F1 and F2 are the foci
    */
    function IsPointInSteinerCircumEllipse takes real ax, real ay, real bx, real by, real cx, real cy, real px, real py returns boolean
        //centroid
        local real gx = (ax+bx+cx)/3
        local real gy = (ay+by+cy)/3
        
        //lengths of each side in terms of x,y
        local real adx = ax-bx
        local real bdx = bx-cx
        local real cdx = cx-ax
        local real ady = ay-by
        local real bdy = by-cy
        local real cdy = cy-ay
        
        local real ad = SquareRoot(adx*adx+ady*ady)
        local real bd = SquareRoot(bdx*bdx+bdy*bdy)
        local real cd = SquareRoot(cdx*cdx+cdy*cdy)
        
        //steiner axes (minor and major axis of steiner circumellipse)
        local real sb
        local real sa
        
        //Sw and Q
        local real Sw
        local real Q
        
        //foci distance from centroid
        local real y
        local real a
        
        //lengths squared since most equations take them that way
        local real ad2 = ad*ad
        local real bd2 = bd*bd
        local real cd2 = cd*cd
        
        set Q = ad2-bd*cd+bd2-cd*ad+cd2-ad*bd
        set Sw = (ad2/2+bd2/2+cd2/2)
        set y = .666666*SquareRoot(Q)
        set sb = SquareRoot(.222222*(Sw-Q))
        set sa = SquareRoot(.222222*(Sw+Q))
        set a = 2*sa
        
        /*set Qx = adx2-bdx*cdx+bdx2-cdx*adx+cdx2-adx*bdx
        set Qy = ady2-bdy*cdy+bdy2-cdy*ady+cdy2-ady*bdy
        
        set Swx = (adx2/2+bdx2/2+cdx2/2)
        set Swy = (ady2/2+bdy2/2+cdy2/2)
        
        set yx = .666666*SquareRoot(Qx)
        set yy = .666666*SquareRoot(Qy)
        
        set sbx = SquareRoot(0.222222*(Swx-Qx))
        set sby = SquareRoot(0.222222*(Swy-Qy))
        set sax = SquareRoot(0.222222*(Swx+Qx))
        set say = SquareRoot(0.222222*(Swy+Qy))*/
        
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 90000, R2S(Pow(.666666*SquareRoot(Sw), 2)) + "==" + R2S(sb*sb+sa*sa))
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 90000, R2S(sa*sa*9/2-Sw) + "==" + R2S(Pow(y*3/2, 2)))
        
        //|P-F1|+|P-F2|<=2*a
        return false
        /*
        set pdyx1 = px-(gx-yx)
        set pdyx2 = px-(gx+yx)
        set pdyy1 = py-(gy+yy)
        set pdyy2 = py-(gy-yy)
        */
        /*
        call CreateUnit(Player(0), 'hmil', .666666*SquareRoot(Swx), .666666*SquareRoot(Swy), 0)
        call CreateUnit(Player(0), 'hfoo', gx-sbx, gy-sby, 0)
        call CreateUnit(Player(0), 'hfoo', gx+sbx, gy+sby, 0)
        call CreateUnit(Player(0), 'hfoo', gx-sax, gy+say, 0)
        call CreateUnit(Player(0), 'hfoo', gx+sax, gy-say, 0)
        
        call CreateUnit(Player(0), 'hrif', gx, gy, 0)
        
        call CreateUnit(Player(0), 'hmtm', gx+yx, gy-yy, 0)
        call CreateUnit(Player(0), 'hmtm', gx-yx, gy+yy, 0)
        
        set pd1 = SquareRoot(pdyx1*pdyx1+pdyy1*pdyy1)
        set pd2 = SquareRoot(pdyx2*pdyx2+pdyy2*pdyy2)
        set a = SquareRoot(sax*sax+say*say)
        
        return pd1+pd1 <= 2*a
        */
    endfunction
    
    struct tester extends array
        private static method onInit takes nothing returns nothing
            //values
            local real ax = 200
            local real ay = 200
            local real bx = 200
            local real by = 800
            local real cx = 800
            local real cy = 200
            local real px = 800
            local real py = 200
            //create units to show triangle
            call CreateUnit(Player(0), 'hpea', ax, ay, 0)
            call CreateUnit(Player(0), 'hpea', bx, by, 0)
            call CreateUnit(Player(0), 'hpea', cx, cy, 0)
            call CreateUnit(Player(0), 'hmpr', px, py, 0)
            
            /*
            loop
                exitwhen not IsPointInSteinerCircumellipse(ax, ay, bx, by, cx, cy, px, py)
                call CreateUnit(Player(0), 'hfoo', px, py, 0)
                set py = py + 100
            endloop
            
            call SetUnitScale(CreateUnit(Player(0), 'hfoo', px, py, 0), 2, 2, 2)
            */
            
            //call function
            if IsPointInSteinerCircumEllipse(ax, ay, bx, by, cx, cy, px, py) then
                call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 900000, "in ellipse")
            endif
        endmethod
    endstruct
endlibrary
 
Last edited:
Status
Not open for further replies.
Top