• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Polygon/Tri

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:
Top