This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KingofGamesYami's profile picture

Has anyone got a drawFilledTriangle() or equivalent function?

Started by KingofGamesYami, 31 January 2015 - 11:07 PM
KingofGamesYami #1
Posted 01 February 2015 - 12:07 AM
I'm looking for a way to draw a filled triangle, given any three points. I'll give you credit if I use it, don't worry. :)/>
Bomb Bloke #2
Posted 01 February 2015 - 12:39 AM
I used the technique explained here, once upon a time.
KingofGamesYami #3
Posted 01 February 2015 - 02:43 AM
Looking at that, I came up with this:

local function getPoint( p1, p2, y ) --#p1, p2 are tables containing x,y.  y is... well y
	local a, b = p2.y-p1.y, p1.x-p2.x
	local c = a*p1.x+b*p1.y
	return (c-b*y)/a
end

		local p1 = tPoints[ i ] --#tPoints a table of coordinates(x,y)
		local p2 = tPoints[ i + 1 ] or tPoints[ 1 ]
		local p3 = { x = maxx/2, y = maxy/2 }
		for y = math.min( p1.y, p2.y, p3.y ), math.max( p1.y, p2.y, p3.y ), 0.1 do --#iterate from minimum y to maximum y
			local a, b, c = getPoint( p1, p2, y ), getPoint( p2, p3, y ), getPoint( p3, p1, y ) --#get the intersections of all three lines on that x coord
                        --#here is problem section:  I'm not sure how to figure out which lines I want to intersect...
		end

(TBH, this could be moved to Ask A Pro now)
Exerro #4
Posted 01 February 2015 - 06:32 PM
I use the same method as Bomb Bloke suggested. I think the issue with your method is that the getPoint() function assumes the line is infinite, not a line segment. It is as simple as returning nil if the x it will return is greater than the maximum x of the 2 points or the x is smaller than the minimum x of the the 2 points. You should then only get 2 intersections (or 3 if one lies on a corner, but then 2 of the 3 will be the same), so draw between the minimum and maximum point.

Not actually sure if this will work, it's just off the top of my head, but it makes sense to me so I might be on the right lines. I added


local function getPoint( p1, p2, y ) --#p1, p2 are tables containing x,y.  y is... well y
		local a, b = p2.y-p1.y, p1.x-p2.x
		local c = a*p1.x+b*p1.y
		local x = (c-b*y)/a
		if x > math.max( p1.x, p2.x ) or x < math.min( p1.x, p2.x ) then return nil end -- check if the intersection is outside the line segment.
		return x
end

				local p1 = tPoints[ i ] --#tPoints a table of coordinates(x,y)
				local p2 = tPoints[ i + 1 ] or tPoints[ 1 ]
				local p3 = { x = maxx/2, y = maxy/2 }
				for y = math.min( p1.y, p2.y, p3.y ), math.max( p1.y, p2.y, p3.y ), 0.1 do --#iterate from minimum y to maximum y
						local a, b, c = getPoint( p1, p2, y ), getPoint( p2, p3, y ), getPoint( p3, p1, y ) --#get the intersections of all three lines on that x coord
						local points = {} -- I just do this because Im too lazy to have an if checking which one is nil.
						table.insert( points, a )
						table.insert( points, b )
						table.insert( points, c )
						if #points > 1 then -- make sure the number of intersections are greater than 1, just in case.
							 for x = math.min( unpack( points ) ), math.max( unpack( points ) ) do -- draw between the intersections.
								 -- do stuff
							 end
						end
				end
Edited on 01 February 2015 - 05:33 PM
KingofGamesYami #5
Posted 01 February 2015 - 07:00 PM
Thanks awsumben, that worked (with a little tweaking).
Exerro #6
Posted 01 February 2015 - 07:03 PM
No problem, glad it worked.