Circle movement using vectors?

DonRoman

New Member
Reaction score
5
Hey, lately I've been trying to do some kind of projectile system for practice, however I always fail when it comes to doing a circle movement around a certain point in 3d.

Here what that means: I got a projectile thats moving into a specific area, now it should continue on a circular path. For all the movements I used vectors and I dont really want any trigonometric functions. I tried using the centripetal force towards the center but somehow i couldnt get it to work. :/

mv^2/r = m * a ; m = mass ; v = velocity = length of velocity vector; r = radius = length of vector between current location and center ; a = acceleration

I tried to calculate a as acceleration towards the center and add it to v but i failed :(

maybe someone of you got an idea ??
 

Trollvottel

never aging title
Reaction score
262
well i did some likely thing and have got no problems, would you show the part of the code pls?
 

DonRoman

New Member
Reaction score
5
Alright here it is, it probably just is some stupid mistake by me ...

also the code is not yet fully optimized :/

JASS:
library PS initializer Init uses PUI
//########################################################################

globals
    private constant real PERIODE = 0.03125
    private constant real MAX_SPEED = 1000 * PERIODE
    
    private real MAX_X
    private real MAX_Y
    private real MIN_X
    private real MIN_Y
    private timer TIMER = CreateTimer()
    private location TempLoc = Location(0,0)
    private vector GRAVITY
    private forcefield Field
endglobals
//=======================================================================
// Useful functions
//=======================================================================

private function GetTerrainZ takes real x, real y returns real
    call MoveLocation(TempLoc, x, y)
    return GetLocationZ(TempLoc)
endfunction

private function SafeX takes real x returns real
    if x > MAX_X then
        return MAX_X
    elseif x < MIN_X then
        return MIN_X
    endif
    return x
endfunction

private function SafeY takes real x returns real
    if x > MAX_Y then 
        return MAX_Y
    elseif x < MIN_Y then
        return MIN_Y
    endif
    return x
endfunction
//=======================================================================
// vector struct
//=======================================================================

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
    
    method declare takes real x, real y, real z returns nothing
        set .x = x
        set .y = y
        set .z = z
    endmethod
    
    method add takes vector v returns nothing
        set .x = .x + v.x
        set .y = .y + v.y
        set .z = .z + v.z
    endmethod
    
    method subtract takes vector v returns nothing
        set .x = .x - v.x
        set .y = .y - v.y
        set .z = .z - v.z
    endmethod
    
    method scale takes real x returns nothing
        set .x = .x * x
        set .y = .y * x
        set .z = .z * x
    endmethod
    
    method getLength takes nothing returns real
        return SquareRoot(.x * .x + .y * .y + .z * .z) 
    endmethod

    method getLengthSquare takes nothing returns real
        return .x * .x + .y * .y + .z * .z
    endmethod
    
    static method VectorBetweenPoints takes vector origin, vector point returns vector
        local vector v = vector.create(point.x - origin.x, point.y - origin.y, point.z - origin.z)
        return v
    endmethod
    
    method SetVectorBetweenPoints takes vector origin, vector point returns nothing
        set .x = point.x - origin.x
        set .y = point.y - origin.y
        set .z = point.z - origin.z
    endmethod
    
    static method GetPointDistanceSquare takes vector origin, vector point returns real
        local vector v = vector.create(point.x - origin.x, point.y - origin.y, point.z - origin.z)
        local real r   = v.x * v.x + v.y * v.y + v.z * v.z
        call v.destroy()
        return r
    endmethod
endstruct
//==========================================================================
// Begin of Projectile things
//==========================================================================

struct projectile
    unit u
    
    real mass
    
    vector position
    vector velocity
    vector acceleration
    vector forcefactor
    
    static group members = CreateGroup()
    static vector Helper
    
    //! runtextmacro PUI()
    
    static method create takes player q, integer id, real x, real y, real z, real speed, real angle, real zangle returns projectile
        local projectile p = projectile.allocate()
        set p.u = CreateUnit(q, id, x, y, angle)
        
        call UnitAddAbility(p.u, 'Amrf')
        call SetUnitFlyHeight(p.u, z - GetTerrainZ(x,y), 0)
        call UnitRemoveAbility(p.u, 'Amrf')
        
        set p.position     = vector.create(x,y,z)
        set p.velocity     = vector.create(Cos(angle * bj_DEGTORAD) * speed, Sin(angle * bj_DEGTORAD) * speed, Sin(angle * bj_DEGTORAD) * speed)
        set p.acceleration = vector.create(0,0,0)
        set p.forcefactor  = vector.create(0,0,0)
        //call p.acceleration.add(GRAVITY)
        call p.velocity.scale(PERIODE)
        call p.acceleration.scale(PERIODE)
        
        set projectile[p.u]  = p
        call GroupAddUnit(p.members, p.u)
        
        return p
    endmethod
    
    method execute takes nothing returns nothing
        local integer i = 1
        local vector helper
        local newField field
        
        set i = newField.count
        //call BJDebugMsg(I2S(newField.count))
        loop
            exitwhen i == 0
            set field = newField.Data<i>
            set helper = vector.VectorBetweenPoints(.position, field.position)
            if helper.getLengthSquare() &lt;= field.radius then
                call helper.scale(.velocity.getLengthSquare() / helper.getLengthSquare() * PERIODE)
                call BJDebugMsg(&quot;Velocity Before: &quot; + R2S(helper.getLength()))
            endif
            set i = i - 1
        endloop
        
        call BJDebugMsg(&quot;Velocity Before: &quot; + R2S(.velocity.getLength()))
        call .velocity.add(.acceleration)
        call BJDebugMsg(&quot;Velocity After: &quot; + R2S(.velocity.getLength()))
        call .position.add(.velocity)
        call .position.add(helper) // tried different things here
        
        set .position.x = SafeX(.position.x)
        set .position.y = SafeY(.position.y)
        
        call SetUnitX(.u, .position.x)
        call SetUnitY(.u, .position.y)
        call SetUnitFlyHeight(.u, .position.z - GetTerrainZ(.position.x, .position.y), 0)
        
        if .velocity.getLengthSquare() &gt; MAX_SPEED * MAX_SPEED then
            call .velocity.scale(MAX_SPEED / .velocity.getLength())
        endif
        
        call helper.destroy()
    endmethod
    
endstruct

//===========================================================================
// new forcefield
//===========================================================================
struct newField
    vector position
    real radius
    
    static newField array Data
    static integer count = 0
    
    static method create takes real x, real y, real z, real radius returns newField
        set .count = .count + 1
        set .Data[.count] = newField.allocate()
        set .Data[.count].position = vector.create(x,y,z)
        set .Data[.count].radius = radius
        return .Data[.count]
    endmethod
endstruct

//===========================================================================
private function GroupLoop takes nothing returns nothing
    local projectile p = projectile[GetEnumUnit()]
    call p.execute()
endfunction

private function Loop takes nothing returns nothing
    call ForGroup(projectile.members, function GroupLoop)
endfunction

private function Init takes nothing returns nothing
    call TimerStart(TIMER, PERIODE, true, function Loop)
    
    set MIN_X = GetRectMinX(bj_mapInitialPlayableArea)
    set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)
    set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
    set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
    
    set GRAVITY = vector.create(0,0, -10)
    set projectile.Helper = vector.create(0,0,0)
    call newField.create(1000,1000, 1000, 10000)
endfunction
//########################################################################
endlibrary</i>
 

Viikuna

No Marlo no game.
Reaction score
265
My math skills usually fail me, but isnt it: a = (v*v) / r ?
 

darkbeer

Beer is Good!
Reaction score
84
ye and thats what i think he did here:

JASS:
call helper.scale(.velocity.getLengthSquare() / helper.getLengthSquare() * PERIODE)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top