2012-01-01 04:01:18 +01:00
local GetTime = QuestHelper_GetTime
2010-11-08 14:28:59 +01:00
QuestHelper_File [ " dodads_triangles.lua " ] = " 4.0.1.$svnversion$ "
2010-10-24 23:17:33 +02:00
QuestHelper_Loadtime [ " dodads_triangles.lua " ] = GetTime ( )
-- I'm really curious what people might make out of this file. I'm not actually open-sourcing it yet, but let's say that if you *were* to come up with a neat idea, and wanted to use this code, I would almost certainly be willing to let you use it. Contact me as ZorbaTHut on EFNet/Freenode/Synirc, or zorba-qh-triangles@pavlovian.net email, or ZorbaTHut on AIM.
local function print ( )
end
function matrix_create ( )
return { 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 }
end
function matrix_rescale ( matrix , x , y )
matrix [ 1 ] , matrix [ 4 ] = matrix [ 1 ] * x , matrix [ 4 ] * x
matrix [ 2 ] , matrix [ 5 ] = matrix [ 2 ] * y , matrix [ 5 ] * y
end
function matrix_mult ( matrix , a , b , c , d , e , f ) -- this is probably buggy
matrix [ 1 ] , matrix [ 2 ] , matrix [ 3 ] , matrix [ 4 ] , matrix [ 5 ] , matrix [ 6 ] , matrix [ 7 ] , matrix [ 8 ] , matrix [ 9 ] =
matrix [ 1 ] * a + matrix [ 4 ] * b + matrix [ 7 ] * c , matrix [ 2 ] * a + matrix [ 5 ] * b + matrix [ 8 ] * c , matrix [ 3 ] * a + matrix [ 6 ] * b + matrix [ 9 ] * c ,
matrix [ 1 ] * d + matrix [ 4 ] * e + matrix [ 7 ] * f , matrix [ 2 ] * d + matrix [ 5 ] * e + matrix [ 8 ] * f , matrix [ 3 ] * d + matrix [ 6 ] * e + matrix [ 9 ] * f ,
matrix [ 7 ] , matrix [ 8 ] , matrix [ 9 ]
end
function matrix_rotate ( matrix , angle )
matrix_mult ( matrix , cos ( angle ) , - sin ( angle ) , 0 , sin ( angle ) , cos ( angle ) , 0 )
end
function matrix_print ( matrix )
print ( string.format ( " \n %f %f %f \n %f %f %f \n %f %f %f " , unpack ( matrix ) ) )
end
local function dist ( sx , sy , ex , ey )
local dx = sx - ex
local dy = sy - ey
dx , dy = dx * dx , dy * dy
return math.sqrt ( dx + dy )
end
local function testrange ( ... )
for k = 1 , select ( " # " , ... ) do
if not ( select ( k , ... ) > - 60000 and select ( k , ... ) < 60000 ) then
return true
end
end
end
-- thoughts about the transformation
-- start with a right triangle, define the top as the base (find a base)
-- rescale Y to get the right height
-- skew X to get the right bottom X position
-- now we have the right shape
-- rotate, rescale, translate?
-- for now, we define a-b as the base, which means c is the peak
local spots = { }
for k = 1 , 3 do
local minbutton = CreateFrame ( " Button " , nil , UIParent )
minbutton : SetWidth ( 50 )
minbutton : SetHeight ( 50 )
local minbutton_tex = minbutton : CreateTexture ( )
minbutton_tex : SetAllPoints ( )
minbutton_tex : SetTexture ( 1 , 0 , 0 , 0.5 )
minbutton.Moove = function ( self , x , y )
minbutton : ClearAllPoints ( )
minbutton : SetPoint ( " CENTER " , UIParent , " TOPLEFT " , x , - y )
end
table.insert ( spots , minbutton )
end
local function MakeTriangle ( frame )
tex = frame : CreateTexture ( )
tex : SetTexture ( " Interface \\ AddOns \\ QuestHelper \\ triangle " )
tex.parent_frame = frame
-- relative to 0,1 coordinates relative to parent
tex.SetTriangle = function ( self , ax , ay , bx , by , cx , cy )
-- do we need to reverse the triangle?
if ax * by - bx * ay + bx * cy - cx * by + cx * ay - cy * ax < 0 then
ax , bx = bx , ax
ay , by = by , ay
end
print ( ax , ay , bx , by , cx , cy )
ax , bx , cx = ax * frame : GetWidth ( ) , bx * frame : GetWidth ( ) , cx * frame : GetWidth ( )
ay , by , cy = ay * frame : GetHeight ( ) , by * frame : GetHeight ( ) , cy * frame : GetHeight ( )
print ( ax , ay , bx , by , cx , cy )
self : ClearAllPoints ( )
local sx = math.min ( ax , bx , cx )
local sy = math.min ( ay , by , cy )
local ex = math.max ( ax , bx , cx )
local ey = math.max ( ay , by , cy )
local disty = math.max ( ex - sx , ey - sy ) / 2
--print("TOPLEFT", frame, "TOPLEFT", math.min(ax, bx, cx) * frame:GetWidth(), math.min(ax, bx, cx) * frame:GetHeight())
--print("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -math.max(ax, bx, cx) * frame:GetWidth(), -math.max(ax, bx, cx) * frame:GetHeight())
self : SetPoint ( " TOPLEFT " , frame , " TOPLEFT " , ( sx + ex ) / 2 - disty , - ( sy + ey ) / 2 + disty )
self : SetPoint ( " BOTTOMRIGHT " , frame , " TOPLEFT " , ( sx + ex ) / 2 + disty , - ( sy + ey ) / 2 - disty )
local wid = disty * 2
local hei = disty * 2
local widextra = ( wid - ( ex - sx ) ) / 2
local heiextra = ( hei - ( ey - sy ) ) / 2
local base = matrix_create ( )
matrix_mult ( base , 1 , 0 , - 1 / 512 , 0 , 1 , - 1 / 512 )
matrix_rescale ( base , 512 / 510 , 512 / 510 )
local lenab = dist ( ax , ay , bx , by )
local lenbc = dist ( bx , by , cx , cy )
local lenca = dist ( cx , cy , ax , ay )
local s = ( lenab + lenbc + lenca ) / 2
local area = math.sqrt ( s * ( s - lenab ) * ( s - lenbc ) * ( s - lenca ) ) -- heron's formula
-- triangle area=base*height/2, therefore height=area/base*2
local height = area / lenab * 2
print ( wid , hei , disty , ex - sx , ey - sy )
print ( lenab , lenbc , lenca )
print ( area , height )
print ( lenab / wid , height / hei )
matrix_print ( base )
matrix_rescale ( base , lenab / wid , height / hei )
matrix_print ( base )
-- now we have it scaled properly, now we have to skew
-- right now we have:
-- A----------B
-- |
-- C
-- We want:
-- A------------B
--
-- C
-- Virtual point:
-- D A------------B
--
-- C
-- So the question is, how long is DB? Find that out, divide by height, and there's our skew constant
-- unit(A-B) dot (C-B) - does this work? I think so
-- alternatively, ((A-B) dot (C-B)) / lenab
print ( " db is " , ( ( ax - bx ) * ( cx - bx ) + ( ay - by ) * ( cy - by ) ) )
print ( " height is " , height )
print ( " lenab is " , lenab )
if height == 0 then
self : SetTexCoord ( 3 , 3 , 4 , 4 )
return
end
-- same as matrix_mult(base, 1, (nastything), 0, 1) (I think? maybe not?)
matrix_mult ( base , 1 , - ( ( ax - bx ) * ( cx - bx ) + ( ay - by ) * ( cy - by ) ) / lenab / height , 0 , 0 , 1 , 0 )
--base[2] = base[2] - ((ax - bx) * (cx - bx) + (ay - by) * (cy - by)) / lenab / height * base[5]
matrix_print ( base )
-- next: we sit and rotate on it
local angle = atan2 ( ax - bx , ay - by )
print ( angle )
matrix_rotate ( base , - angle - 90 ) -- this will take adjustment
matrix_print ( base )
-- now we translate to the expected position
print ( ax - sx , ay - sy , ( ax - sx ) / lenab , ( ay - sy ) / lenab , ( ax - sx ) / wid , ( ay - sy ) / hei )
matrix_mult ( base , 1 , 0 , tigo or ( ( ax - sx + widextra ) / wid ) , 0 , 1 , togo or ( ( ay - sy + heiextra ) / hei ) )
--base[3] = base[3] + (ax - sx) / lenab
--base[6] = base[6] + (ay - sy) / lenab
--[[matrix_rescale(base, 0.5, 0.5)
base [ 3 ] = base [ 3 ] + wing
base [ 6 ] = base [ 6 ] + wong ] ]
local A , B , C , D , E , F = base [ 1 ] , base [ 2 ] , base [ 3 ] , base [ 4 ] , base [ 5 ] , base [ 6 ]
local det = A * E - B * D
local ULx , ULy , LLx , LLy , URx , URy , LRx , LRy
ULx , ULy = ( B * F - C * E ) / det , ( - ( A * F ) + C * D ) / det
LLx , LLy = ( - B + B * F - C * E ) / det , ( A - A * F + C * D ) / det
URx , URy = ( E + B * F - C * E ) / det , ( - D - A * F + C * D ) / det
LRx , LRy = ( E - B + B * F - C * E ) / det , ( - D + A - ( A * F ) + C * D ) / det
if testrange ( ULx , ULy , LLx , LLy , URx , URy , LRx , LRy ) then
self : SetTexCoord ( 3 , 3 , 4 , 4 )
return
end
--QuestHelper:TextOut(string.format("%f %f %f %f %f %f %f %f %f", det, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy))
--QuestHelper:TextOut(string.format("%f %f %f %f %f %f", A, B, C, D, E, F))
self : SetTexCoord ( ULx , ULy , LLx , LLy , URx , URy , LRx , LRy ) ; -- the sound you hear is vomiting
--[[spots[1]:Moove(ax, ay)
spots [ 2 ] : Moove ( bx , by )
spots [ 3 ] : Moove ( cx , cy ) ] ]
end
return tex
end
local alloc = { }
function CreateTriangle ( frame )
if alloc [ frame ] and # alloc [ frame ] > 0 then
return table.remove ( alloc [ frame ] )
else
return MakeTriangle ( frame )
end
end
function ReleaseTriangle ( tri )
if not alloc [ tri.parent_frame ] then alloc [ tri.parent_frame ] = { } end
table.insert ( alloc [ tri.parent_frame ] , tri )
tri : Hide ( )
end
local function MakeLine ( frame )
tex = frame : CreateTexture ( )
tex : SetTexture ( " Interface \\ AddOns \\ QuestHelper \\ line " )
tex.parent_frame = frame
-- relative to 0,1 coordinates relative to parent
tex.SetLine = function ( self , ax , ay , bx , by )
-- do we need to reverse the triangle? NOTE: a lot of this code is unsurprisingly copied from triangle. were you surprised by this?
--[[
if ax * by - bx * ay + bx * cy - cx * by + cx * ay - cy * ax < 0 then
ax , bx = bx , ax
ay , by = by , ay
end ] ]
print ( ax , ay , bx , by )
ax , bx = ax * frame : GetWidth ( ) , bx * frame : GetWidth ( )
ay , by = ay * frame : GetHeight ( ) , by * frame : GetHeight ( )
print ( ax , ay , bx , by )
self : ClearAllPoints ( )
local sx = math.min ( ax , bx )
local sy = math.min ( ay , by )
local ex = math.max ( ax , bx )
local ey = math.max ( ay , by )
local disty = math.max ( ex - sx , ey - sy ) / 2 + 20
--print("TOPLEFT", frame, "TOPLEFT", math.min(ax, bx, cx) * frame:GetWidth(), math.min(ax, bx, cx) * frame:GetHeight())
--print("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -math.max(ax, bx, cx) * frame:GetWidth(), -math.max(ax, bx, cx) * frame:GetHeight())
self : SetPoint ( " TOPLEFT " , frame , " TOPLEFT " , ( sx + ex ) / 2 - disty , - ( sy + ey ) / 2 + disty )
self : SetPoint ( " BOTTOMRIGHT " , frame , " TOPLEFT " , ( sx + ex ) / 2 + disty , - ( sy + ey ) / 2 - disty )
local wid = disty * 2
local hei = disty * 2
local widextra = ( wid - ( ex - sx ) ) / 2
local heiextra = ( hei - ( ey - sy ) ) / 2
local base = matrix_create ( )
matrix_mult ( base , 1 , 0 , - 1 / 512 , 0 , 1 , 0 )
matrix_rescale ( base , 512 / 510 , 1 / disty )
local lenny = dist ( ax , ay , bx , by )
print ( " lendist " , lenny , disty * 2 )
matrix_rescale ( base , lenny / ( disty * 2 ) , 1 )
local angle = atan2 ( ax - bx , ay - by )
matrix_rotate ( base , - angle - 90 )
print ( " trans " , 1 , 0 , tigo or ( ( ax - sx + widextra ) / wid ) , 0 , 1 , togo or ( ( ay - sy + heiextra ) / hei ) )
matrix_mult ( base , 1 , 0 , tigo or ( ( ax - sx + widextra ) / wid ) , 0 , 1 , togo or ( ( ay - sy + heiextra ) / hei ) )
matrix_print ( base )
local A , B , C , D , E , F = base [ 1 ] , base [ 2 ] , base [ 3 ] , base [ 4 ] , base [ 5 ] , base [ 6 ]
local det = A * E - B * D
local ULx , ULy , LLx , LLy , URx , URy , LRx , LRy
ULx , ULy = ( B * F - C * E ) / det , ( - ( A * F ) + C * D ) / det
LLx , LLy = ( - B + B * F - C * E ) / det , ( A - A * F + C * D ) / det
URx , URy = ( E + B * F - C * E ) / det , ( - D - A * F + C * D ) / det
LRx , LRy = ( E - B + B * F - C * E ) / det , ( - D + A - ( A * F ) + C * D ) / det
if testrange ( ULx , ULy , LLx , LLy , URx , URy , LRx , LRy ) then
self : SetTexCoord ( 3 , 3 , 4 , 4 )
return
end
--QuestHelper:TextOut(string.format("%f %f %f %f %f %f %f %f %f", det, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy))
--QuestHelper:TextOut(string.format("%f %f %f %f %f %f", A, B, C, D, E, F))
self : SetTexCoord ( ULx , ULy , LLx , LLy , URx , URy , LRx , LRy ) ; -- the sound you hear is vomiting
--[[spots[1]:Moove(ax, ay)
spots [ 2 ] : Moove ( bx , by )
spots [ 3 ] : Moove ( cx , cy ) ] ]
end
return tex
end
-- haha
-- yeeeeaah, I just overrode a local variable with another near-identical local variable
-- that's gonna bite me someday
local alloc = { }
-- guess whether I changed this code after copying it
-- hint:
-- I didn't change this code after copying it
-- are you shocked
-- man, if you've read this far in the QH sourcecode, you sure as hell better not be shocked
-- 'cause
-- yeah
-- that'd be kind of sad.
function CreateLine ( frame )
if alloc [ frame ] and # alloc [ frame ] > 0 then
return table.remove ( alloc [ frame ] )
else
return MakeLine ( frame )
end
end
function ReleaseLine ( tri )
if not alloc [ tri.parent_frame ] then alloc [ tri.parent_frame ] = { } end
table.insert ( alloc [ tri.parent_frame ] , tri )
tri : Hide ( )
end
-- note: variable name is "tritest". try to guess why
function testit ( )
if tritest then tritest : Hide ( ) end
tritest = CreateLine ( UIParent )
tritest : SetLine ( 0.5 , 0.6 , 0.8 , 0.7 )
tritest : Show ( )
end