- Joined
- Apr 24, 2012
- Messages
- 5,113
JASS:
library Triangle /* v1.0
************************************************************************************
*
* Allows you to create triangles.
*
************************************************************************************
*
* */ uses /*
*
* */ Alloc /*
* - hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/
* */ ErrorMessage /*
* - hiveworkshop.com/forums/jass-resources-412/snippet-error-message-239210/
*
************************************************************************************
*
* API
*
* static method create takes real ax, real ay, real bx, real by, real cx, real cy returns thistype
* - create a Triangle
*
* 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 setVertexY takes integer v, real y 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, ErrorMessage
*
************************************************************************************/
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
private function DoesIntersect takes real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4 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 m = (b2 - b1)/(a2 - a1)
local real y = b1 - a1*m
local real x = -m/y
return a1*x + b1 == a2*x + b2
endfunction
private struct Vertices extends array
static constant integer A = 0
static constant integer B = 1
static constant integer C = 2
endstruct
struct Triangle extends array
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
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
method operator Vertex takes nothing returns Vertices
return 0
endmethod
method setVertexX takes integer v, real x returns nothing
if v == Vertex.A then
set t_ax = x
set t_actangle = Atan2(t_ay - cty, t_ax - ctx)
set t_actdist = GetDistance(t_ax, t_ay, ctx, cty)
elseif v == Vertex.B then
set t_bx = x
set t_bctangle = Atan2(t_by - cty, t_bx - ctx)
set t_bctdist = GetDistance(t_bx, t_by, ctx, cty)
elseif v == Vertex.C then
set t_cx = x
set t_cctangle = Atan2(t_cy - cty, t_cx - ctx)
set t_cctdist = GetDistance(t_cx, t_cy, ctx, cty)
endif
endmethod
method setVertexY takes integer v, real y returns nothing
if v == Vertex.A then
set t_ay = y
set t_actangle = Atan2(t_ay - cty, t_ax - ctx)
set t_actdist = GetDistance(t_ax, t_ay, ctx, cty)
elseif v == Vertex.B then
set t_by = y
set t_bctangle = Atan2(t_by - cty, t_bx - ctx)
set t_bctdist = GetDistance(t_bx, t_by, ctx, cty)
elseif v == Vertex.C then
set t_cy = y
set t_cctangle = Atan2(t_cy - cty, t_cx - ctx)
set t_cctdist = GetDistance(t_cx, t_cy, ctx, cty)
endif
endmethod
method getVertexX takes integer v returns real
if v == Vertex.A then
return t_ax
elseif v == Vertex.B then
return t_bx
elseif v == Vertex.C then
return t_cx
endif
return 0
endmethod
method getVertexY takes integer v returns real
if v == Vertex.A then
return t_ay
elseif v == Vertex.B then
return t_by
elseif v == Vertex.C then
return t_cy
endif
return 0
endmethod
method collides takes thistype t returns boolean
local boolean r1 = DoesIntersect(t_ax, t_ay, t_bx, t_by, t.t_ax, t.t_ay, t.t_bx, t.t_by)
local boolean r2 = DoesIntersect(t_bx, t_by, t_cx, t_cy, t.t_bx, t.t_by, t.t_cx, t.t_cy)
local boolean r3 = DoesIntersect(t_cx, t_cy, t_ax, t_ay, t.t_cx, t.t_cy, t.t_ax, t.t_ay)
return r1 or r2 or r3
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
endmethod
endstruct
endlibrary
JASS:
library Polygon /* v1.0
************************************************************************************
*
* Allows you to create Polygons
*
************************************************************************************
*
* */ uses /*
*
* */ Alloc /*
*
* */ Triangle /*
*
************************************************************************************
*
* API
*
************************************************************************************
*
* Credits
*
* Nestharus
*
************************************************************************************/
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 PolygonData
real array x
real array y
endstruct
struct Polygon extends array
private Triangle array t
private real array x
private real array y
private real array vdist
private real array vangle
private real ctx
private real cty
private integer t_vertices
implement Alloc
static method create takes PolygonData pd, integer vertices returns thistype
local thistype this = allocate()
local real tx = 0
local real ty = 0
local integer i = 1
set t_vertices = vertices
loop
set x[i] = pd.x[i]
set y[i] = pd.y[i]
set tx = x[i]
set ty = y[i]
exitwhen i == vertices
set i = i + 1
endloop
set ctx = tx/vertices
set cty = ty/vertices
set i = 1
loop
set vdist[i] = GetDistance(x[i], y[i], ctx, cty)
set vangle[i] = Atan2(cty - y[i], ctx - x[i])
set tx = x[i + 1]
set ty = y[i + 1]
if i == vertices then
set tx = x[1]
set ty = y[1]
endif
set t[i] = Triangle.create(x[i], y[i], tx, ty, ctx, cty)
exitwhen i == vertices
set i = i + 1
endloop
return this
endmethod
method scale takes real scale returns nothing
local integer i = 1
loop
set x[i] = ctx + (vdist[i] * scale) * Cos(vangle[i])
set y[i] = cty + (vdist[i] * scale) * Sin(vangle[i])
call t[i].setVertexX(Vertex.A, x[i])
call t[i].setVertexY(Vertex.A, y[i])
exitwhen i == t_vertices
set i = i + 1
endloop
endmethod
method rotate takes real radians returns nothing
local integer i = 1
local real tx = ctx
local real ty = cty
local real tdist
local real tangle
loop
set vangle[i] = vangle[i] + radians
set x[i] = ctx + vdist[i] * Cos(vangle[i])
set y[i] = cty + vdist[i] * Sin(vangle[i])
call t[i].setVertexX(Vertex.A, x[i])
call t[i].setVertexY(Vertex.A, y[i])
exitwhen i == t_vertices
set i = i + 1
endloop
endmethod
method move takes real x, real y returns nothing
local integer i = 1
local real tdist
local real tangle
set ctx = x
set cty = y
loop
set x[i] = ctx + vdist[i] * Cos(vangle[i])
set y[i] = cty + vdist[i] * Sin(vangle[i])
call t[i].setVertexX(Vertex.A, x[i])
call t[i].setVertexY(Vertex.A, y[i]
exitwhen i == t_vertices
set i = i + 1
endloop
endmethod
method containsPoint takes real x, real y returns boolean
local integer i = 1
local boolean b
loop
set b = t[i].containsPoint(x, y)
if b then
return true
endif
exitwhen i == t_vertices
set i = i + 1
endloop
return false
endmethod
method getCentroidX takes nothing returns real
return ctx
endmethod
method getCentroidY takes nothing returns real
return cty
endmethod
method getVertexX takes integer v returns real
return x[v]
endmethod
method getVertexY takes integer v returns real
return y[v]
endmethod
method setVertexX takes integer v, real x returns nothing
set x[v] = x
set vangle[v] = Atan2(y[v] - cty, x[v] - ctx)
set vdist[v] = GetDistance(x[v], y[v], ctx, cty)
call t[v].setVertexX(Vertex.A, x)
endmethod
method setVertexY takes integer v, real y returns nothing
set y[v] = y
set vangle[v] = Atan2(y[v] - cty, x[v] - ctx)
set vdist[v] = GetDistance(x[v], y[v], ctx, cty)
call t[v].setVertexY(Vertex.A, y)
endmethod
method collides takes thistype p returns boolean
local integer i = 1
local boolean b
loop
set b = t[i].collides(p.t[i])
if b then
return true
endif
exitwhen i == t_vertices or i == p.t_vertices
set i = i + 1
endloop
return false
endmethod
method destroy takes nothing returns nothing
local thistype this = deallocate()
local integer i = 1
loop
call t[i].destroy()
set t[i] = 0
set x[i] = 0
set y[i] = 0
set vangle[i] = 0
set vdist[i] = 0
exitwhen i == t_vertices
set i = i + 1
endloop
set t_vertices = 0
set ctx = 0
set cty = 0
endmethod
endstruct
endlibrary
Last edited: