Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Scripts (http://www.wc3c.net/forumdisplay.php?f=737)
-   -   Vector (http://www.wc3c.net/showthread.php?t=87027)

cohadar 03-05-2008 08:58 AM

Quote:

Originally Posted by Toadcop
thats true ~30 wisp are almost the max.
but anyway awesome stuff need awesome presentation ^^ (thats why grim001 demo was so impressive)


offtopic:
And that is why grim001 never finishes anything....

Toadcop 03-05-2008 05:29 PM

cohadar yes it's true. and also he banned me in AIM xDDDD he's a bad ass xD

ClichesAreSt00pid 06-07-2008 10:38 PM

Great system, forced me to learn vjass too.

Anyways I'm having trouble with one thing that I just can't figure out. I want it to be like a "thrown" bouncy ball from a spell, and the velocity is calculated in XYZ, so how would I make the velocity take the ball towards the target?

I'm also trying to make it so any kind of collision will make it bounce, like trees and stuff, but it's tough and will take time. I'm using items (like vexorian did I think) to check it if you are wondering, just the actual Z height of different models is what makes it difficult.


Edit: Okay figured it out. I just did...well this in the creation part (and many other things, like making the trigger into a spell):

Collapse JASS:
    static method create takes nothing returns bouncyBall
        local bouncyBall b = bouncyBall.allocate()
        local location l = GetSpellTargetLoc()
        local location l2 = GetUnitLoc(GetTriggerUnit())
        local location l3 = PolarProjectionBJ(l2, 600, AngleBetweenPoints(l2, l))
        set b.position = vector.create(GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),75.0) //this is the thrower
      //  give the ball a starting velocity
        set b.velocity = vector.create((GetLocationX(l3) - GetLocationX(l2))*MOVE_PERIOD,(GetLocationY(l3) - GetLocationY(l2))*MOVE_PERIOD,600.0*MOVE_PERIOD)
        set b.ball = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'ewsp', 0.0,0.0,0.0)
      //  make it possible to change the unit's flyheight
        call UnitAddAbility(b.ball, 'Amrf')
        call UnitRemoveAbility(b.ball, 'Amrf')
        set balls[ballNum]=b
        set b.spot=ballNum
        set balls[ballNum].duration = 0
        set ballNum=ballNum+1

        call RemoveLocation(l)
        set l = null
        call RemoveLocation(l2)
        set l2 = null
        call RemoveLocation(l3)
        set l3 = null
        return b
    endmethod

Seshiro 08-25-2008 10:41 PM

New Functions for Units
 
Hey,
I've had to add some new methods to your atruct, because i neede them! :D
They all improve working with units and vectors! they are easey to use, and i think, that they're useful!
Collapse JASS:
library VectorLib
    // Credits:
    //  ;- to Waterknight for UnitZ funcs

    function GetFloorHeight takes real x, real y returns real
        local location whichUnitLocation = Location( x, y )
        local real z = GetLocationZ( whichUnitLocation )
        call RemoveLocation( whichUnitLocation )
        set whichUnitLocation = null
        return z
    endfunction

    function GetUnitZ takes unit whichUnit returns real
        local real z = ( GetFloorHeight( GetUnitX( whichUnit ), GetUnitY( whichUnit ) ) + GetUnitFlyHeight( whichUnit ) )
        set whichUnit = null
        return z
    endfunction



    function SetUnitZ takes unit whichUnit, real z returns nothing
        local boolean whichUnitHasNotAmrf = ( GetUnitAbilityLevel( whichUnit, 'Amrf' ) <= 0 )
        if ( whichUnitHasNotAmrf ) then
            call UnitAddAbility( whichUnit, 'Amrf' )
        endif
        call SetUnitFlyHeight( whichUnit, z - GetFloorHeight( GetUnitX( whichUnit ), GetUnitY( whichUnit ) ), 0.00 )
        if ( whichUnitHasNotAmrf ) then
            call UnitRemoveAbility( whichUnit, 'Amrf' )
        endif    
        set whichUnit = null
    endfunction

    globals
        private location loc = Location(0.0,0.0)
    endglobals

    struct vector
        real x
        real y
        real z
        
        static method create takes real x, real y, real z returns vector
            local vector v = vector.allocate()
            set v.x=x
            set v.y=y
            set v.z=z
            return v
        endmethod
        
        static method setUnitVector takes unit c, vector v returns nothing
            call SetUnitX(c,v.x)
            call SetUnitY(c,v.y)
            call SetUnitZ(c,v.z)
            set c = null
        endmethod
        
        method updateUnitVector takes unit u returns nothing
            set this.x = GetUnitX(u)
            set this.y = GetUnitY(u)
            set this.z = GetUnitZ(u)
            set u = null
        endmethod
        
        static method getUnitVector takes unit u returns vector
            local vector v = vector.allocate()
            set v.x = GetUnitX(u)
            set v.y = GetUnitY(u)
            set v.z = GetUnitZ(u)
            set u = null
            return v
        endmethod
        
        method getLength takes nothing returns real
          return SquareRoot(.x*.x + .y*.y + .z*.z)
        endmethod
        
        static method sum takes vector augend, vector addend returns vector
            local vector v = vector.allocate()
            set v.x = augend.x+addend.x
            set v.y = augend.y+addend.y
            set v.z = augend.z+addend.z
            return v
        endmethod
        method add takes vector addend returns nothing
            set this.x=this.x+addend.x
            set this.y=this.y+addend.y
            set this.z=this.z+addend.z
        endmethod
        
        static method difference takes vector minuend, vector subtrahend returns vector
            local vector v = vector.allocate()
            set v.x = minuend.x-subtrahend.x
            set v.y = minuend.y-subtrahend.y
            set v.z = minuend.z-subtrahend.z
            return v
        endmethod
        method subtract takes vector subtrahend returns nothing
            set this.x=this.x-subtrahend.x
            set this.y=this.y-subtrahend.y
            set this.z=this.z-subtrahend.z
        endmethod
        
        method scale takes real factor returns nothing
            set this.x=this.x*factor
            set this.y=this.y*factor
            set this.z=this.z*factor
        endmethod
        
        method setLength takes real length returns nothing
            local real l = SquareRoot(.x*.x + .y*.y + .z*.z)
            if l == 0.0 then
                debug call BJDebugMsg("Attempted to set the length of a vector with no length!")
                return
            endif
            set l = length/l
            set this.x = this.x*l
            set this.y = this.y*l
            set this.z = this.z*l
        endmethod
        
        static method dotProduct takes vector a, vector b returns real
            return (a.x*b.x+a.y*b.y+a.z*b.z)
        endmethod
        
        static method crossProduct takes vector a, vector b returns vector
            local vector v = vector.allocate()
            set v.x = a.y*b.z - a.z*b.y
            set v.y = a.z*b.x - a.x*b.z
            set v.z = a.x*b.y - a.y*b.x
            return v
        endmethod
        
        static method projectionVector takes vector projected, vector direction returns vector
            local vector v = vector.allocate()
            local real l = direction.x*direction.x+direction.y*direction.y+direction.z*direction.z
            if l == 0.0 then
                call v.destroy()
                debug call BJDebugMsg("Attempted to project onto a vector with no length!")
                return null
            endif
            set l = (projected.x*direction.x+projected.y*direction.y+projected.z*direction.z) / l
            set v.x = direction.x*l
            set v.y = direction.y*l
            set v.z = direction.z*l
            return v
        endmethod
        method projectVector takes vector direction returns nothing
            local real l = direction.x*direction.x+direction.y*direction.y+direction.z*direction.z
            if l == 0.0 then
                debug call BJDebugMsg("Attempted to project onto a vector with no length!")
                return
            endif
            set l = (this.x*direction.x+this.y*direction.y+this.z*direction.z) / l
            set this.x = direction.x*l
            set this.y = direction.y*l
            set this.z = direction.z*l
        endmethod

        static method projectionPlane takes vector projected, vector normal returns vector
            local vector v = vector.allocate()
            local real l = normal.x*normal.x+normal.y*normal.y+normal.z*normal.z
            if l == 0.0 then
                call v.destroy()
                debug call BJDebugMsg("Attempted to project onto an undefined plane!")
                return null
            endif
            set l = (projected.x*normal.x+projected.y*normal.y+projected.z*normal.z) / l
            set v.x = projected.x - normal.x*l
            set v.y = projected.y - normal.y*l
            set v.z = projected.z - normal.z*l
            return v
        endmethod
        method projectPlane takes vector normal returns nothing
            local real l = normal.x*normal.x+normal.y*normal.y+normal.z*normal.z
            if l == 0.0 then
                debug call BJDebugMsg("Attempted to project onto an undefined plane!")
                return
            endif
            set l = (this.x*normal.x+this.y*normal.y+this.z*normal.z) / l
            set this.x = this.x - normal.x*l
            set this.y = this.y - normal.y*l
            set this.z = this.z - normal.z*l
        endmethod

        static method getAngle takes vector a, vector b returns real
            local real l = SquareRoot(a.x*a.x + a.y*a.y + a.z*a.z)*SquareRoot(b.x*b.x + b.y*b.y + b.z*b.z)
            if l == 0 then
                debug call BJDebugMsg("Attempted to get angle between vectors with no length!")
                return 0.0
            endif
            return Acos((a.x*b.x+a.y*b.y+a.z*b.z)/l) //angle is returned in radians
        endmethod
        
        method rotate takes vector axis, real angle returns nothing //angle is taken in radians
            local real xx
            local real xy
            local real xz
            local real yx
            local real yy
            local real yz
            local real zx
            local real zy
            local real zz
            local real al = axis.x*axis.x+axis.y*axis.y+axis.z*axis.z //axis length^2
            local real f
            local real c = Cos(angle)
            local real s = Sin(angle)
            if al == 0.0 then
                debug call BJDebugMsg("Attempted to project onto a vector with no length!")
                return
            endif
            set f = (this.x*axis.x+this.y*axis.y+this.z*axis.z) / al
            set zx = axis.x*f
            set zy = axis.y*f
            set zz = axis.z*f //axis component of rotated vector
            set xx = this.x-zx
            set xy = this.y-zy
            set xz = this.z-zz //component of vector perpendicular to axis
            set al = SquareRoot(al)
            set yx = (axis.y*xz - axis.z*xy)/al
            set yy = (axis.z*xx - axis.x*xz)/al //y same length as x by using cross product and dividing with axis length
            set yz = (axis.x*xy - axis.y*xx)/al //x,y - coordinate system in which we rotate
            set this.x=xx*c+yx*s+zx
            set this.y=xy*c+yy*s+zy
            set this.z=xz*c+yz*s+zz
        endmethod
        
        static method createTerrainPoint takes real x, real y returns vector
            local vector v = vector.allocate()
            call MoveLocation(loc,x,y)
            set v.x=x
            set v.y=y
            set v.z=GetLocationZ(loc)
            return v
        endmethod
        method getTerrainPoint takes real x, real y returns nothing
            call MoveLocation(loc,x,y)
            set this.x=x
            set this.y=y
            set this.z=GetLocationZ(loc)
        endmethod

        static method createTerrainNormal takes real x, real y, real sampleRadius returns vector
            local vector v = vector.allocate()
            local real z1
            local real z2
            local real z3
            local real z4
            call MoveLocation(loc, x-sampleRadius, y)
            set z1=GetLocationZ(loc)
            call MoveLocation(loc, x+sampleRadius, y)
            set z2=GetLocationZ(loc)
            call MoveLocation(loc, x, y-sampleRadius)
            set z3=GetLocationZ(loc)
            call MoveLocation(loc, x, y+sampleRadius)
            set z4=GetLocationZ(loc)
            set sampleRadius=2*sampleRadius
            set v.x = (z1-z2)*sampleRadius
            set v.y = (z3-z4)*sampleRadius
            set v.z = sampleRadius*sampleRadius
            return v
        endmethod
        method getTerrainNormal takes real x, real y, real sampleRadius returns nothing
            local real z1
            local real z2
            local real z3
            local real z4
            call MoveLocation(loc, x-sampleRadius, y)
            set z1=GetLocationZ(loc)
            call MoveLocation(loc, x+sampleRadius, y)
            set z2=GetLocationZ(loc)
            call MoveLocation(loc, x, y-sampleRadius)
            set z3=GetLocationZ(loc)
            call MoveLocation(loc, x, y+sampleRadius)
            set z4=GetLocationZ(loc)
            set sampleRadius=2*sampleRadius
            set this.x = (z1-z2)*sampleRadius
            set this.y = (z3-z4)*sampleRadius
            set this.z = sampleRadius*sampleRadius
        endmethod

        method isInCylinder takes vector cylinderOrigin, vector cylinderHeight, real cylinderRadius returns boolean
            local real l

            local real x = this.x-cylinderOrigin.x
            local real y = this.y-cylinderOrigin.y
            local real z = this.z-cylinderOrigin.z
            if x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z < 0.0 then //point below cylinder
                return false
            endif
            
            set x = x-cylinderHeight.x
            set y = y-cylinderHeight.y
            set z = z-cylinderHeight.z
            if x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z > 0.0 then //point above cylinder
                return false
            endif
            
            set l = cylinderHeight.x*cylinderHeight.x+cylinderHeight.y*cylinderHeight.y+cylinderHeight.z*cylinderHeight.z
            if l == 0.0 then
                debug call BJDebugMsg("Cylinder with no height!")
                return false
            endif
            set l = (x*cylinderHeight.x+y*cylinderHeight.y+z*cylinderHeight.z) / l
            set x = x - cylinderHeight.x*l
            set y = y - cylinderHeight.y*l
            set z = z - cylinderHeight.z*l
            if x*x+y*y+z*z > cylinderRadius*cylinderRadius then //point outside cylinder
                return false
            endif
            
            return true
        endmethod

        method isInCone takes vector coneOrigin, vector coneHeight, real coneRadius returns boolean
            local real l

            local real x = this.x-coneOrigin.x
            local real y = this.y-coneOrigin.y
            local real z = this.z-coneOrigin.z
            if x*coneHeight.x+y*coneHeight.y+z*coneHeight.z < 0.0 then //point below cone
                return false
            endif
            
            set l = coneHeight.x*coneHeight.x+coneHeight.y*coneHeight.y+coneHeight.z*coneHeight.z
            if l == 0.0 then
                debug call BJDebugMsg("cone with no height!")
                return false
            endif
            set l = (x*coneHeight.x+y*coneHeight.y+z*coneHeight.z) / l
            set x = x - coneHeight.x*l
            set y = y - coneHeight.y*l
            set z = z - coneHeight.z*l
            if SquareRoot(x*x+y*y+z*z) > coneRadius*(1.0-l) then //point outside cone
                return false
            endif
            
            return true
        endmethod

        method isInSphere takes vector sphereOrigin, real sphereRadius returns boolean
            if sphereRadius*sphereRadius < ((this.x-sphereOrigin.x)*(this.x-sphereOrigin.x)+(this.y-sphereOrigin.y)*(this.y-sphereOrigin.y)+(this.z-sphereOrigin.z)*(this.z-sphereOrigin.z)) then
                return false
            endif
            return true
        endmethod
    endstruct

