1
0
Bifurcation 0
Ce dépôt a été archivé le 2020-03-15. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
questhelperredux/QuestHelper/dodads_triangles.lua

353 lignes
12 KiB
Lua

local GetTime = QuestHelper_GetTime
QuestHelper_File["dodads_triangles.lua"] = "4.0.1.$svnversion$"
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