1 QuestHelper_File
["dodads_triangles.lua"] = "Development Version"
2 QuestHelper_Loadtime
["dodads_triangles.lua"] = GetTime()
4 -- 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.
9 function matrix_create()
10 return {1, 0, 0, 0, 1, 0, 0, 0, 1}
13 function matrix_rescale(matrix
, x
, y
)
14 matrix
[1], matrix
[4] = matrix
[1] * x
, matrix
[4] * x
15 matrix
[2], matrix
[5] = matrix
[2] * y
, matrix
[5] * y
17 function matrix_mult(matrix
, a
, b
, c
, d
, e
, f
) -- this is probably buggy
18 matrix
[1], matrix
[2], matrix
[3], matrix
[4], matrix
[5], matrix
[6], matrix
[7], matrix
[8], matrix
[9] =
19 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
,
20 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
,
21 matrix
[7], matrix
[8], matrix
[9]
23 function matrix_rotate(matrix
, angle
)
24 matrix_mult(matrix
, cos(angle
), -sin(angle
), 0, sin(angle
), cos(angle
), 0)
26 function matrix_print(matrix
)
27 print(string.format("\n%f %f %f\n%f %f %f\n%f %f %f", unpack(matrix
)))
30 local function dist(sx
, sy
, ex
, ey
)
33 dx
, dy
= dx
* dx
, dy
* dy
34 return math
.sqrt(dx
+ dy
)
37 local function testrange(...)
38 for k
= 1, select("#", ...) do
39 if not (select(k
, ...) > -60000 and select(k
, ...) < 60000) then
44 -- thoughts about the transformation
45 -- start with a right triangle, define the top as the base (find a base)
46 -- rescale Y to get the right height
47 -- skew X to get the right bottom X position
48 -- now we have the right shape
49 -- rotate, rescale, translate?
51 -- for now, we define a-b as the base, which means c is the peak
55 local minbutton
= CreateFrame("Button", nil, UIParent
)
56 minbutton
:SetWidth(50)
57 minbutton
:SetHeight(50)
59 local minbutton_tex
= minbutton
:CreateTexture()
60 minbutton_tex
:SetAllPoints()
61 minbutton_tex
:SetTexture(1, 0, 0, 0.5)
63 minbutton
.Moove
= function(self
, x
, y
)
64 minbutton
:ClearAllPoints()
65 minbutton
:SetPoint("CENTER", UIParent
, "TOPLEFT", x
, -y
)
67 table.insert(spots
, minbutton
)
70 local function MakeTriangle(frame
)
71 tex
= frame
:CreateTexture()
72 tex
:SetTexture("Interface\\AddOns\\QuestHelper\\triangle")
74 tex
.parent_frame
= frame
75 -- relative to 0,1 coordinates relative to parent
76 tex
.SetTriangle
= function(self
, ax
, ay
, bx
, by
, cx
, cy
)
77 -- do we need to reverse the triangle?
78 if ax
* by
- bx
* ay
+ bx
* cy
- cx
* by
+ cx
* ay
- cy
* ax
< 0 then
83 print(ax
, ay
, bx
, by
, cx
, cy
)
84 ax
, bx
, cx
= ax
* frame
:GetWidth(), bx
* frame
:GetWidth(), cx
* frame
:GetWidth()
85 ay
, by
, cy
= ay
* frame
:GetHeight(), by
* frame
:GetHeight(), cy
* frame
:GetHeight()
86 print(ax
, ay
, bx
, by
, cx
, cy
)
89 local sx
= math
.min(ax
, bx
, cx
)
90 local sy
= math
.min(ay
, by
, cy
)
91 local ex
= math
.max(ax
, bx
, cx
)
92 local ey
= math
.max(ay
, by
, cy
)
94 local disty
= math
.max(ex
- sx
, ey
- sy
) / 2
96 --print("TOPLEFT", frame, "TOPLEFT", math.min(ax, bx, cx) * frame:GetWidth(), math.min(ax, bx, cx) * frame:GetHeight())
97 --print("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -math.max(ax, bx, cx) * frame:GetWidth(), -math.max(ax, bx, cx) * frame:GetHeight())
98 self
:SetPoint("TOPLEFT", frame
, "TOPLEFT", (sx
+ ex
) / 2 - disty
, -(sy
+ ey
) / 2 + disty
)
99 self
:SetPoint("BOTTOMRIGHT", frame
, "TOPLEFT", (sx
+ ex
) / 2 + disty
, -(sy
+ ey
) / 2 - disty
)
101 local wid
= disty
* 2
102 local hei
= disty
* 2
104 local widextra
= (wid
- (ex
- sx
)) / 2
105 local heiextra
= (hei
- (ey
- sy
)) / 2
107 local base
= matrix_create()
109 matrix_mult(base
, 1, 0, -1 / 512, 0, 1, -1 / 512)
110 matrix_rescale(base
, 512 / 510, 512 / 510)
112 local lenab
= dist(ax
, ay
, bx
, by
)
113 local lenbc
= dist(bx
, by
, cx
, cy
)
114 local lenca
= dist(cx
, cy
, ax
, ay
)
115 local s
= (lenab
+ lenbc
+ lenca
) / 2
116 local area
= math
.sqrt(s
* (s
- lenab
) * (s
- lenbc
) * (s
- lenca
)) -- heron's formula
117 -- triangle area=base*height/2, therefore height=area/base*2
118 local height
= area
/ lenab
* 2
120 print(wid
, hei
, disty
, ex
- sx
, ey
- sy
)
121 print(lenab
, lenbc
, lenca
)
123 print(lenab
/ wid
, height
/ hei
)
126 matrix_rescale(base
, lenab
/ wid
, height
/ hei
)
129 -- now we have it scaled properly, now we have to skew
130 -- right now we have:
142 -- So the question is, how long is DB? Find that out, divide by height, and there's our skew constant
143 -- unit(A-B) dot (C-B) - does this work? I think so
144 -- alternatively, ((A-B) dot (C-B)) / lenab
146 print("db is", ((ax
- bx
) * (cx
- bx
) + (ay
- by
) * (cy
- by
)))
147 print("height is", height
)
148 print("lenab is", lenab
)
151 self
:SetTexCoord(3, 3, 4, 4)
155 -- same as matrix_mult(base, 1, (nastything), 0, 1) (I think? maybe not?)
156 matrix_mult(base
, 1, -((ax
- bx
) * (cx
- bx
) + (ay
- by
) * (cy
- by
)) / lenab
/ height
, 0, 0, 1, 0)
157 --base[2] = base[2] - ((ax - bx) * (cx - bx) + (ay - by) * (cy - by)) / lenab / height * base[5]
161 -- next: we sit and rotate on it
163 local angle
= atan2(ax
- bx
, ay
- by
)
166 matrix_rotate(base
, -angle
- 90) -- this will take adjustment
170 -- now we translate to the expected position
172 print(ax
- sx
, ay
- sy
, (ax
- sx
) / lenab
, (ay
- sy
) / lenab
, (ax
- sx
) / wid
, (ay
- sy
) / hei
)
174 matrix_mult(base
, 1, 0, tigo
or ((ax
- sx
+ widextra
) / wid
), 0, 1, togo
or ((ay
- sy
+ heiextra
) / hei
))
175 --base[3] = base[3] + (ax - sx) / lenab
176 --base[6] = base[6] + (ay - sy) / lenab
178 --[[matrix_rescale(base, 0.5, 0.5)
179 base[3] = base[3] + wing
180 base[6] = base[6] + wong]]
183 local A
, B
, C
, D
, E
, F
= base
[1], base
[2], base
[3], base
[4], base
[5], base
[6]
185 local det
= A
*E
- B
*D
186 local ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
188 ULx
, ULy
= ( B
*F
- C
*E
) / det
, ( -(A
*F
) + C
*D
) / det
189 LLx
, LLy
= ( -B
+ B
*F
- C
*E
) / det
, ( A
- A
*F
+ C
*D
) / det
190 URx
, URy
= ( E
+ B
*F
- C
*E
) / det
, ( -D
- A
*F
+ C
*D
) / det
191 LRx
, LRy
= ( E
- B
+ B
*F
- C
*E
) / det
, ( -D
+ A
-(A
*F
) + C
*D
) / det
193 if testrange(ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
) then
194 self
:SetTexCoord(3, 3, 4, 4)
198 --QuestHelper:TextOut(string.format("%f %f %f %f %f %f %f %f %f", det, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy))
199 --QuestHelper:TextOut(string.format("%f %f %f %f %f %f", A, B, C, D, E, F))
201 self
:SetTexCoord(ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
); -- the sound you hear is vomiting
203 --[[spots[1]:Moove(ax, ay)
204 spots[2]:Moove(bx, by)
205 spots[3]:Moove(cx, cy)]]
213 function CreateTriangle(frame
)
214 if alloc
[frame
] and #alloc
[frame
] > 0 then
215 return table.remove(alloc
[frame
])
217 return MakeTriangle(frame
)
221 function ReleaseTriangle(tri
)
222 if not alloc
[tri
.parent_frame
] then alloc
[tri
.parent_frame
] = {} end
223 table.insert(alloc
[tri
.parent_frame
], tri
)
231 local function MakeLine(frame
)
232 tex
= frame
:CreateTexture()
233 tex
:SetTexture("Interface\\AddOns\\QuestHelper\\line")
235 tex
.parent_frame
= frame
236 -- relative to 0,1 coordinates relative to parent
237 tex
.SetLine
= function(self
, ax
, ay
, bx
, by
)
238 -- do we need to reverse the triangle? NOTE: a lot of this code is unsurprisingly copied from triangle. were you surprised by this?
240 if ax * by - bx * ay + bx * cy - cx * by + cx * ay - cy * ax < 0 then
245 print(ax
, ay
, bx
, by
)
246 ax
, bx
= ax
* frame
:GetWidth(), bx
* frame
:GetWidth()
247 ay
, by
= ay
* frame
:GetHeight(), by
* frame
:GetHeight()
248 print(ax
, ay
, bx
, by
)
249 self
:ClearAllPoints()
251 local sx
= math
.min(ax
, bx
)
252 local sy
= math
.min(ay
, by
)
253 local ex
= math
.max(ax
, bx
)
254 local ey
= math
.max(ay
, by
)
256 local disty
= math
.max(ex
- sx
, ey
- sy
) / 2 + 20
258 --print("TOPLEFT", frame, "TOPLEFT", math.min(ax, bx, cx) * frame:GetWidth(), math.min(ax, bx, cx) * frame:GetHeight())
259 --print("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -math.max(ax, bx, cx) * frame:GetWidth(), -math.max(ax, bx, cx) * frame:GetHeight())
260 self
:SetPoint("TOPLEFT", frame
, "TOPLEFT", (sx
+ ex
) / 2 - disty
, -(sy
+ ey
) / 2 + disty
)
261 self
:SetPoint("BOTTOMRIGHT", frame
, "TOPLEFT", (sx
+ ex
) / 2 + disty
, -(sy
+ ey
) / 2 - disty
)
263 local wid
= disty
* 2
264 local hei
= disty
* 2
266 local widextra
= (wid
- (ex
- sx
)) / 2
267 local heiextra
= (hei
- (ey
- sy
)) / 2
269 local base
= matrix_create()
271 matrix_mult(base
, 1, 0, -1 / 512, 0, 1, 0)
272 matrix_rescale(base
, 512 / 510, 1 / disty
)
274 local lenny
= dist(ax
, ay
, bx
, by
)
275 print("lendist", lenny
, disty
* 2)
276 matrix_rescale(base
, lenny
/ (disty
* 2), 1)
279 local angle
= atan2(ax
- bx
, ay
- by
)
280 matrix_rotate(base
, -angle
- 90)
283 print("trans", 1, 0, tigo
or ((ax
- sx
+ widextra
) / wid
), 0, 1, togo
or ((ay
- sy
+ heiextra
) / hei
))
284 matrix_mult(base
, 1, 0, tigo
or ((ax
- sx
+ widextra
) / wid
), 0, 1, togo
or ((ay
- sy
+ heiextra
) / hei
))
287 local A
, B
, C
, D
, E
, F
= base
[1], base
[2], base
[3], base
[4], base
[5], base
[6]
289 local det
= A
*E
- B
*D
290 local ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
292 ULx
, ULy
= ( B
*F
- C
*E
) / det
, ( -(A
*F
) + C
*D
) / det
293 LLx
, LLy
= ( -B
+ B
*F
- C
*E
) / det
, ( A
- A
*F
+ C
*D
) / det
294 URx
, URy
= ( E
+ B
*F
- C
*E
) / det
, ( -D
- A
*F
+ C
*D
) / det
295 LRx
, LRy
= ( E
- B
+ B
*F
- C
*E
) / det
, ( -D
+ A
-(A
*F
) + C
*D
) / det
297 if testrange(ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
) then
298 self
:SetTexCoord(3, 3, 4, 4)
302 --QuestHelper:TextOut(string.format("%f %f %f %f %f %f %f %f %f", det, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy))
303 --QuestHelper:TextOut(string.format("%f %f %f %f %f %f", A, B, C, D, E, F))
304 self
:SetTexCoord(ULx
, ULy
, LLx
, LLy
, URx
, URy
, LRx
, LRy
); -- the sound you hear is vomiting
306 --[[spots[1]:Moove(ax, ay)
307 spots[2]:Moove(bx, by)
308 spots[3]:Moove(cx, cy)]]
317 -- yeeeeaah, I just overrode a local variable with another near-identical local variable
318 -- that's gonna bite me someday
321 -- guess whether I changed this code after copying it
323 -- I didn't change this code after copying it
325 -- man, if you've read this far in the QH sourcecode, you sure as hell better not be shocked
328 -- that'd be kind of sad.
329 function CreateLine(frame
)
330 if alloc
[frame
] and #alloc
[frame
] > 0 then
331 return table.remove(alloc
[frame
])
333 return MakeLine(frame
)
337 function ReleaseLine(tri
)
338 if not alloc
[tri
.parent_frame
] then alloc
[tri
.parent_frame
] = {} end
339 table.insert(alloc
[tri
.parent_frame
], tri
)
343 -- note: variable name is "tritest". try to guess why
345 if tritest
then tritest
:Hide() end
346 tritest
= CreateLine(UIParent
)
347 tritest
:SetLine(0.5, 0.6, 0.8, 0.7)