endlibrary

the new functions are:
  • updateUnitVector: sets the current vector to the one of the unit
  • setUnitVector: sets the vectors of the unit to the vector
  • getUnitVector: the same as update but creates a new vector

and a very very big thanks to Antiarf for such work!

I don't know, wether I'm allowed to do this, if u dislike this, u may tell me and i delete at the moment :) !

Greez

Anitarf 08-26-2008 12:30 AM

Those extra methods you have there don't really fit in my opinion since doing stuff with actual units is outside the scope of this system, that's something you should build on top of the system not in it, also your GetFloorHeight function is obsolete, you also do some odd things in other functions as well, it's all rather unoptimised for a low-level system and we don't want to encourage people to code like that.

So I'm not adding those functions and methods to my first post, but thanks for the suggestions anyway.

akolyt0r 03-24-2009 12:09 PM

<nitpicking
Collapse JASS:
        static constant method dotProduct takes vector a, vector b returns real
            return (a.x*b.x+a.y*b.y+a.z*b.z)
        endmethod

peq 11-24-2009 09:23 PM

I have a request for an operation which I use quite often:
Collapse JASS:
        method addScaled takes vector addend, real scale returns nothing
            set this.x=this.x+addend.x*scale
            set this.y=this.y+addend.y*scale
            set this.z=this.z+addend.z*scale
        endmethod

Its nice to have a function like this if you use vectors for movement as you always need nomething like this:

Collapse JASS:
call position.addScaled(velocity, TimedLoop_PERIOD)

It would be nice if you could add this ;)

Anachron 04-12-2010 09:09 AM

Why don't you have GetXyDistance and GetXyzDistance in the vector library? I think that is important.

Can you please add it or tell me how I can do it?

0zyx0 04-12-2010 11:20 AM

GetXyzDistance could be done by subtracting one of the vectors from the other, and getting the length of the resulting vector. GetXyDistance would be done the same way, but you would have to make sure the two vectors have the same z-component first.

Anachron 04-12-2010 11:28 AM

I still don't get it.
Can you post code that returns the distance as a real?

Anitarf 04-12-2010 12:51 PM

Collapse JASS:
function Distance takes vector a, vector b, boolean z returns real
    local vector d = vector.difference(b,a)
    local real r
    if not z then
        set d.z = 0.0
    endif
    set r = d.getLength()
    call d.destroy()
    return r
endfunction

Or a more efficient version:

Collapse JASS:
function Distance takes vector a, vector b, boolean z returns real
    if z then
        return SquareRoot(Pow(b.x-a.x,2)+Pow(b.y-a.y,2)+Pow(b.z-a.z,2))
    else
        return SquareRoot(Pow(b.x-a.x,2)+Pow(b.y-a.y,2))
    endif
endfunction

Anachron 04-12-2010 01:52 PM

Thanks, can you please add that into the library?

BBQ 07-10-2011 07:38 PM

May I suggest that you include normalizing? Unit vectors can be quite useful.
Collapse Zinc:
method normalize() {
    real length = this.getLength();
    this.x /= length;
    this.y /= length;
    this.z /= length;
}

Anitarf 07-12-2011 09:32 AM

Quote:

Originally Posted by BBQ
May I suggest that you include normalizing? Unit vectors can be quite useful.

Well, there's the .setLength() method which does just this if you give it 1.0 as the argument.

Bribe 07-12-2011 12:19 PM

Is there a way to rotate a vector considering the Z value
with the rotation?

I suspect not in this library, based on that it's only rotating
the X and Y. I wonder what kind of complexity we'd deal
with if we had to factor in all three dimensions into the
equations.

I'm also unsure of what the purpose of "terrainNormal" is.
It takes four corners into consideration but what if the center
is a bit indented/raised offset from the rest?


All times are GMT. The time now is 10:48 AM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services