[comp.sys.amiga.tech] Clicking on Irregular Shapes

schwager@m.cs.uiuc.edu (06/21/89)

Hope someone can help with this C question:

Given an irregularly shaped object on a Screen, how can one tell if
the mouse button has been pressed inside of it?  I don't want a box all
around or inside it; I want the object and exactly the object.  Here's
why I ask: I'm going to be drawing a map on the screen (into a Backdrop
window of a workbenchscreen) and I want to be able to select individual
countries.  Take something like Italy- if the user selects the toe of
the boot or the top, it should acknowledge either.  But I don't want them
to be able to select Italy while they're just a tad into Switzerland.  Nor
do I want them to be able to click in a corner of Italy and have them
wondering why the Amiga didn't grab their click.

I was looking at info about gadgets, but I didn't find them handy cuz
the active part is a box.  I don't like the way collision detection is
handled with Bobs, either (I was thinking of checking the collision of
the mouse pointer with Bobs- but the way it's done, the collision
borders for the Bob become a square, also).

Also- the countries will be bordered, if that helps.  Maybe I need to
define my countries by a series of borders, and see if the mouse click
falls inside a border.

So, wizened ones, can anyone help or point me in the direction of some
sample code?  Thanks.
-Mike Schwager				schwager@a.cs.uiuc.edu
-- {uunet,convex,pur-ee}!uiucdcs!schwager   schwager%uiuc@csnet-relay.arpa
	University of Illinois, Dept. of Computer Science

sah@ukc.ac.uk (S.A.Hill) (06/21/89)

In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
>
>Hope someone can help with this C question:
>
>Given an irregularly shaped object on a Screen, how can one tell if
>the mouse button has been pressed inside of it?  I don't want a box all
> ....
>
>-Mike Schwager				schwager@a.cs.uiuc.edu
>-- {uunet,convex,pur-ee}!uiucdcs!schwager   schwager%uiuc@csnet-relay.arpa
>	University of Illinois, Dept. of Computer Science

The easiest thing to do would be to look at the colour under the pointer hot
spot.  Allocate one colour per country (note they needn't look different).
If you don't have enough bit planes in the display to differentiate all the
countries you can have some extra bit planes which aren't displayed.
If memory is at a premium, you could use colour in combination with a
table which gave a rough idea of what is where.

Steve.

steveb@cbmvax.UUCP (Steve Beats) (06/21/89)

In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
>
>Hope someone can help with this C question:
>
>Given an irregularly shaped object on a Screen, how can one tell if
>the mouse button has been pressed inside of it?  I don't want a box all
>around or inside it; I want the object and exactly the object.  
>
>.........................  I don't like the way collision detection is
>handled with Bobs, either (I was thinking of checking the collision of
>the mouse pointer with Bobs- but the way it's done, the collision
>borders for the Bob become a square, also).
>
>-Mike Schwager				schwager@a.cs.uiuc.edu

You were on the right track with the BOBs idea in the first place.  Although
the "hit box" is just that (a box), BOBs allow you to specify a hit mask
too.  You simply OR together all the planes of your country images (excluding
the borders in this case) and install them as the hit mask for the individual
BOBs.  Now, whenever a mouse click is detected inside the hit box, it is
further qualified by anding with the hit mask.  One caveat here, you will
have to make the mouse pointer into a BOB too.  BOB collision detect won't
work with the intuition mouse pointer.  Just turn it into a BOB with a single
pixel hit mask at the hot spot.

	Steve

bradch@microsoft.UUCP (Bradford Christian ms1) (06/22/89)

In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
>[ ... ]
>Given an irregularly shaped object on a Screen, how can one tell if
>the mouse button has been pressed inside of it?  I don't want a box all
>around or inside it; I want the object and exactly the object.  Here's
>why I ask: I'm going to be drawing a map on the screen (into a Backdrop
>window of a workbenchscreen) and I want to be able to select individual
>countries.  Take something like Italy- if the user selects the toe of
>the boot or the top, it should acknowledge either.  But I don't want them
>to be able to select Italy while they're just a tad into Switzerland.  Nor
>do I want them to be able to click in a corner of Italy and have them
>wondering why the Amiga didn't grab their click.
> [ ... ]

Easy solution (hack):

	Make each country a color different than it's neighbors using basic
	topology rules.  Define a rectangle around each country.  When the 
	user clicks, get the color of the pixel under the cursor and check
	all rectangles that contain the cursor.  When one of the right color
	is found, so is your country.  I repeat: this is a hack and will only
	work under ideal conditions.  For example, if you label the countries,
	the user would have to be careful not to click on the label (it would
	be the wrong color).

Better solution (hard):

	QuickDraw (the Mac graphics library) defines an object called a region
	which is an arbitrary shape.  Internally, it's structure is a set of
	lines containing start/end column pairs.  (E.g. line 1 starts at 10
	and continues to 20, line 2 starts at 3 and continues to 15.)  You
	could write your own region package that would include some way of
	converting your country shapes into regions and a check to see if a
	point is inside the region.

Another solution (memory hog):

	Create a separate bitmap for each country.  When the user clicks,
	look at each country whose bounding rectangle contains the point
	and check to see if the point is set in the countrie's bitmap.

I believe there is a way to use the last solution in the BOB code, but I've
never played with that stuff.  It sure would be nice if Commodore would add
regions to the graphics library; they are REALLY handy for a number of things
(hint for 1.4 ;^)

	BradCh

rap@ez.ardent.com (Rob Peck) (06/22/89)

In article <7110@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
>In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
>>
>>Given an irregularly shaped object on a Screen, how can one tell if
>>the mouse button has been pressed inside of it?  I don't want a box all
>>around or inside it; I want the object and exactly the object.  
>
>You were on the right track with the BOBs idea in the first place.  Although
.... more deleted...

I had this same thought, but it was pointed out to me that starting with
1.2, and documented in the 1.2 enhancer docs (though I dont have em here),
there is supposed to be something extra attached to a gadget structure
that is the equivalent of the object collision mask in Bobs.  In other
words, since 1.2, masked gadgets HAVE been available.  I have not tried
it, nor have I actually looked at the documentation, but I have seen this
facility used in an actual product, on a map of Italy, "to boot". (grin)

Look it up, perhaps in intuition/intuition.h under the Gadget structure
description, or find the 1.2 enhancer docs.  "They" tell me it is
there.  (There's that wonderful "they" again).

Rob Peck

dillon@HERMES.BERKELEY.EDU (Matt Dillon) (06/23/89)

:Mike Schwager	<schwager@a.cs.uiuc.edu> Writes:
:Hope someone can help with this C question:
:
:Given an irregularly shaped object on a Screen, how can one tell if
:the mouse button has been pressed inside of it?  I don't want a box all
:around or inside it; I want the object and exactly the object.  Here's
:why I ask: I'm going to be drawing a map on the screen (into a Backdrop
:window of a workbenchscreen) and I want to be able to select individual
:...
:I was looking at info about gadgets, but I didn't find them handy cuz
:the active part is a box.  I don't like the way collision detection is
:...
:Also- the countries will be bordered, if that helps.  Maybe I need to
:define my countries by a series of borders, and see if the mouse click
:falls inside a border.

	This is more an algorithmic question.  As has been said, Intuition
does not handle irregularly shaped objects as gadgets and even if it did
one would probably *not* want to implement your map as such.

	This is, in fact, a perfect application for a QUAD-TREE to handle
in terms of identifying the country under the mouse when you hit a button.
Once identified, you can highlight the country according to its borders
which I assume have been extracted somehow from the bitmap (?? else how 
would you know the dimensions, eh?).  The QUAD-TREE would terminate when
a particular quad contains one or zero countries.

				---

	What is a quad tree?  Very simply put it is like a binary 
subdivision only in two dimensions instead of one.

#define NEETO_ASCII_GRAPHICS_ON

	0000000011110000
	0000000011110000
	0000000011110000
	0000000011110000
	1000000011111111
	0000000011111111
	0000000011111111
	0000000011111111
	0000000000000000
	0000000000000000
	0000000000000000
	0000000000000000
	0000000000000000
	0000000000000000
	0000000000000000
	0000000000000000

	Lets say you want to represent the above bitmap as a quad tree.  First
of all, note that the bounds are a power of two high and wide... this makes
the quad tree extremely simple to generate.  

	You take the square and split it up into four subsquares.  If a 
given subsquare is all 0's or all 1's you mark it as such and do not recurse.
If a given subsquare is a mix you recurse (break up that subsquare into four
more subsubsquares, add infintum).

	The above example would be represented as:

#define AWESOME_AI_GENERATED_GRAPH_USING_NEETO_ASCII_GRAPHICS_ON

	Quadrant:
		21
		34
	

		|(1) ZEROS
		|(2) ONES
	|(1)----|(3) ONES
	|	|(4) ONES
	|	|
	|	|
	|	|(1) ZEROS
ROOT----|(2)----|(2) ZEROS	|(1) ZEROS
	|	|		|		|(1) ZEROS
	|	|(3)------------|(2)------------|(2) ONES
	|	|		|		|(3) ZEROS
	|	|		|(3) ZEROS	|(4) ZEROS
	|	|(4) ZEROS	|(4) ZEROS
	|
	|(3) ZEROS
	|(4) ZEROS
	

	If you use the quad tree to only identify the country the coordinate
resides in, it would be quite small (with complexity only at the borders),
and identification would be extremely fast.  For example, you could stream
line it by simplifying quads containing a single country + ocean to identify
the entire quad with the country.

					-Matt

shf@well.UUCP (Stuart H. Ferguson) (06/23/89)

+-- rap@ez.ardent.com (Rob Peck) writes:
| In article <7110@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
| >In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
| >>Given an irregularly shaped object on a Screen, how can one tell if
| >>the mouse button has been pressed inside of it?  I don't want a box all
| >>around or inside it; I want the object and exactly the object.  
| 
| I had this same thought, but it was pointed out to me that starting with
| 1.2, and documented in the 1.2 enhancer docs (though I dont have em here),

I do.  To coin a phrase: "It's in there!"  Check out section 4.6.2 --
Masked Gadgets.  To summarize, there's a "BoolInfo" structure that
hangs off the SpecialInfo pointer in a boolean gadget.  This struct
points in turn to an Intuition "Image" struct that defines your mask
region.

The refreshing and highlighting don't honor the mask, it seems, so these
gadgets should probably be "quiet" and let you do your own highlighting.
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC

schwager@m.cs.uiuc.edu (06/24/89)

Thanks, one and all for all the responses!  I'll let you know what I
come up with, once I peruse the 1.2 docs and ruminate about what I'm
trying to do.  The quadtree example looks really interesting... have
they given Matt Dillon god status yet? :-)

-Mike Schwager				schwager@a.cs.uiuc.edu
-- {uunet,convex,pur-ee}!uiucdcs!schwager   schwager%uiuc@csnet-relay.arpa
	University of Illinois, Dept. of Computer Science

pds@quintus.UUCP (Peter Schachte) (06/24/89)

If you have enough memory to give each state/country/region/whatever a
different pixel value, the simplest, fastest way to do what you want is
to just check the pixel value of the pixel that was clicked on.  This
will tell you which state/country/region/whatever was selected.

A simple variation on this idea is to divide up your picture into a few
rectangular areas in each of which each color only appears in a single
state/country/region/whatever.  Then you can determine the
state/country/region/whatever from the area and color.  For example, you
might divide up a map of the US into 16 equal-sized parts so that each
part contains only one state with each of your, say, 8 pixel values.
I'm not sure if this is possible with a US map, but I'm sure you could
do it with 16 pixel values.  Anyway, you take the top 2 bits of the X
and Y component of the position selected, plus the 3 (or 4) bits of
pixel value for the selected pixel, and use that as an index into a
table of state names/numbers/whatever.

The beauty of the first approach, when it works, is that you can do
color table hacking to highlight the selected state.  Fast!

Hey, it may not be useful all that often but it sure is fast and easy
when it works!

-- 
-Peter Schachte
pds@quintus.uucp
...!sun!quintus!pds

bryan@geo-works.UUCP (Bryan Ford) (06/26/89)

In article <7007@ardent.UUCP>, rap@ez.ardent.com (Rob Peck) writes:
>I had this same thought, but it was pointed out to me that starting with
>1.2, and documented in the 1.2 enhancer docs (though I dont have em here),
>there is supposed to be something extra attached to a gadget structure
>that is the equivalent of the object collision mask in Bobs.  In other
>words, since 1.2, masked gadgets HAVE been available.  I have not tried
>it, nor have I actually looked at the documentation, but I have seen this
>facility used in an actual product, on a map of Italy, "to boot". (grin)
>
>Look it up, perhaps in intuition/intuition.h under the Gadget structure
>description, or find the 1.2 enhancer docs.  "They" tell me it is
>there.  (There's that wonderful "they" again).

Indeed.  I've tried it, and it works great.  (Rounded button gadgets look
REALLY nice when done this way.) Unfortunately, I've seen very few programs
that use it.  Pity, since it makes things look very nice, and it's not very
hard at all.

In the 1.2 Enhancer manual, a description of this feature is on page 60,
and a partial example is on page 76.  This is the only place I can find
that describes it very well.

Good luck!

				Bryan
--

     ____________________________________________
   _/ Bryan Ford - bryan@geo-works.geo-works.com \_
 _/    ..!utah-cs!caeco!i-core!geo-works!bryan     \_
/   ..!uunet!iconsys!caeco!i-core!geo-works!bryan    \

doug@xdos.UUCP (Doug Merritt) (06/26/89)

In article <42700016@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
>
>trying to do.  The quadtree example looks really interesting... have
>they given Matt Dillon god status yet? :-)

No, just Saint. He doesn't glow in the dark or create talking burning
bushes or anything yet.

BTW he was one of the most cheerful people at DevCon, was sociable
and amiable the whole time. So if he does get Elevated, odds
are good that he'll be a Benevolent God.

You may be interested to know that tithing is required of those who
ask if he's a god. :-)
	Doug
-- 
Doug Merritt		{pyramid,apple}!xdos!doug
Member, Crusaders for a Better Tomorrow		Professional Wildeyed Visionary

jimm@amiga.UUCP (Jim Mackraz) (06/28/89)

In article <6124@microsoft.UUCP> bradch@microsoft.UUCP (Bradford Christian ms1) writes:
)Easy solution (hack):
)
)	Make each country a color different than it's neighbors using basic
)	topology rules.  [ ... ]

It follows trivially that four colors suffice for this, so you can
do it in hires without usurping chip bus bandwidth.

;^)

	jimm
-- 
Jim Mackraz, I and I Computing	   	"He's hidden now, but you can see
{cbmvax,well,oliveb}!amiga!jimm          The bubbles where he breathes."
							- Shriekback
Opinions are my own.  Comments are not to be taken as Commodore official policy.

new@udel.EDU (Darren New) (06/29/89)

In article <4007@amiga.UUCP> jimm@cloyd.UUCP (Jim Mackraz) writes:
>It follows trivially that four colors suffice for this, so you can
	    ^^^^^^^^^ 
Really?  The four-color proof for flat surfaces is trivial?
	     That's certainly news to me!

:-) :-) :-) (-: (-: (-:     Darren

nsw@cbnewsm.ATT.COM (Neil Weinstock) (06/29/89)

In article <1205.AA1205@geo-works> bryan@geo-works.UUCP (Bryan Ford) writes:
>In article <7007@ardent.UUCP>, rap@ez.ardent.com (Rob Peck) writes:
[ stuff about gadget masks in 1.2 Enhancer docs deleted ]
>Indeed.  I've tried it, and it works great.  (Rounded button gadgets look
>REALLY nice when done this way.) Unfortunately, I've seen very few programs
>that use it.  Pity, since it makes things look very nice, and it's not very
>hard at all.

Indeed.  Maybe it's purely a matter of aesthetics, but I find rounded button
gadgets to be darn near infinitely nicer than square gadgets, and one of the
things that makes M*c screens look better than analogous Amiga or Atari
screens.  True, square buttons can be made very nice, as in MandelVroom

Round those gadget boxes!

>In the 1.2 Enhancer manual, a description of this feature is on page 60,
>and a partial example is on page 76.  This is the only place I can find
>that describes it very well.

One would presume that the new RKM's would include such a description as well?

 /.- -- .. --. .- .-. ..- .-.. . ... .- -- .. --. .- .-. ..- .-.. . ...\
/ Neil Weinstock | att!cord!nsw     | "One man's garbage is another     \
\ AT&T Bell Labs | nsw@cord.att.com | man's prune danish." - Harv Laser /
 \.- -- .. --. .- .-. ..- .-.. . ... .- -- .. --. .- .-. ..- .-.. . .../

pds@quintus.UUCP (Peter Schachte) (06/29/89)

In article <6124@microsoft.UUCP> bradch@microsoft.UUCP (Bradford Christian ms1) writes:
->In article <42700015@m.cs.uiuc.edu> schwager@m.cs.uiuc.edu writes:
->>Given an irregularly shaped object on a Screen, how can one tell if
->>the mouse button has been pressed inside of it?
->	Make each country a color different than it's neighbors using basic
->	topology rules.  ...  I repeat: this is a hack and will only
->	work under ideal conditions.  For example, if you label the countries,
->	the user would have to be careful not to click on the label (it would
->	be the wrong color).

There is a simple solution to that flaw:  allocate an extra plane for
the label, and set all pixel values with this bit on to the same label
color.  Then when you go to determine which country was clicked, get the
pixel value for that spot, and mask off that plane.  For example,
allocate 4 planes, and set pixel values 0-7 to nice, distinct colors,
and pixel values 8-15 to black (or whatever color you want labels in).
Then if you draw France in, say, color 3, draw the label "France" in color
11, which, anded with 7, gives you 3.

My earlier posting suggested a way to support more countries than you
have colors by dividing up your area into a grid, where each color only
appears once in each grid cell.

This may be a hack, but it's simplicity and efficiency make it a good
choice for many situations.

-- 
-Peter Schachte
pds@quintus.uucp
...!sun!quintus!pds

kevin@cbmvax.UUCP (Kevin Klop) (06/29/89)

In article <18678@louie.udel.EDU> new@udel.EDU (Darren New) writes:
>Really?  The four-color proof for flat surfaces is trivial?
>	     That's certainly news to me!


:^)  It's trivial NOW - someone's already done it.  Until then it
was monumental.  :^)

                -- Kevin --

Kevin Klop		{uunet|rutgers|amiga}!cbmvax!kevin
Commodore-Amiga, Inc.

The number, 111-111-1111 has been changed.  The new number is:
134-253-2452-243556-678893-3567875645434-4456789432576-385972

Disclaimer: _I_ don't know what I said, much less my employer.

451061@UOTTAWA.BITNET (Valentin Pepelea) (06/30/89)

In article <18678@louie.udel.EDU> new@udel.EDU (Darren New) writes:

> Really?  The four-color proof for flat surfaces is trivial?
> That's certainly news to me!

Oh yes, the four-color proof is surprisingly simple. The only problem is that
you need to run a Cray for 3 months to test out all the combinations/exceptions
possible.

Valentin
_________________________________________________________________________
The godess of democracy? "The           Name:   Valentin Pepelea
tyrants may distroy a statue,           Phonet: (613) 231-7476
but they cannot kill a god."            Bitnet: 451061@Uottawa.bitnet
                                        Usenet: Use cunyvm.cuny.edu gate
                   - Confucius          Planet: 451061@acadvm1.UOttawa.CA

riley@batcomputer.tn.cornell.edu (Daniel S. Riley) (07/06/89)

[I'm catching up on old articles.  Just when you thought they were dead...]

In article <18678@louie.udel.EDU> new@udel.EDU (Darren New) writes:
>Really?  The four-color proof for flat surfaces is trivial?
>	     That's certainly news to me!

Well, it's been done.  However, it really isn't very useful for the problem
at hand.  Most geographical maps are *not* maps in the mathematical sense.
For instance, you can't color a map of the US with four colors.

-Dan Riley (riley@tcgould.tn.cornell.edu, cornell!batcomputer!riley)
-Wilson Lab, Cornell U.

chuckh@hpindwa.HP.COM (Chuck Hacala) (07/07/89)

>                  ...  However, it really isn't very useful for the problem
> at hand.  Most geographical maps are *not* maps in the mathematical sense.
> For instance, you can't color a map of the US with four colors.
>
> -Dan Riley (riley@tcgould.tn.cornell.edu, cornell!batcomputer!riley)
> -Wilson Lab, Cornell U.

Why not?  I'm sure I've seen maps of the US with only four colors.  What makes
a US map not a map in the mathematical sense?  The four-color theorem has
always been one of my favorites, and it required the use of a computer to 
prove it.  I believe they reduced the theorem down to a finite, but large,
number of cases which were then checked individually by a computer.  Perhaps it
was even an Amiga!  :-)

riley@batcomputer.tn.cornell.edu (Daniel S. Riley) (07/07/89)

In article <36590001@hpindwa.HP.COM> chuckh@hpindwa.HP.COM (Chuck Hacala) writes:
>>                  ...  However, it really isn't very useful for the problem
>> at hand.  Most geographical maps are *not* maps in the mathematical sense.
>> For instance, you can't color a map of the US with four colors.
>Why not?  I'm sure I've seen maps of the US with only four colors.  What makes
>a US map not a map in the mathematical sense?

I should have been more careful in that statement.  On further reflection,
I'm not positive that you can't color the US with four colors.  What I
should have said is that the four color theorem doesn't apply to a map of
the US.  One reason is Michigan, which is non-contiguous.  In the case of
Michigan, you can get around the problem by including part of the Great
Lakes in the state.  In general, though, it's fairly easy to construct maps
which obviously require more than four colors if you are allowed to use
non-contiguous regions.  I believe there are other reasons why the four
color theorem doesn't apply to a map of the US, but I should probably go
reference hunting before making any more rash statements.

Since this discussion has wandered off of Amiga's, I'm redirecting
followups to sci.math.

-Dan Riley (riley@tcgould.tn.cornell.edu, cornell!batcomputer!riley)
-Wilson Lab, Cornell U.

p.s.  Gratuitous Amiga content:  VLT V4.036 (the version on the latest Fish
disks) does indeed have some scrolling problems.  I just was bit for the
first time while editting this message.