- Joined
- Apr 24, 2012
- Messages
- 5,111
JASS:
library Triangle /* v1.0
************************************************************************************
*
* Allows you to create triangles.
*
************************************************************************************
*
* */ uses /*
*
* */ Alloc /*
* - hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/
*
************************************************************************************
*
* API
*
* static method create takes real ax, real ay, real bx, real by, real cx, real cy returns thistype
* - create a Triangle
*
* method assign takes thistype t returns nothing
* - assigns the properties of "t" to the triangle.
*
* method copy takes nothing returns thistype
* - copies a triangle by creating a new triangle and assigning it's properties to it.
*
* method scale takes real scale returns nothing
* - scale the Triangle size
*
* method rotate takes real radians returns nothing
* - rotate the Triangle
*
* method moveCentroid takes real x, real y returns nothing
* - move the Triangle by it's centroid
*
* method containsPoint takes real x, real y returns boolean
* - check if the Triangle contains a point.
*
* method getCentroidX takes nothing returns real
* - get the x centroid of the Triangle
*
* method getCentroidY takes nothing returns real
* - get the y centroid of the Triangle
*
* method setVertexX takes integer v, real x returns nothing
* method setVertexY takes integer v, real y returns nothing
* - set the coordinates of a given vertex of a Triangle.
*
* method getVertexX takes integer v returns real
* method getVertexY takes integer v returns real
* - get the coordinate value of a given vertex of the Triangle
*
* method collides takes thistype t returns boolean
* - checks if the Triangle collides with the other Triangle.
*
* method destroy takes nothing returns nothing
* - destroys/removes a Triangle
*
************************************************************************************
*
* Credits
*
* Nestharus - Alloc
* lfh - intersection formula
*
************************************************************************************/
private function GetDistance takes real x1, real x2, real y1, real y2 returns real
return SquareRoot((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
endfunction
struct Triangle extends array
readonly static constant integer A = 0
readonly static constant integer B = 1
readonly static constant integer C = 2
private real t_ax
private real t_ay
private real t_bx
private real t_by
private real t_cx
private real t_cy
private real t_ctx
private real t_cty
private real t_actangle
private real t_bctangle
private real t_cctangle
private real t_actdist
private real t_bctdist
private real t_cctdist
implement Alloc
static method create takes real ax, real ay, real bx, real by, real cx, real cy returns thistype
local thistype this = allocate()
set t_ax = ax
set t_ay = ay
set t_bx = bx
set t_by = by
set t_cx = cx
set t_cy = cy
set t_ctx = (ax + bx + cx)/3
set t_cty = (ay + by + cy)/3
set t_actangle = Atan2(ay - t_cty, ax - t_ctx)
set t_bctangle = Atan2(by - t_cty, bx - t_ctx)
set t_cctangle = Atan2(cy - t_cty, bx - t_ctx)
set t_actdist = GetDistance(ax, t_ctx, ay, t_cty)
set t_bctdist = GetDistance(bx, t_ctx, by, t_cty)
set t_cctdist = GetDistance(cx, t_ctx, cy, t_cty)
return this
endmethod
method assign takes thistype t returns nothing
set t_ax = t.t_ax
set t_ay = t.t_ay
set t_bx = t.t_bx
set t_by = t.t_by
set t_cx = t.t_cx
set t_cy = t.t_cy
set t_ctx = t.t_ctx
set t_cty = t.t_cty
set t_actangle = t.t_actangle
set t_bctangle = t.t_bctangle
set t_cctangle = t.t_cctangle
set t_actdist = t.t_actdist
set t_bctdist = t.t_bctdist
set t_cctdist = t.t_cctdist
endmethod
method copy takes nothing returns thistype
local thistype t = create(0, 0, 0, 0, 0, 0)
call t.assign(this)
return t
endmethod
private method update takes nothing returns nothing
set t_ax = t_ctx + t_actdist * Cos(t_actangle)
set t_ay = t_cty + t_actdist * Sin(t_actangle)
set t_bx = t_ctx + t_bctdist * Cos(t_bctangle)
set t_by = t_cty + t_bctdist * Sin(t_bctangle)
set t_cx = t_ctx + t_cctdist * Cos(t_cctangle)
set t_cy = t_cty + t_cctdist * Sin(t_cctangle)
endmethod
method scale takes real scale returns nothing
set t_actdist = t_actdist * scale
set t_bctdist = t_bctdist * scale
set t_cctdist = t_cctdist * scale
call update()
endmethod
method rotate takes real radians returns nothing
set t_actangle = t_actangle + radians
set t_bctangle = t_bctangle + radians
set t_cctangle = t_cctangle + radians
call update()
endmethod
method moveCentroid takes real x, real y returns nothing
set t_ctx = x
set t_cty = y
call update()
endmethod
method containsPoint takes real x, real y returns boolean
local real cross0 = (y - t_ay)*(t_bx - t_ax) - (x - t_ax)*(t_by - t_ay)
local real cross1 = (y - t_cy)*(t_ax - t_cx) - (x - t_cx)*(t_ay - t_cy)
return cross0*cross1 >= 0 and ((y - t_by)*(t_cx - t_bx) - (x - t_bx) * (t_cy - t_by)) * cross1 >= 0
endmethod
method getCentroidX takes nothing returns real
return t_ctx
endmethod
method getCentroidY takes nothing returns real
return t_cty
endmethod
private method updateCent takes nothing returns nothing
set t_ctx = (t_ax + t_bx + t_cx)/3
set t_cty = (t_ay + t_by + t_cy)/3
endmethod
method setVertexX takes integer v, real x returns nothing
if v == A then
set t_ax = x
call updateCent()
set t_actangle = Atan2(t_ay - t_cty, t_ax - t_ctx)
set t_actdist = GetDistance(t_ax, t_ay, t_ctx, t_cty)
elseif v == B then
set t_bx = x
call updateCent()
set t_bctangle = Atan2(t_by - t_cty, t_bx - t_ctx)
set t_bctdist = GetDistance(t_bx, t_by, t_ctx, t_cty)
elseif v == C then
set t_cx = x
call updateCent()
set t_cctangle = Atan2(t_cy - t_cty, t_cx - t_ctx)
set t_cctdist = GetDistance(t_cx, t_cy, t_ctx, t_cty)
endif
endmethod
method setVertexY takes integer v, real y returns nothing
if v == A then
set t_ay = y
call updateCent()
set t_actangle = Atan2(t_ay - t_cty, t_ax - t_ctx)
set t_actdist = GetDistance(t_ax, t_ay, t_ctx, t_cty)
elseif v == B then
set t_by = y
call updateCent()
set t_bctangle = Atan2(t_by - t_cty, t_bx - t_ctx)
set t_bctdist = GetDistance(t_bx, t_by, t_ctx, t_cty)
elseif v == C then
set t_cy = y
call updateCent()
set t_cctangle = Atan2(t_cy - t_cty, t_cx - t_ctx)
set t_cctdist = GetDistance(t_cx, t_cy, t_ctx, t_cty)
endif
endmethod
method getVertexX takes integer v returns real
if v == A then
return t_ax
elseif v == B then
return t_bx
elseif v == C then
return t_cx
endif
return 0.
endmethod
method getVertexY takes integer v returns real
if v == A then
return t_ay
elseif v == B then
return t_by
elseif v == C then
return t_cy
endif
return 0.
endmethod
private method doesIntersect takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, thistype t returns boolean
local real a1 = (y2 - y1)/(x2 - x1)
local real a2 = (y4 - y3)/(x4 - x3)
local real b1 = y1 - a1*x1
local real b2 = y3 - a2*x3
local real x = (b2 - b1)/(a1 - a2)
local real y_1 = a1*x + b1
local real y_2 = a2*x + b2
if RAbsBJ(y_1 - y_2) > 0.01 then
return false
endif
return (containsPoint(x, y_1) and t.containsPoint(x, y_1))
endmethod
method collides takes thistype t returns boolean
local boolean b1 = doesIntersect(t_ax, t_ay, t_bx, t_by, t.t_ax, t.t_ay, t.t_bx, t.t_by, t)
local boolean b2 = doesIntersect(t_ax, t_ay, t_bx, t_by, t.t_ax, t.t_ay, t.t_cx, t.t_cy, t)
local boolean b3 = doesIntersect(t_ax, t_ay, t_bx, t_by, t.t_bx, t.t_by, t.t_cx, t.t_cy, t)
local boolean b4 = doesIntersect(t_ax, t_ay, t_cx, t_cy, t.t_ax, t.t_ay, t.t_bx, t.t_by, t)
local boolean b5 = doesIntersect(t_ax, t_ay, t_cx, t_cy, t.t_ax, t.t_ay, t.t_cx, t.t_cy, t)
local boolean b6 = doesIntersect(t_ax, t_ay, t_cx, t_cy, t.t_bx, t.t_by, t.t_cx, t.t_cy, t)
local boolean b7 = doesIntersect(t_bx, t_by, t_cx, t_cy, t.t_ax, t.t_ay, t.t_bx, t.t_by, t)
local boolean b8 = doesIntersect(t_bx, t_by, t_cx, t_cy, t.t_ax, t.t_ay, t.t_cx, t.t_cy, t)
local boolean b9 = doesIntersect(t_bx, t_by, t_cx, t_cy, t.t_bx, t.t_by, t.t_cx, t.t_cy, t)
return b1 or b2 or b3 or b4 or b5 or b6 or b7 or b8 or b9
endmethod
method destroy takes nothing returns nothing
call deallocate()
set t_ax = 0
set t_ay = 0
set t_bx = 0
set t_by = 0
set t_cx = 0
set t_cy = 0
set t_actangle = 0
set t_bctangle = 0
set t_cctangle = 0
set t_actdist = 0
set t_bctdist = 0
set t_cctdist = 0
set t_ctx = 0
set t_cty = 0
endmethod
endstruct
endlibrary
Demo:
JASS:
struct Tester extends array
private static method onInit takes nothing returns nothing
// Create a triangle
local Triangle t = Triangle.create(0, 0, 10, 0, 0, 10)
// scale it
call t.scale(2)
// rotate it
call t.rotate(bj_PI)
// move it
call t.moveCentroid(0, 0)
// check if it contains point
if t.containsPoint(1, 1) then
call BJDebugMsg("Triangle contains (1, 1)")
endif
// get its coordinates
call BJDebugMsg("( " + R2S(t.getCentroidX()) + " , " + R2S(t.getCentroidY()) + " ) ")
// check if it collides with a triangle
if t.collides(Triangle.create(0, 0, 1, 0, 0, 1)) then
call BJDebugMsg("a triangle collided with another triangle")
endif
// destroy it
call t.destroy()
endmethod
endstruct
Last edited: