[REBOL] Transparency
From: philb:upnaway at: 16-Nov-2001 21:42
Hi Brent,
I never managed to get the key effect to work ... excellent.
The version of graph.r you are using is rather old.
I did start work on a version that used the draw dialect to draw lines instead of poke'ing
the image.
As the lines are just enties in a block it is possible to remove the lines by removing
the entries in the block & re-showing the face.
This is much quicker than clearing the image as the program currently does (by poking
every pixel!!).
It may solve your transparency problem.
Cheers Phil
=== Original Message ===
I need to plot some points dynamically over an image. I thought I could
do it easily by adapting graph.r by Phil Bevans. I'd just make the
paper
transparent and make the image the backdrop. This sorta
worked. I made the "paper" color, white, transparent in the panel on
which the plot is done. That works up until I clear the plot to update
it. Then the "paper" goes back to white - which should be OK since
I've made white the transparent color - but it isn't transparent
anymore. Is it a bug that white doesn't remain transparent - or do I
just not know how to keep it that way.
Below is the code of graph.r with my few mods to it. If you search down
for ";;;this works" and ";;;this makes paper opaque again" you'll see
where I think the problem is - but then I obviously don't understand
the problem.
Brent Meeker
"A computer lets you make more mistakes faster than any invention in
human
history--with the possible exceptions of handguns and tequila."
--Mitch Ratcliffe
================================================================================
REBOL []
; functions
paper: make object!
[
size: 0x0
x-min: -1
x-max: 1
y-min: -1
y-max: 1
grid: yes
x-grid: 20
y-grid: 20
grid-color: red
axes: yes
axes-color: black
paper-color: white
pen-color: black
axes-color: black
image: none
crt: func
[
size [pair!]
xmin [decimal!]
xmax [decimal!]
ymin [decimal!]
ymax [decimal!]
]
[
self/size: size
self/x-min: xmin
self/x-max: xmax
self/y-min: ymin
self/y-max: ymax
self/image: to-image to-pair reduce [size/x size/y]
clear-im self/image self/paper-color
]
]
; clear the image to a colour
clear-im: func [im [image!] color [tuple!] /local j]
[
repeat j im/size/x * im/size/y [poke im j color]
]
; plot a point
plot: func [im [image!] p col [tuple!] /local i xs ys]
[
set [xs ys] [im/size/x im/size/y]
if any[p/x < 1 p/x > xs p/y < 1 p/y > ys]
[return]
i: ys - p/y * xs + p/x
if any [i <= 0 i > (im/size/x * im/size/y)]
[return]
poke im i col
]
draw-line: func [
{draw line from point a to b using Bresenham's algorithm}
im [image!]
a [pair!]
b [pair!]
color [tuple!]
/local d inc dpr dpru p set-pixel xs ys
][
set [xs ys] [im/size/x im/size/y]
set-pixel: func [p c] [poke im (ys - p/y * xs + p/x) c]
if any [a/x < 1 a/y < 1 a/x > xs a/y > ys b/x < 1 b/y < 1 b/x > xs
b/y >
ys] [return]
d: abs (b - a)
inc: 1x1
if a/x > b/x [inc/x: -1]
if a/y > b/y [inc/y: -1]
either d/x >= d/y [
dpr: 2 * d/y
dpru: dpr - (2 * d/x)
p: dpr - d/x
loop d/x + 1 [
set-pixel a color
either p > 0 [
a: a + inc
p: p + dpru
][
a/x: a/x + inc/x
p: p + dpr
]
]
][
dpr: 2 * d/x
dpru: dpr - (2 * d/y)
p: dpr - d/y
loop d/y + 1 [
set-pixel a color
either p > 0 [
a: a + inc
p: p + dpru
][
a/y: a/y + inc/y
p: p + dpr
]
]
]
]
; Convert Degrees to Radians & Radians to Degrees
rad: function [x] [] [ x * pi / 180 ]
deg: function [x] [] [ x * 180 / pi ]
; trig functions
sin: function [x] [] [return sine/radians x]
cos: function [x] [] [return cosine/radians x]
tan: function [x] [] [return tangent/radians x]
; square-root
sqrt: function [x] [] [return square-root x]
; hyperbolic trig functions
sinh: function [x] [] [return ((exp(x)) - (exp(- x))) / 2]
cosh: function [x] [] [return ((exp(x)) + (exp(- x))) / 2]
tanh: function [x] [] [return ((exp(2 * x)) - 1) / ((exp(2 * x)) + 1)]
fac: func [x [integer!] /local fa i]
[
if x < 0 [return none]
fa: 1.0
i: 1
while [i <= x]
[
fa: fa * i
i: i + 1
]
return fa
]
; create a function
create-function: function [t-func [string!]] [f]
[
; return a newly created function
if error? try [f: to-block load t-func]
[return none]
function [x [any-type!]] [] f
]
mod: func
[
{compute a non-negative remainder}
a [number!]
b [number!]
/local r
]
[
either negative? r: a // b [
r + abs b
] [r]
]
round: func
[
"Round a number"
n [number!]
/places
p [integer!] {Decimal places - can be negative}
/local factor r
]
[
factor: either places [10 ** (- p)] [1]
n: 0.5 * factor + n
n - mod n factor
]
floor: func [
n [number!]
/places
p [integer!] {Decimal places - can be negative}
/local factor r
] [
factor: either places [10 ** (- p)] [1]
n - mod n factor
]
ceiling: func [
n [number!]
/places
p [integer!] {Decimal places - can be negative}
/local factor r
] [
factor: either places [10 ** (- p)] [1]
n + mod (- n) factor
]
truncate: func [
n [number!]
/places
p [integer!] {Decimal places - can be negative}
/local factor r
] [
factor: either places [10 ** (- p)] [1]
n - (n // factor)
]
; initialise the graph
init-graph: func [paper [object!]]
[
clear-im paper/image paper/paper-color
draw-axes paper
]
draw-axes: func [paper /local pt]
[
pt: coordinates paper 0 0
if all [pt/y >= 0 pt/y < paper/size/y]
[draw-line paper/image to-pair reduce [1 pt/y] to-pair reduce
[(paper/size/x - 1) pt/y] paper/axes-color] ; x-axis
if all [pt/x >= 0 pt/x < paper/size/x]
[draw-line paper/image to-pair reduce [pt/x 1] to-pair reduce
[pt/x
paper/size/y] paper/axes-color]; y-axis
]
; convert to co-ordinates
coordinates: func [paper [object!] x [number!] y [number!] /local xc yc]
[
xd: x - paper/x-min
xp: (paper/x-max - paper/x-min) / paper/size/x
xc: xd / xp
if any [xc < 0 xc > paper/size/x] [-1]
if error? try[xc: to-integer round xc]
[return none]
yd: y - paper/y-min
yp: (paper/y-max - paper/y-min) / paper/size/y
yc: yd / yp
if any [yc < 0 yc > paper/size/y] [-1]
if error? try[yc: to-integer round yc]
[return none]
return make pair! reduce [xc yc]
]
new-styles: stylize
[
fix-area: area font [name: "courier new" size: 12] wrap
fix-field: field font [name: "courier new" size: 12]
fix-text: text font [name: "courier new" size: 12]
]
; Draw the graph
draw-graph: func [paper [object!] t-fx [string!] trace [string!] /local
x
x-step fx pt last-pt]
[
if t-fx = ""
[request/ok "No function entered" return]
f-fx: create-function t-fx
if not function? :f-fx
[request/ok "Improper function entered" return]
last-pt: none
x-step: (paper/x-max - paper/x-min) / paper/size/x
for x paper/x-min paper/x-max x-step
[
either not error? try [fx: f-fx x]
[
pt: coordinates paper x fx
if pt <> none
[
switch trace
[
"Point"
[plot paper/image pt paper/pen-color]
"Line"
[
either last-pt <> none
[draw-line paper/image last-pt pt
paper/pen-color]
[plot paper/image pt
paper/pen-color]
]
]
]
last-pt: pt
]
[last-pt: none]
]
]
; Graph Paper settings
gr-settings: func
[
paper [object!]
gr-face [object!]
/local f-xmin f-xmax f-ymin f-ymax f-paper-color f-pen-color
lv-valid
lv-col
]
[
view/new layout
[
backdrop 0.150.0
styles new-styles
origin 5x5
space 5
across
at 5x5
label "Min X" right 80x24
f-xmin: fix-field to-string(paper/x-min) 100x24
return
label "Max X" right 80x24
f-xmax: fix-field to-string(paper/x-max) 100x24
return
label "Min Y" right 80x24
f-ymin: fix-field to-string(paper/y-min) 100x24
return
label "Max Y" right 80x24
f-ymax: fix-field to-string(paper/y-max) 100x24
return
pad 0x-3
label "Clear" right 80x24
pad 0x3
cb-clear: check with [state: false]
return
pad 0x-5
button "Paper Color" 80x24
[
lv-col: request-color/color paper/paper-color
if lv-col <> none
[
f-paper-color/color: lv-col
show f-paper-color
]
]
f-paper-color: box paper/paper-color 100x24 edge [size: 2x2
color:
gray effect: 'bevel]
return
button "Pen Color" 80x24
[
lv-col: request-color/color paper/paper-color
if lv-col <> none
[
f-pen-color/color: lv-col
show f-pen-color
]
]
f-pen-color: box paper/pen-color 100x24 edge [size: 2x2 color:
gray
effect: 'bevel]
return
button "Apply" 185x24
[
lv-valid: yes
if error? try [paper/x-min: to-decimal f-xmin/text]
[request/ok
Invalid Min X value entered
lv-valid: no]
if error? try [paper/x-max: to-decimal f-xmax/text]
[request/ok
Invalid Max X value entered
lv-valid: no]
if error? try [paper/y-min: to-decimal f-ymin/text]
[request/ok
Invalid Min Y value entered
lv-valid: no]
if error? try [paper/y-max: to-decimal f-ymax/text]
[request/ok
Invalid Min Y value entered
lv-valid: no]
paper/paper-color: f-paper-color/color
paper/pen-color: f-pen-color/color
if cb-clear/data = true
[
init-graph pape
show gr-face
]
if lv-valid = yes
[unview]
]
]
]
;
; Main Line
;
gr-size: 700x500
gr-paper: make paper []
gr-paper/crt gr-size -180.0 180.0 -10.0 90.0
gr-paper/pen-color: 0.0.255
gr-paper/paper-color: 255.255.255
gr-paper/image: to-image 650x400
draw-axes gr-paper
lv-init-eqn: "10 * (1 + ((sin (x / 30)) / (x / 30)))"
;
; view the window
;
view layout [
backdrop %ma-31f-16.jpg
origin 0x0
styles new-styles
at 0x0
space 0x0
panel
[
backdrop teal
origin 0x0
space 0
across
vtext "Clear" bold white teal 40x24
[
init-graph gr-paper
show gr-paper-f ;;;this makes paper opaque
again
]
vtext "Save" bold white teal 40x24
[
t-save-name: request-file/title/filter/keep/file "Save Graph
as
png" "Save" "*.png" "graph.png"
if t-save-name <> none
[
if error? try [save/png to-file t-save-name
gr-paper/image]
[request/OK "Unable to Save graph"]
]
]
vtext "Settings" bold white teal [gr-settings gr-paper
gr-paper-f]
60x24
vtext "Quit" bold white teal [quit] 40x24
] edge [size: 1x1 color: gray effect: 'bevel] 510x24
panel
[
across
origin 5x5
space 5x5
at 5x5
gr-paper-f: image gr-paper/image
effect [key white] ;;;this works
return
t-func1: fix-field lv-init-eqn (gr-size * 1x0 + 0x24)
space 0
return
r-trace: rotary 120.20.120 100x24 data ["Line" "Point"]
button "Graph Color"
[
gr-col: request-color/color gr-paper/pen-color
if gr-col <> none [gr-paper/pen-color: gr-col]
]
space 0x5
button "Draw f(x)" 100x24
[
draw-graph gr-paper t-func1/text first r-trace/data
show gr-paper-f
]
button "Save Equation"
[
either t-func1/text = ""
[request/ok "No equation to Save"]
[
filnm: request-file/title/filter/file/keep "Save
Equation"
Save
"*.eqn" "graph.eqn"
if filnm <> none
[
if error? try [write to-file filnm t-func1/text]
[request/OK "Unable to Save Equation"]
]
]
]
button "Load Equation"
[
filnm: request-file/title/filter/file/keep "Load Equation"
Load
"*.eqn" "graph.eqn"
if filnm <> none
[
t-func1/text: read to-file filnm
show t-func1
]
]
] 660x410 + (2 * 0x25) + 0x5
]