comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: ERASING a line
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: ERASING a line [message #7152] Thu, 10 October 1996 00:00
David Foster is currently offline  David Foster
Messages: 341
Registered: January 1996
Senior Member
Andilu wrote:

> On Tue, 8 Oct 1996, Mario Noyon wrote:
>
>> I would like to draw a vertical line on a drawing widget and erase it
>> afterwards. Just like idl does it with the BOX_CURSOR.
>> I watched this routine to see how they did, but my pocedure refuses to
>> redraw the line erased.

You might try using the XOR drawing mode to allow you to draw and
then erase in a draw widget. Sometimes the results are acceptable,
sometimes not. I have a routine called WINDOW_XOR_LINE.PRO that
pops up a slider widget, and lets you adjust either a vertical or
horizontal line in a draw widget, and returns the X/Y position.
Don't know if this is what you need, but it would at least
illustrate the method. Let me know by email if you'd like a
copy.

Dave

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
David S. Foster Univ. of California, San Diego
Programmer/Analyst Brain Image Analysis Laboratory
foster@bial1.ucsd.edu Department of Psychiatry
(619) 622-5892 8950 Via La Jolla Drive, Suite 2200
La Jolla, CA 92037
[ UCSD Mail Code 0949 ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
Re: ERASING a line [message #7159 is a reply to message #7152] Wed, 09 October 1996 00:00 Go to previous message
davidf is currently offline  davidf
Messages: 2866
Registered: September 1996
Senior Member
Mario Noyon <mnoyon@jmc-luni.u-bordeaux2.fr> writes:

> I would like to draw a vertical line on a drawing widget and erase it
> afterwards. Just like idl does it with the BOX_CURSOR.
> I watched this routine to see how they did, but my procedure refuses to
> redraw the line erased.

> Does someone have an idea?

You should count your blessings. I have just the opposite problem.
My procedures do *exactly* what I tell them to do, but half the
time they produce nonsense. The technical term for this is
"recalcitrant procedures".

Andy Loughe suggests one solution. Draw the line over again in
the background color.

PLOTS, line, color=!P.BACKGROUND

This is often an excellent solution, but it is not really "erasing" the
box, which you will soon discover if your line crosses anything other
than background.

The technique used in the BOX_CURSOR program is to use the
exclusive OR graphics function.

DEVICE, SET_GRAPHICS_FUNCTION=6 ; XOR mode
PLOTS, line ; Draw the line
PLOTS, line ; Erase the line
DEVICE, SET_GRAPHICS_FUNCTION=3 ; Normal mode

This works by "flipping" the bits of the underlying pixel
values to their "opposite" color. When you draw the second
time, the pixels are flipped back to their original values,
thereby erasing the line.

Unfortunately, this does not always give satisfactory results either
because you can't exactly draw a "green" box, unless you have
a private color table in IDL (and who does?). Since I often want
to draw lines in green or yellow, or some other pleasant color,
I prefer to use a technique called "device copy" in conjunction
with pixmap windows.

In this technique, you create a copy of your graphics window
as a pixmap window (a window in memory). This has everything
your graphics window has in it, except for the line that you
drew in the graphics window. When you want to erase the
line, you "copy" the contents of the pixmap window into the
graphics window. (Sometimes you copy only the portion of
the pixmap window necessary to repair the damage in the
graphics window, but most of the time this technique is
fast enough that I just slam the whole pixmap window
over.) This has the effect of erasing the line. It will
look something like this:

WINDOW, 0, TITLE='Graphics Window', XS=300, YS=300
PLOT, data
OPLOT, moredata
WINDOW, 1, /PIXMAP, XS=300, YS=300
PLOT, data
OPLOT, moredata

; Now draw the line in the graphics window.

WSET, 0
PLOTS, line, COLOR=green

; Now erase the line.

DEVICE, COPY=[0, 0, 300, 300, 0, 0, 1]

Device copy is extremely fast (*much* faster than just re-doing
the graphics). It is the technique I would recommend.

Yours,

David

--
David Fanning, Ph.D.
Phone: 970-221-0438
Fax: 970-221-4728
E-Mail: davidf@fortnet.org
Re: ERASING a line [message #7161 is a reply to message #7159] Wed, 09 October 1996 00:00 Go to previous message
peter is currently offline  peter
Messages: 80
Registered: February 1994
Member
Peter Mason (peterm@demsyd.syd.dem.csiro.au) wrote:

: <Lots of good advice about how to draw on displays>

I'd back up Peter's method 2 -- it is reliable (you get control over the
color of the line(s)), and certainly fast enough (many 10's of redraws
per second, if you want). I've always taken the simple route of copying
the entire window to a pixmap and back (especially if you are drawing
boxes or more complex shapes rather than lines), and I've found that
using normal co-ordinates is 100% reliable and results in short, easy to
read code. If you'd like a copy of a box_cursor routine that uses this
method, let me know.

Peter

--------------------------------
Peter Webb, HP Labs Medical Dept
E-Mail: peter_webb@hpl.hp.com
Phone: (415) 813-3756
Re: ERASING a line [message #7163 is a reply to message #7159] Wed, 09 October 1996 00:00 Go to previous message
Peter Mason is currently offline  Peter Mason
Messages: 145
Registered: June 1996
Senior Member
On Tue, 8 Oct 1996, Mario Noyon wrote:
> I would like to draw a vertical line on a drawing widget and erase it
> afterwards. Just like idl does it with the BOX_CURSOR.
> I watched this routine to see how they did, but my pocedure refuses to
> redraw the line erased.

Here are two ways to do it:

The first is the easiest; it just involves using "XOR" mode. In XOR mode
you can erase a graphic simply by redrawing it. BOX_CURSOR uses this method.
Here's how:
1] Draw your "main" graphics as usual (e.g., a plot or an image).
2] Wait for some initialisation signal (e.g., a button-down event from your
draw widget).
3] Use DEVICE,GET_GRAPHICS=old,SET_GRAPHICS=6 to enter "xor" drawing mode.
4] Draw your initial line (or box or whatever). It's best if you draw it
using "device" coordinates, as it's possible that "data" coords might not
be established, and "normal" coords can be imperfectly repeatable (well,
I've noticed this once or twice with some older versions of IDL).
5] Wait for the user to update the line's position, or to issue a termination
signal. e.g., Wait for a motion- or button-up event from your draw
widget.
6] Redraw your line in the same position as before - this rubs it out.
7] If you got a position-update (e.g., a motion event) in 5], draw the line
in the new position and go back to 5].
8] Use DEVICE,SET_GRAPHICS=old to restore the graphics mode. (Normally "old"
is 3, meaning "copy".)
Commonly the line (or box...) would be drawn with the highest available
colour (!d.table_size in 8-bit mode). In XOR mode it will only come out in
this colour in areas which are otherwise black (if you're lucky) - in other
areas it'll come out in some arbitrary colour. But it'll usually stand out
against the background. If you want total control over the line's colour,
you have to resort to method 2...

Method 2 is more complicated - it's the hard and thorough way.
Before drawing the line, you save the bits of your graphics window which are
about to be overwritten (by the line) to PIXMAP (invisible) window(s). You
erase the line by restoring the bits from the pixmap window(s).
A pixmap window can be created by:
WINDOW,/FREE,/PIXMAP,XSIZE=xpix,YSIZE=ypix &pixid=!D.WINDOW
The easy way out is to make the pixmap window the same size as your draw
widget. But since graphics memory can be a scarce resource and since you'll
just be "overplotting" a vertical line, xpix=1 and ypix=[your widget's height]
will suffice.
To save a "line's worth" to the pixmap window, use:
WSET,pixid &DEVICE,COPY=[xpos,ypos,1,ypix,0,0,drawid] &WSET,drawid
where: xpos&ypos are your line-to-be's position in your draw widget (device
coords); ypix is the height (in pixels) of your draw widget; drawid
is the "value" of your draw widget; pixid is the window ID of your
pixmap window.
To restore from the pixmap window, use:
DEVICE,COPY=[0,0,1,ypix,xpos,ypos,pixid]
So..
Steps 3] and 8] disappear.
Before you draw the line (steps 4] and 7]), save to the pixmap window.
To erase the line (step 6]), just restore from the pixmap window.
This method has an additional complication: you have to destroy and recreate
the pixmap window if the size of your draw widget is changed.


Hope this helps

Peter Mason
Re: ERASING a line [message #7166 is a reply to message #7159] Tue, 08 October 1996 00:00 Go to previous message
Andy Loughe is currently offline  Andy Loughe
Messages: 174
Registered: November 1995
Senior Member
Can you re-draw the line using color=!p.background

-------
Andrew F. Loughe afl@cdc.noaa.gov
University of Colorado, CIRES http://cdc.noaa.gov/~afl
Campus Box 449 phn:(303)492-0707 fax:(303)497-7013
Boulder, CO 80309-0449 "He who laughs last thinks slowest!"


On Tue, 8 Oct 1996, Mario Noyon wrote:

> I would like to draw a vertical line on a drawing widget and erase it
> afterwards. Just like idl does it with the BOX_CURSOR.
> I watched this routine to see how they did, but my pocedure refuses to
> redraw the line erased.
>
> Does someone has an idea??
>
> Thanks.
>
> --
> NOYON Mario
> Computer Science in Medical imaging
> University of Bordeaux 2
> mnoyon@jmc-luni.u-bordeaux2.fr
>
>
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: Filters
Next Topic: SPEED UP

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:06:41 PDT 2025

Total time taken to generate the page: 0.00730 seconds