• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Finding the color of a pixel

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is my first post to these forums, so forgive me if this post is in the wrong forum.I wasn't sure if this question falls under intermediate or advanced, but I have done searches in all three skill levels for Java, as well as the Applet forum. The few threads I found were not applicable to my situation.

What I am trying to do is draw an object on the screen in an empty spot. By empty, I mean that no other oebject or text has been drawn there. To do this, I am currently trying to use nested for loops to cycle through every pixel in the applet window (hard coded to be 800x600, or 480,000 pixels). What I am having trouble doing is actually determining the color value of the pixel at that location, however. The ColorModel.getRGB(int pixel) looks promising, but I can't figure out how that pixel gets defined and used. Since it is not a point object, I don't know how the integer value of the pixel passed to that method gets translated from an x/y coordinate.

I have also tried casting a point object (using the given x/y coordinates) to a color object, or a ColorModel object, so that I could use their getRGB() method, but with no success.

If anyone has any suggestions or code samples, or just classes to look at, let me know. I have read through every class in the javadocs that seems even remotely related to color, pixel, point, and UI, and haven't found what I am looking for yet.

Also, if there is an easier way to go about accomplishing my higher goal (finding a clear space with a given width and height, to be determined at runtime), please let me know. All my ideas thus far are about as efficient as using recursion to display the fibonaci sequence, but it is the best I've come up with.

Thanks,

Mike
[ June 09, 2005: Message edited by: Mike Winters ]
 
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is the java.awt.Robot.getPixelColor(int x, int y). It returns a Color object. I'm not sure how it will work in an applet though.

Rather than trying to detect where an empty space is it might be easier, and less expensive, to hold all the drawn objects and redraw from scratch on each 'frame', if that is close to what you are doing. Then you would determine what is empty by keeping track of where you have drawn.
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Steven Bell:
There is the java.awt.Robot.getPixelColor(int x, int y). It returns a Color object. I'm not sure how it will work in an applet though.

Rather than trying to detect where an empty space is it might be easier, and less expensive, to hold all the drawn objects and redraw from scratch on each 'frame', if that is close to what you are doing. Then you would determine what is empty by keeping track of where you have drawn.



I'm not quite sure how to implement that class. I get the following error: "Unhandled exception type AWTException" when creating a new Robot object with no arguments, and I'm not sure how to create it with an argument (how do I pass the applet window as a GraphicsDevice?). That looks like it should do what I want, however. If I can figure it out.

To answer your question, I think that what you suggest may be well beyond my skill level. I am not doing any kind of animation or anything, so redrawing shouldn't be necessary. The goal of the project is simply to accept a series of numbers from the user, and draw a series of shapes of various kinds that do not overlap. I figured that by comparing the pixel color to the background color (which I just noticed is different from the appletviewer to the actual applet in a page), I could find the blank spaces.

I started with drawing the new objects in areas I knew were clear, but that quickly became difficult and time consuming to do, since the objects could be of any size and in any location.

I'm very new to java, so I might be overlooking something obvious.

Thanks,

Mike

Edit: fixed a typo
[ June 09, 2005: Message edited by: Mike Winters ]
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Give me an example of the input and output.

Does the user say 'draw 5 circles and 8 squares' and then you draw them? I'm pretty sure it will be easier to calculate this all before drawing, as well as faster.
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The user enters four integers. The first and second become the origin point for a rectangle. The third and fourth are the width and height, respectively. From that point, the ones digit of the smallest number entered is then calculated, and that many ovals are drawn (so up to 9 possible) using the width and height from before. The objective is to make sure none of the objects overlap. Currently, my code works as long as the user enters numbers smaller than 150 for each integer, but as the origin and the size get larger, I have to start writing more and more complex code to ensure I am drawing to clear space. I figured that writing a routine to scan the applet window for clear space based on the background color would be easier in the long run. I was going to use white, as that is the background color of the aplet window, but in a browser, the window is gray, so now I am not sure.

Thanks,

Mike
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm guessing this is some homework assignment?

A couple things I'm assuming from your response.

1) All ovals have the same height and width of the rectangle.
2) An oval may not be drawn inside the rectangle as the lines would touch.

First off there are inputs which make solving the puzzle impossible, something to think about. Second given the parameters in most cases the ovals can/will occupy the same space as if they were rectangles. It will only be as space gets tight that it may be worthwhile to place ovals in positions where the 'corners' would overlap.

You should be able to use a 'greedy' algorithm to make this work. That is what looks best at the current time, just do, and assume the later ones will take care of themselves.

So what I would do might look something like this.

Create some class that will keep track of used space and for allocating space for the next object. It could look something like this. (I'm just putting the method signatures)


As you already seem to understand the screen is basically a 2D array of pixels. You can simulate that inside the SpaceAllocator with a 2D array of booleans (on/off) or something similar. If you used this it would go something like:

-Get the input from the user.
-Check for out of bounds.
-call placeShape to place the rectangle.
-call allocateShape once for each oval.
-if and exception is thrown report to the user it is impossible.
-call drawShapes with the Graphics context from the applets paint method.
(forgive if I'm a bit off on the Graphics in the applet bit, been awhile)

The placeShape and draw shapes are fairly self explanitory.

The allocateShape could do something like this:

-Start at the top left of your 2D array and look for an opening.
-Each time you find one check if the new shape will fit.
-Once you find a place you would actually create a shape with the correct location and store it.
-Flip the locations on the 2D array to used (either true or false, true might be easier as false is the default)

The algorithm used to see if a shape will fit and the algorithm used to flip the 2D array will determine how effective the program will be. To begin with I would simply get the bounding rect of each shape and use that to see if a shape will fit. On the flip I would flip all 'points' within the bounding rect (a fill, not just the outline).
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I thought about doing that as well, having a two dimensional array of size [height][width], but I would essentially be doing the same operation either way, which is to find a blank spot, and then check "width" pixels to the right and "height" pixels down for open spaces. If I cannot find the color of a pixel at that location (which it seems is just outside my grasp), I will resort to the array method. It won't be any faster in terms of number of calculations (although the actual calculations performed might be quicker, since it will be comparing a bool value and not a color value). The only extra problem I can see right now is that I would have to be sure that I fill the array correctly whenever a new object is drawn.

Ideally, I would still prefer to go the (what seems to be) more direct route and just checkk the pixel color, but if that is not possible, the array method should be nearly identical to implement, with the exception of the fill that I mentioned above.

Thanks,

Mike

Edit: And yes, this is a homework assignment, so don't give me the answers . Just looking for a shove in the right direction.
[ June 09, 2005: Message edited by: Mike Winters ]
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I've decided to go with the two dimensional array route, but for some reason, the method that is supposed to be filling a section of the array (whenever an object is drawn) SEEMS to be filling the entire array. I say seems to because Eclipse is not showing me the values of the relevant variables in debug mode (it says the field is not visible).

Would it be ok to post the relevant sections of code here (or in a new, more appropriately named thread perhaps?) and see if you can figure out why the fill method does not terminate when it should (if that is indeed the error, as I believe it to be)?

Thanks,

Mike
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Posting code and asking for help with it is just fine. Just be sure to put the code in code tags (there is a button below the posting area).
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, here is the code for my applet. I'm beginning to think that the problem lies in the possibility that the paint method runs continuously, but I haven't been able to determine if that is truly the case yet.


Some of my debug code is still there, but can be disregarded.

Thanks,

Mike

Edit: removed some excessively long lines of code to prevent side scrolling.
[ June 09, 2005: Message edited by: Mike Winters ]
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First thing I notice is that you have alot of code in your paint method. The only thing in the should be:



Where rectange is a Rectange and ovals is a Ellipse2D[]

Also how are you getting the input from the user?
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure how I would remove some of that code from the paint method, or what (if any) advantages it would have. Calling an external method from within paint would still call it, and the paint method is not very long.

Also, I am getting the four integers using JOptionPane's showInputDialog, then parsing them to integer.

Thanks,

Mike
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I figured out the logic error from before, but I am still encountering a small problem that I just can't figure out.

Some of the ovals are overlapping either each other, or the rectangle that is drawn earlier. I've pasted the relevant sections of code below:



The fillScreenArray method is called from paint immediately after an object is drawn, like this:



I'd be more than happy to email or post the entire code to anyone who is willing to take a look at it and help me find whatever it is that I am overlooking. The objects only overlap under certain conditions, but as far as I can tell, the code should check to make sure the space is clear under ALL conditions, which is why I can't figure out why this is happening.

Thanks,

Mike

Edit: removed a debug line to prevent side scrolling
[ June 14, 2005: Message edited by: Mike Winters ]
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would make this small change. It's hard to find bugs with nests like these
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Surprisingly enough, that one small change of relocating the assignment seems to have fixed the overlap problem I was having.

I still can't see a logic error with the code as it was, although I agree that the method you sugeested is cleaner.

Thanks for your help,

Mike

Edit: typo (is there a spellcheck feature on these forums? I don't see one)
[ June 16, 2005: Message edited by: Mike Winters ]
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I couldn't actually see the bug there, but code like


inside of a loop just screams possible bug. You should try to keep your flags going only one way as best as possible.

And no, I don't think there is a spellcheck.
 
Mike Winters
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, I'll start doing that from now on.

On a side note- I'm having trouble figuring out how to actually draw some shapes from the java.awt.geom package (namely Ellipse2D.Float, but they are all the same implementation it seems).

I've created and defined the object, but I can't figure out how to actually draw it. I've looked in all the superclasses or Ellipse2D, as well as applet, paint, and graphics, and haven't seen a method that can accept a shape object as a parameter to be drawn.



Thanks,

Mike
 
Steven Bell
Ranch Hand
Posts: 1071
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is a draw(Shape) method in the Graphics2D object (all Graphics objects can be safely cast to Graphics2D). I'm not sure just how that works. You may have to use the drawOval method of Graphics.
reply
    Bookmark Topic Watch Topic
  • New Topic