Cool little UI thingys. I can think of an immediate use for two of them as ui improvements here at focus… thanks so much for sharing… I think I’ll impliment test number five as a control for our network render file pathing… and see if anyone can find their renders… ha ha…
I am always in favor of making animators or other crew members go crazy because of
my script and tools just for fun. But I am not sure I understood exactly how are you
planing to use test 5 for whatever you said you would… :curious:
By the way, I would be glad to hear how and where did you implement these babies.
Thanks for the comments!
Well… I was thinking each grid opening could represent a path on the network… and of course the user would have no idea where it is, but could get there through this ui element… ha ha ha…( evil laugh ) Really, Either of the curves would look nice as soft selection ui elements…
This is awesome. Great job!
i love playing with bitmaps. So much fun and can really help illustrating scenarios. How fast are bitmaps generally for you guys to manipulate. Where do you guys begin to see the limitations? I haven’t really tried to push the limit with bitmaps.
/Andreas
nice!, didn’t know exactly how the softselection work, now i know thanks to you. A bezier line with both tangent points manipulated by the pinch and bubble values respectively
Test #7:
try destroyDialog bitmapTest catch ()
rollout bitmapTest "Bitmap test 7"
(
-- Local Variable Declerations
------------------------------------------
local dim = 200
local bgMap
local mousePressed = false
local bgColor = white
local p1Color = red
local p2Color = green
local p3Color = blue
local pt1 = [10,dim - 10]
local pt2 = [dim / 2,10]
local pt3 = [dim - 10,dim - 10]
local jsPos = [0,0]
-- User Interface
------------------------------------------
bitmap bmGraph "" width:dim height:dim
spinner spSubD "SubD:" range:[1,100,6] type:#integer align:#center fieldWidth:30
-- Functions
------------------------------------------
fn createBGMap =
(
bgMap = bitmap bmGraph.width bmGraph.height color:bgColor
)
fn lineLineIntersect pA pB pC pD =
(
pA = [pA.x,pA.y,0]
pB = [pB.x,pB.y,0]
pC = [pC.x,pC.y,0]
pD = [pD.x,pD.y,0]
local a = pB - pA
local b = pD - pC
local c = pC - pA
local cross1 = cross a b
local cross2 = cross c b
local n = pA + (a * ((dot cross2 cross1) / ((length cross1) ^ 2)))
[n.x,n.y]
)
fn getSteps p1 p2 =
(
struct s_neighbor (
pos,
dist
)
local neighborsPos = #([-1,-1],[0,-1],[1,-1],[-1,0],[1,0],[-1,1],[0,1],[1,1])
local neighbors = #()
for p in neighborsPos do (
local newNeighbor = s_neighbor p (distance p2 (p1 + p))
append neighbors newNeighbor
)
fn sortFn v1 v2 =
(
if v1.dist > v2.dist then 1
else if v1.dist < v2.dist then -1
else 0
)
qsort neighbors sortFn
#(neighbors[1].pos,neighbors[2].pos)
)
fn getStep p1 p2 pt steps =
(
local crossPt = lineLineIntersect p1 p2 (pt + steps[1]) (pt + steps[2])
local dist1 = distance crossPt (pt + steps[1])
if dist1 < 0.5 then (
pt + steps[1]
) else (
pt + steps[2]
)
)
fn drawEdge p1 p2 c1 c2 bMap =
(
setPixels bMap p1 #(c1)
setPixels bMap p2 #(c2)
local newPt = p1
local steps = getSteps p1 p2
local cnt = 0
while newPt != p2 and cnt < dim * 2 do (
newPt = getStep p1 p2 newPt steps
local dist1 = distance p1 newPt
local dist2 = distance p2 newPt
local newColor = c1 * dist2 / (dist1 + dist2) + c2 * dist1 / (dist1 + dist2)
setPixels bMap newPt #(newColor)
cnt += 1
)
bMap
)
fn updateGraph =
(
local newMap = copy bgMap
local subD = spSubD.value + 1
newMap = drawEdge pt1 pt2 p1color p2color newMap
newMap = drawEdge pt1 pt3 p1color p3color newMap
newMap = drawEdge pt2 pt3 p2color p3color newMap
fn round val =
(
if val - (floor val) > 0.5 then (
ceil val
) else (
floor val
)
)
for i = 1.0 to subD - 1.0 do (
local rat = i / subD
local pt = pt3 + (pt2 - pt3) * rat
pt = [round pt.x,round pt.y]
newMap = drawEdge pt1 pt p1color (p2color * rat + p3color * (1 - rat)) newMap
)
for i = 1.0 to subD - 1.0 do (
local rat = i / subD
local pt = pt3 + (pt1 - pt3) * rat
pt = [round pt.x,round pt.y]
newMap = drawEdge pt2 pt p2color (p1color * rat + p3color * (1 - rat)) newMap
)
for i = 1.0 to subD - 1.0 do (
local rat = i / subD
local pt = pt2 + (pt1 - pt2) * rat
pt = [round pt.x,round pt.y]
newMap = drawEdge pt3 pt p3color (p1color * rat + p2color * (1 - rat)) newMap
)
bmGraph.bitmap = newMap
) -- end updateGraph fn
fn updateJS pos =
(
if mousePressed do (
jsPos = pos - bmGraph.pos
if jsPos.x >= 0 and jsPos.x <= dim then (
if jsPos.y >= 0 and jsPos.y <= dim then (
if distance jsPos pt1 < distance jsPos pt2 and distance jsPos pt1 < distance jsPos pt3 then (
pt1 = jsPos
) else (
if distance jsPos pt2 < distance jsPos pt3 then (
pt2 = jsPos
) else (
pt3 = jsPos
)
)
updateGraph()
)
)
)
)
fn openDialog =
(
createDialog bitmapTest width:(dim + 10) style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing)
)
fn init =
(
createBGMap()
updateGraph()
)
fn done =
(
-- cleanup code
gc light:true
)
-- Event Handlers
------------------------------------------
on bitmapTest lbuttondown pos do mousePressed = true
on bitmapTest lbuttonup pos do mousePressed = false
on bitmapTest mousemove pos do updateJS pos
on spSubD changed val do updateGraph()
on bitmapTest open do init()
on bitmapTest close do done()
) -- end of rollout
bitmapTest.openDialog()
For a while I was curious about how to draw a line between to point in a bitmap, the quickest way. Yesterday I got an idea. This is the first demo using the new technique.
The basic idea is to test the neighbor pixels of the pixel located on one end of the line and pick the two pixels that are closest to the other end. Than all you need to do is to progress along the line by moving from neighbor to neighbor and checking which neighbor should be next until you reach the other end.
prettyPixel – thanks for that wonderful thread:
http://forums.cgsociety.org/showthread.php?f=98&t=295257
I used the Line-Line Intersection function to determine which neighbor to pick.
I would also like to thank Dave (Opeth) for helping me to develop the idea.
Test #8:
try destroyDialog bitmapTest catch ()
rollout bitmapTest "Bitmap test 6"
(
-- Local Variable Declerations
------------------------------------------
local width = 200
local height = 200
local boarder = 20
local bgColor = white
local p1Color = red
local p2Color = green
local p3Color = blue
local stripedLinesColor = bgColor / 2
local graphColor = blue
local bgMap
local mousePressed = false
local jsPos = [0,0]
-- User Interface
------------------------------------------
bitmap bmGraph "" width:(width * 2) height:(height + 2 * boarder)
spinner spMax "Max:" range:[-10,10,1] align:#left offset:[-10,0] fieldwidth:35 scale:0.01
spinner spMin "Min:" range:[-10,10,0] align:#right offset:[10,-22] fieldwidth:35 scale:0.01
spinner spPrec "precision:" range:[0.01,1,0.5] align:#center fieldwidth:40 scale:0.01
-- Functions
------------------------------------------
fn createBGMap =
(
bgMap = bitmap bmGraph.width bmGraph.height color:bgColor
-- Draw Horizontal striped lines:
local linePixels = #()
for x = 0 to (bmGraph.width - 1) do (
append linePixels (if mod x 10 > 5 then stripedLinesColor else bgColor)
)
setPixels bgMap [0,boarder] linePixels
setPixels bgMap [0,boarder + height] linePixels
-- Draw Vertical striped lines:
for y = 0 to (bmGraph.height - 1) do (
if mod y 10 > 5 then (
setPixels bgMap [width,y] #(stripedLinesColor)
)
)
)
fn lineLineIntersect pA pB pC pD =
(
pA = [pA.x,pA.y,0]
pB = [pB.x,pB.y,0]
pC = [pC.x,pC.y,0]
pD = [pD.x,pD.y,0]
local a = pB - pA
local b = pD - pC
local c = pC - pA
local cross1 = cross a b
local cross2 = cross c b
local n = pA + (a * ((dot cross2 cross1) / ((length cross1) ^ 2)))
[n.x,n.y]
)
fn getSteps p1 p2 =
(
struct s_neighbor (
pos,
dist
)
local neighborsPos = #([-1,-1],[0,-1],[1,-1],[-1,0],[1,0],[-1,1],[0,1],[1,1])
local neighbors = #()
for p in neighborsPos do (
local newNeighbor = s_neighbor p (distance p2 (p1 + p))
append neighbors newNeighbor
)
fn sortFn v1 v2 =
(
if v1.dist > v2.dist then 1
else if v1.dist < v2.dist then -1
else 0
)
qsort neighbors sortFn
#(neighbors[1].pos,neighbors[2].pos)
)
fn getStep p1 p2 pt steps =
(
local crossPt = lineLineIntersect p1 p2 (pt + steps[1]) (pt + steps[2])
local dist1 = distance crossPt (pt + steps[1])
if dist1 < 0.5 then (
pt + steps[1]
) else (
pt + steps[2]
)
)
fn drawEdge p1 p2 bMap =
(
local newPt = p1
local steps = getSteps p1 p2
local cnt = 0
while newPt != p2 and cnt < 200 do (
newPt = getStep p1 p2 newPt steps
setPixels bMap newPt #(graphColor)
cnt += 1
)
bMap
)
fn updateGraph =
(
-- Draw Bezier Curve:
local newMap = copy bgMap
local P0 = [0,height + boarder]
local P1 = [width / 3,boarder + height * (1 - spMin.value)]
local P2 = [width * 2 / 3,boarder + height * (1 - spMax.value)]
local P3 = [width,boarder]
local lastPt = [0,0]
for t = 0.0 to 1.0 by spPrec.value do (
local Pt = (1-t) ^ 3 * P0 + 3 * (1-t) ^ 2 * t * P1 + 3 * (1-t) * t ^ 2 * P2 + t ^ 3 * P3
for i = 1 to 2 do (
Pt[i] = if Pt[i] - (floor Pt[i]) > 0.5 then ceil Pt[i] else floor Pt[i]
)
if Pt != lastPt then (
newMap = drawEdge lastPt Pt newMap
newMap = drawEdge [2 * width - lastPt.x,lastPt.y] [2 * width - Pt.x,Pt.y] newMap
lastPt = Pt
)
)
newMap = drawEdge [width,boarder] lastPt newMap
newMap = drawEdge [width,boarder] [2 * width - lastPt.x,lastPt.y] newMap
bmGraph.bitmap = newMap
) -- end updateGraph fn
fn openDialog =
(
createDialog bitmapTest width:((width + 5) * 2) style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing)
)
fn init =
(
createBGMap()
updateGraph()
)
fn done =
(
-- cleanup code
gc light:true
)
-- Event Handlers
------------------------------------------
on spPrec changed val do updateGraph()
on spMax changed val do updateGraph()
on spMin changed val do updateGraph()
on bitmapTest open do init()
on bitmapTest close do done()
) -- end of rollout
bitmapTest.openDialog()
A Bezier Curve with the Draw Edge Function.
Test #9:
try destroyDialog bitmapTest catch ()
rollout bitmapTest "Bitmap test 9"
(
-- Local Variable Declerations
------------------------------------------
local dim = 200
local knotRad = 2.4
local bgMap
local mousePressed = false
local lastKnotInd = [0,0]
local bgColor = white
local knotColor = red
local knotVecColor = green
local lineColor = blue
local knotsArr = #()
local jsPos = [0,0]
-- User Interface
------------------------------------------
bitmap bmGraph "" width:dim height:dim
radioButtons rbMode "" labels:#("Draw","Edit") align:#center
radioButtons rbBezierMode "" labels:#("Bezier","Bezier Corner") align:#center
checkBox cbHideKnots "Hide Knots" align:#center
spinner spSteps "Steps:" range:[1,20,6] type:#integer align:#center fieldWidth:30
button bnClear "Clear" width:100
-- Functions
------------------------------------------
fn createBGMap =
(
bgMap = bitmap bmGraph.width bmGraph.height color:bgColor
)
fn round val =
(
if val - (floor val) < 0.5 then floor val else ceil val
)
fn lineLineIntersect pA pB pC pD =
(
pA = [pA.x,pA.y,0]
pB = [pB.x,pB.y,0]
pC = [pC.x,pC.y,0]
pD = [pD.x,pD.y,0]
local a = pB - pA
local b = pD - pC
local c = pC - pA
local cross1 = cross a b
local cross2 = cross c b
local n = pA + (a * ((dot cross2 cross1) / ((length cross1) ^ 2)))
[n.x,n.y]
)
fn getSteps p1 p2 =
(
struct s_neighbor (
pos,
dist
)
local neighborsPos = #([-1,-1],[0,-1],[1,-1],[-1,0],[1,0],[-1,1],[0,1],[1,1])
local neighbors = #()
for p in neighborsPos do (
local newNeighbor = s_neighbor p (distance p2 (p1 + p))
append neighbors newNeighbor
)
fn sortFn v1 v2 =
(
if v1.dist > v2.dist then 1
else if v1.dist < v2.dist then -1
else 0
)
qsort neighbors sortFn
#(neighbors[1].pos,neighbors[2].pos)
)
fn getStep p1 p2 pt steps =
(
local crossPt = lineLineIntersect p1 p2 (pt + steps[1]) (pt + steps[2])
local dist1 = distance crossPt (pt + steps[1])
if dist1 < 0.5 then (
pt + steps[1]
) else (
pt + steps[2]
)
)
fn drawDot pos rad bMap color =
(
for y = 0 to dim - 1 where y >= pos.y - rad and y <= pos.y + rad do (
for x = 0 to dim - 1 where distance pos [x,y] <= rad do (
setPixels bMap [x,y] #(color)
)
)
)
fn drawEdge p1 p2 color bMap =
(
local newPt = p1
local steps = getSteps p1 p2
local cnt = 0
setPixels bMap newPt #(color)
while newPt != p2 and cnt < dim * 2 do (
newPt = getStep p1 p2 newPt steps
setPixels bMap newPt #(color)
cnt += 1
)
bMap
)
fn drawKnots bmap =
(
if not cbHideKnots.state and knotsArr.count > 0 then (
for k = 1 to knotsArr.count do (
drawDot knotsArr[k][1] knotRad bmap knotVecColor
drawDot knotsArr[k][2] knotRad bmap knotColor
drawDot knotsArr[k][3] knotRad bmap knotVecColor
)
if mousePressed and rbMode.state == 2 then (
drawDot knotsArr[lastKnotInd.x][lastKnotInd.y] (knotRad * 1.5) bmap orange
)
)
bmap
)
fn updateGraph =
(
local newMap = copy bgMap
if knotsArr.count > 0 then (
for k = 1 to knotsArr.count do (
if knotsArr.count > 1 and k < knotsArr.count then (
local P0 = knotsArr[k][2]
local P1 = knotsArr[k][3]
local P2 = knotsArr[k + 1][1]
local P3 = knotsArr[k + 1][2]
local Pt0 = P0
for t = 0.0 to 1.0 by 1.0 / spSteps.value do (
local Pt = (1-t) ^ 3 * P0 + 3 * (1-t) ^ 2 * t * P1 + 3 * (1-t) * t ^ 2 * P2 + t ^ 3 * P3
Pt = [round Pt.x,round Pt.y]
newMap = drawEdge Pt0 Pt lineColor newMap
Pt0 = Pt
)
)
if not cbHideKnots.state then (
newMap = drawEdge knotsArr[k][1] knotsArr[k][2] knotVecColor newMap
newMap = drawEdge knotsArr[k][2] knotsArr[k][3] knotVecColor newMap
)
)
)
newMap = drawKnots newMap
bmGraph.bitmap = newMap
) -- end updateGraph fn
fn mPressed pos =
(
mousePressed = true
if rbMode.state == 1 then (
local newKnot = #()
append newKnot (pos - bmGraph.pos - [10,0])
append newKnot (pos - bmGraph.pos)
append newKnot (pos - bmGraph.pos + [10,0])
append knotsArr newKnot
updateGraph()
) else (
if knotsArr.count > 0 then (
local lastDist = dim * 2
for k = 1 to knotsArr.count do (
for i = 1 to 3 do (
local newDist = distance (pos - bmGraph.pos) knotsArr[k][i]
if newDist < lastDist then (
lastDist = newDist
lastKnotInd = [k,i]
)
)
)
)
)
)
fn updateJS pos =
(
if mousePressed do (
jsPos = pos - bmGraph.pos
if rbMode.state == 1 then (
knotsArr[knotsArr.count][2] = jsPos
knotsArr[knotsArr.count][1] = jsPos - [10,0]
knotsArr[knotsArr.count][3] = jsPos + [10,0]
) else (
if lastKnotInd.y == 2 then (
local oldPos = knotsArr[lastKnotInd.x][lastKnotInd.y]
knotsArr[lastKnotInd.x][1] += jsPos - oldPos
knotsArr[lastKnotInd.x][3] += jsPos - oldPos
) else (
if rbBezierMode.state == 1 then (
local otherHandleIndex = 4 - lastKnotInd.y
local otherHandleDist = distance knotsArr[lastKnotInd.x][2] knotsArr[lastKnotInd.x][otherHandleIndex]
local dir = normalize (jsPos - knotsArr[lastKnotInd.x][2])
local otherHandlePos = knotsArr[lastKnotInd.x][2] - dir * otherHandleDist
knotsArr[lastKnotInd.x][otherHandleIndex] = [round otherHandlePos.x,round otherHandlePos.y]
)
)
knotsArr[lastKnotInd.x][lastKnotInd.y] = jsPos
)
)
updateGraph()
)
fn clearVP =
(
knotsArr = #()
updateGraph()
rbMode.state = 1
)
fn openDialog =
(
createDialog bitmapTest width:(dim + 10) style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing)
)
fn init =
(
createBGMap()
updateGraph()
)
fn done =
(
-- cleanup code
gc light:true
)
-- Event Handlers
------------------------------------------
on bitmapTest lbuttondown pos do mPressed pos
on bitmapTest lbuttonup pos do mousePressed = false
on bitmapTest mousemove pos do updateJS pos
on bnClear pressed do clearVP()
on cbHideKnots changed state do updateGraph()
on spSteps changed val do updateGraph()
on bitmapTest open do init()
on bitmapTest close do done()
) -- end of rollout
bitmapTest.openDialog()
Draw a Spline using the bezier function and draw edge technique.
Edit (05.07.2008) – Added Bezier / Bezier Corner Handles radio button.
Test #10:
try destroyDialog bitmapTest catch ()
rollout bitmapTest "Bitmap test 9"
(
-- Local Variable Declerations
------------------------------------------
local dim = 200
local knotRad = 2.4
local bgMap, newMap
local mousePressed = false
local lastKnotInd = [0,0]
local knotsArr = #()
local jsPos = [0,0]
local bgColor = white
local knotColor = red
local knotVecColor = green
local lineColor = blue
-- User Interface
------------------------------------------
bitmap bmGraph "" width:dim height:dim
radioButtons rbMode "" labels:#("Draw","Edit") align:#center
radioButtons rbBezierMode "" labels:#("Bezier","Bezier Corner") align:#center
spinner spThickness "Thickness:" range:[0.1,10,0.3] align:#center scale:0.1 fieldWidth:40
checkBox cbHideKnots "Hide Knots" align:#center
spinner spSteps "Steps:" range:[1,20,6] type:#integer align:#center fieldWidth:30
button bnClear "Clear" width:100
-- Functions
------------------------------------------
fn createBGMap =
(
bgMap = bitmap bmGraph.width bmGraph.height color:bgColor
)
fn round val =
(
if val - (floor val) < 0.5 then floor val else ceil val
)
fn lineLineIntersect pA pB pC pD =
(
pA = [pA.x,pA.y,0]
pB = [pB.x,pB.y,0]
pC = [pC.x,pC.y,0]
pD = [pD.x,pD.y,0]
local a = pB - pA
local b = pD - pC
local c = pC - pA
local cross1 = cross a b
local cross2 = cross c b
local n = pA + (a * ((dot cross2 cross1) / ((length cross1) ^ 2)))
[n.x,n.y]
)
fn getSteps p1 p2 =
(
struct s_neighbor (
pos,
dist
)
local neighborsPos = #([-1,-1],[0,-1],[1,-1],[-1,0],[1,0],[-1,1],[0,1],[1,1])
local neighbors = #()
for p in neighborsPos do (
local newNeighbor = s_neighbor p (distance p2 (p1 + p))
append neighbors newNeighbor
)
fn sortFn v1 v2 =
(
if v1.dist > v2.dist then 1
else if v1.dist < v2.dist then -1
else 0
)
qsort neighbors sortFn
#(neighbors[1].pos,neighbors[2].pos)
)
fn getStep p1 p2 pt steps =
(
local crossPt = lineLineIntersect p1 p2 (pt + steps[1]) (pt + steps[2])
local dist1 = distance crossPt (pt + steps[1])
if dist1 < 0.5 then (
pt + steps[1]
) else (
pt + steps[2]
)
)
fn drawDot pos rad color =
(
for y = 0 to rad do (
local colorArr = #()
for x = 0 to rad do (
local dist = sqrt (x ^ 2 + y ^ 2)
if dist <= rad then (
append colorArr color
insertItem color colorArr 1
)
)
setPixels newMap (pos - [colorArr.count / 2,y]) colorArr
setPixels newMap (pos - [colorArr.count / 2,- y]) colorArr
)
)
fn drawEdge p1 p2 color rad =
(
local newPt = p1
local steps = getSteps p1 p2
local cnt = 0
while newPt != p2 and cnt < dim * 2 do (
newPt = getStep p1 p2 newPt steps
drawDot newPt rad color
cnt += 1
)
)
fn drawKnots =
(
if not cbHideKnots.state and knotsArr.count > 0 then (
for k = 1 to knotsArr.count do (
drawDot knotsArr[k][1] knotRad knotVecColor
drawDot knotsArr[k][2] knotRad knotColor
drawDot knotsArr[k][3] knotRad knotVecColor
)
if mousePressed and rbMode.state == 2 then (
drawDot knotsArr[lastKnotInd.x][lastKnotInd.y] (knotRad * 1.5) orange
)
)
)
fn updateGraph =
(
newMap = copy bgMap
if knotsArr.count > 0 then (
for k = 1 to knotsArr.count do (
if knotsArr.count > 1 and k < knotsArr.count then (
local P0 = knotsArr[k][2]
local P1 = knotsArr[k][3]
local P2 = knotsArr[k + 1][1]
local P3 = knotsArr[k + 1][2]
local Pt0 = P0
for t = 0.0 to 1.0 by 1.0 / spSteps.value do (
local Pt = (1-t) ^ 3 * P0 + 3 * (1-t) ^ 2 * t * P1 + 3 * (1-t) * t ^ 2 * P2 + t ^ 3 * P3
Pt = [round Pt.x,round Pt.y]
local newRad = spThickness.value
drawEdge Pt0 Pt lineColor newRad
Pt0 = Pt
)
)
if not cbHideKnots.state then (
drawEdge knotsArr[k][1] knotsArr[k][2] knotVecColor 0.3
drawEdge knotsArr[k][2] knotsArr[k][3] knotVecColor 0.3
)
)
)
drawKnots()
bmGraph.bitmap = newMap
) -- end updateGraph fn
fn mPressed pos =
(
mousePressed = true
if rbMode.state == 1 then (
local newKnot = #()
append newKnot (pos - bmGraph.pos - [10,0])
append newKnot (pos - bmGraph.pos)
append newKnot (pos - bmGraph.pos + [10,0])
append knotsArr newKnot
updateGraph()
) else (
if knotsArr.count > 0 then (
local lastDist = dim * 2
for k = 1 to knotsArr.count do (
for i = 1 to 3 do (
local newDist = distance (pos - bmGraph.pos) knotsArr[k][i]
if newDist < lastDist then (
lastDist = newDist
lastKnotInd = [k,i]
)
)
)
)
)
)
fn updateJS pos =
(
if mousePressed do (
jsPos = pos - bmGraph.pos
if rbMode.state == 1 then (
knotsArr[knotsArr.count][2] = jsPos
knotsArr[knotsArr.count][1] = jsPos - [10,0]
knotsArr[knotsArr.count][3] = jsPos + [10,0]
) else (
if lastKnotInd.y == 2 then (
local oldPos = knotsArr[lastKnotInd.x][lastKnotInd.y]
knotsArr[lastKnotInd.x][1] += jsPos - oldPos
knotsArr[lastKnotInd.x][3] += jsPos - oldPos
) else (
if rbBezierMode.state == 1 then (
local otherHandleIndex = 4 - lastKnotInd.y
local otherHandleDist = distance knotsArr[lastKnotInd.x][2] knotsArr[lastKnotInd.x][otherHandleIndex]
local dir = normalize (jsPos - knotsArr[lastKnotInd.x][2])
local otherHandlePos = knotsArr[lastKnotInd.x][2] - dir * otherHandleDist
knotsArr[lastKnotInd.x][otherHandleIndex] = [round otherHandlePos.x,round otherHandlePos.y]
)
)
knotsArr[lastKnotInd.x][lastKnotInd.y] = jsPos
)
updateGraph()
)
)
fn clearVP =
(
knotsArr = #()
updateGraph()
rbMode.state = 1
)
fn openDialog =
(
createDialog bitmapTest width:(dim + 10) style:#(#style_titlebar, #style_border, #style_sysmenu,#style_resizing)
)
fn init =
(
createBGMap()
updateGraph()
)
fn done =
(
-- cleanup code
gc light:true
)
-- Event Handlers
------------------------------------------
on bitmapTest lbuttondown pos do mPressed pos
on bitmapTest lbuttonup pos do (
mousePressed = false
updateGraph()
)
on bitmapTest mousemove pos do updateJS pos
on bnClear pressed do clearVP()
on spThickness changed val do updateGraph()
on spPower changed val do updateGraph()
on cbHideKnots changed state do updateGraph()
on spSteps changed val do updateGraph()
on bitmapTest open do init()
on bitmapTest close do done()
) -- end of rollout
bitmapTest.openDialog()
An improved version of the ‘Draw Dot’ function.
Using this technique I was able to set the spline thickness as well.