- Joined
- Apr 24, 2012
- Messages
- 5,113
JASS:
library Polygon /* v1.0
************************************************************************************
*
* Allows you to create Polygons
*
************************************************************************************
*
* */ uses /*
*
* */ Triangle /*
* - hiveworkshop.com/forums/submissions-414/wip-triangle-240017/
*
************************************************************************************
*
* API
*
* struct PolygonData
* - you will use this to cache the vertex coordinates
*
* static method create takes PolygonData pd, integer vertices returns thistype
* - creates a Polygon using a PolygonData instance
*
* method scale takes real scale returns nothing
* - scales a Polygon size
*
* method rotate takes real radians returns nothing
* - rotates a Polygon
*
* method move takes real tx, real ty returns nothing
* - moves a Polygon via centroid
*
* method containsPoint takes real x, real y returns boolean
* - checks if a Polygon contains a point
*
* method getCentroidX takes nothing returns real
* - gets the x centroid of a polygon
*
* method getCentroidY takes nothing returns real
* - gets the y centroid of a polygon
*
* method getVertexX takes integer v returns real
* - gets the x of a given vertex of a polygon
*
* method getVertexY takes integer v returns real
* - gets the y of a given vertex of a polygon
*
* method setVertexX takes integer v, real tx returns nothing
* - sets the x value of a given vertex of a polygon
*
* method setVertexY takes integer v, real ty returns nothing
* - sets the y value of a given vertex of a polygon
*
* method collides takes thistype p returns boolean
* - checks if a polygon collides with other polygon
*
* method destroy takes nothing returns nothing
* - destroys a polygon
*
************************************************************************************/
globals
/*
Max vertices that can be used
*/
private constant integer VERTEX_MAX_NUMBER = 20
endglobals
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[VERTEX_MAX_NUMBER]
real array y[VERTEX_MAX_NUMBER]
endstruct
struct Polygon
private Triangle array t[VERTEX_MAX_NUMBER]
private real array x[VERTEX_MAX_NUMBER]
private real array y[VERTEX_MAX_NUMBER]
private real array vdist[VERTEX_MAX_NUMBER]
private real array vangle[VERTEX_MAX_NUMBER]
private real ctx
private real cty
private integer t_vertices
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(Triangle.Vertex.A, x[i])
call t[i].setVertexY(Triangle.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(Triangle.Vertex.A, x[i])
call t[i].setVertexY(Triangle.Vertex.A, y[i])
exitwhen i == t_vertices
set i = i + 1
endloop
endmethod
method move takes real tx, real ty returns nothing
local integer i = 1
local real tdist
local real tangle
set ctx = tx
set cty = ty
loop
set x[i] = ctx + vdist[i] * Cos(vangle[i])
set y[i] = cty + vdist[i] * Sin(vangle[i])
call t[i].setVertexX(Triangle.Vertex.A, x[i])
call t[i].setVertexY(Triangle.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
private method updateCent takes nothing returns nothing
local real tx = 0
local real ty = 0
local integer i = 1
loop
set tx = tx + x[i]
set ty = ty + y[i]
exitwhen i == t_vertices
set i = i + 1
endloop
set ctx = tx/t_vertices
set cty = ty/t_vertices
endmethod
method setVertexX takes integer v, real tx returns nothing
set x[v] = tx
call updateCent()
set vangle[v] = Atan2(y[v] - cty, x[v] - ctx)
set vdist[v] = GetDistance(x[v], y[v], ctx, cty)
call t[v].setVertexX(Triangle.Vertex.A, tx)
endmethod
method setVertexY takes integer v, real ty returns nothing
set y[v] = ty
call updateCent()
set vangle[v] = Atan2(y[v] - cty, x[v] - ctx)
set vdist[v] = GetDistance(x[v], y[v], ctx, cty)
call t[v].setVertexY(Triangle.Vertex.A, ty)
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 integer i = 1
call deallocate()
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
Demo code:
JASS:
struct Tester extends array
private static method onInit takes nothing returns nothing
// Create a Polygon(e.g. Pentagon)
local Polygon p
local PolygonData pd = PolygonData.create()
set pd.x[1] = -1
set pd.y[1] = 0
set pd.x[2] = -2.5
set pd.y[2] = 2.5
set pd.x[3] = 0
set pd.y[3] = 5
set pd.x[4] = 2.5
set pd.y[4] = 2.5
set pd.x[5] = 1
set pd.y[5] = 1
set p = Polygon.create(pd, 5)
// scale it
call p.scale(2)
// rotate it
call p.rotate(bj_PI)
// move it
call p.move(0, 0)
// check if it contains point
if p.containsPoint(1, 1) then
call BJDebugMsg("Polygon contains (1, 1)")
endif
// get its coordinates
call BJDebugMsg("( " + R2S(p.getCentroidX()) + " , " + R2S(p.getCentroidY()) + " ) ")
// check if it collides with a polygon
if p.collides(p) then
call BJDebugMsg("a polygon collided with another polygon")
endif
// destroy it
call p.destroy()
endmethod
endstruct
Last edited: