Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (426)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (466)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Drawing images  (Read 2072 times)
0 Members and 1 Guest are viewing this topic.
Offline mati

Senior Newbie





« Posted 2011-04-01 17:58:41 »

Is it possible to draw an image with double precision? Im using a drawImage method, but it only takes integer coordinates.
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #1 - Posted 2011-04-01 18:04:18 »

Think about it like this: would it make sense to draw in between pixels?
Sometimes, it might look like a line is drawn between two pixels, however that is done using Anti-Aliasing.

You would then have to round:
1  
g.drawImage(image,(int)Math.round(x),(int)Math.round(y),null);

Offline pjt33
« Reply #2 - Posted 2011-04-01 18:05:16 »

Yes, using Graphics2D and a suitable transform. But in general things run faster and look better if you render at an integer position.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mati

Senior Newbie





« Reply #3 - Posted 2011-04-01 18:34:47 »

I have a rectangle2d moving on the screen with double precision using vectors and I want to draw an image on top of the rectangle. When the rectangle is moving the image just does not stay on top of it all the time because its drawn with double precision and the image with integer.
Offline Zushii

Senior Newbie





« Reply #4 - Posted 2011-04-01 18:45:47 »

Well its technically impossible to draw with so-called double precission. Because you can't split pixels.

What you are experiencing ist that the "double precision" values are being rounded.
So if the rectangle x is : 0.5 and the x of the img is 0.

the rectangle will be placed at 1 and the img at 0.

Could you maybe post the code where you draw the rectangle and the image?
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #5 - Posted 2011-04-01 21:10:03 »

No need for code. Zushii is right, Rectangle2D.Double is basically rounded to the nearest integer and drawn there because there are no fractional pixels. Tongue

Offline pjt33
« Reply #6 - Posted 2011-04-01 22:15:21 »

No need for code. Zushii is right, Rectangle2D.Double is basically rounded to the nearest integer and drawn there because there are no fractional pixels. Tongue
I think that depends on rendering hints wrt anti-aliasing.
Offline ra4king

JGO Kernel


Medals: 322
Projects: 2
Exp: 4 years


I'm the King!


« Reply #7 - Posted 2011-04-02 04:28:51 »

No need for code. Zushii is right, Rectangle2D.Double is basically rounded to the nearest integer and drawn there because there are no fractional pixels. Tongue
I think that depends on rendering hints wrt anti-aliasing.
Yes, if anti-aliasing is turned on, then it may seem as if the lines are drawn between 2 pixels when it actually just spreads it over both in some specific way that tricks your eye into thinking it is smooth.

Offline mati

Senior Newbie





« Reply #8 - Posted 2011-04-05 15:36:19 »

Hello again. I use this code to draw a rectangle and then a 32x32 image on top of it. The problem is that when x and y change the coordinates of the rectangle and image are not always rounded to the same number, sometimes the image is 1 pixel further than the rectangle. When I round the x and y before this code they are drawn in the same position, but I can't do that, I have to create the rectangle giving it the x and y in double precision.

1  
2  
3  
4  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);
g2d.drawImage(boxTexture, (int)Math.round(100 + x), (int)Math.round(250 + y), null);



I also tried this code but again I got the same result:

1  
2  
3  
g2d.setPaint(new TexturePaint(boxTexture, new Rectangle.Double(100 + x, 250 + y, boxTexture.getWidth(), boxTexture.getHeight())));
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);


Any ideas how to fix that?  :/
Offline SimonH
« Reply #9 - Posted 2011-04-05 16:26:56 »

Don't use Math.round(). I think the AWT just casts doubles to ints: (1.9 => 1), but you're using Math.round: (1.9 => 2) - so there's your extra pixel!

People make games and games make people
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mati

Senior Newbie





« Reply #10 - Posted 2011-04-05 16:37:12 »

I tried it without using Math.round() and it didn't help. This code doesn't even use Math.round() but it still causes the same problem. Image and rectangle coordinates don't match Sad

1  
2  
3  
g2d.setPaint(new TexturePaint(boxTexture, new Rectangle.Double(100 + x, 250 + y, boxTexture.getWidth(), boxTexture.getHeight())));
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);
Offline SimonH
« Reply #11 - Posted 2011-04-05 16:44:35 »

You're using Math.round() to draw your image;
1  
g2d.drawImage(boxTexture, (int)Math.round(100 + x), (int)Math.round(250 + y), null);
try it without;
1  
g2d.drawImage(boxTexture, (int)(100 + x), (int)(250 + y), null);

People make games and games make people
Offline mati

Senior Newbie





« Reply #12 - Posted 2011-04-05 16:49:02 »

You're using Math.round() to draw your image;
1  
g2d.drawImage(boxTexture, (int)Math.round(100 + x), (int)Math.round(250 + y), null);
try it without;
1  
g2d.drawImage(boxTexture, (int)(100 + x), (int)(250 + y), null);


Yes I tried that, didn't solve the problem. But then have a look at the second code which uses TexturePaint. It doesn't use Math.round() so I think it must be something else...
Offline SimonH
« Reply #13 - Posted 2011-04-05 16:55:26 »

Ok, plan B. try;
1  
2  
3  
4  
5  
6  
7  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);

AffineTransform at=new AffineTransform();
at.translate(100+x,250+y);
g2d.drawImage(boxTexture,at,null);

People make games and games make people
Offline mati

Senior Newbie





« Reply #14 - Posted 2011-04-05 17:02:56 »

Ok, plan B. try;
1  
2  
3  
4  
5  
6  
7  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);

AffineTransform at=new AffineTransform();
at.translate(100+x,250+y);
g2d.drawImage(boxTexture,at,null);


Nope, the result is the same. I am hoping someone's gonna give me plan c
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #15 - Posted 2011-04-05 17:20:21 »

1  
2  
3  
4  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);
g2d.drawImage(boxTexture, (int)Math.round(100 + x), (int)Math.round(250 + y), null);


planC

instead of g2d.fill(f)
could you try
g2d.fillrect(f.x, f.y, f.width, f.height);

It may require you to cast (int)  and use the same method as you do for your drawImage

either just leave "both (int)  with no round", or both "drawimage and fillrect with (int)math.round"


plan D

1  
2  
3  
4  
5  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);

g2d.fillrect((int)f.x, (int)f.y, f.width, f.height);
g2d.drawImage(boxTexture, (int)f.x, (int)f.y, null);


This should allow both the filled rect and image to be the same pixel locations
While maintaining the rectangles double precision(for collision detection or other "high resolution/ sub pixel accuracy"



edit:
Could I inquire to why you need both an image and a filled red rectangle occupying the same location?  Will the image or red rect not just obstruct the other from sight?
Because although I'd like to continue to help you solve your problem the method you'd like to. Perhaps there is another underlying better solution to the whole thing?


"Experience is what you get when you did not get what you wanted"
Offline Abuse

JGO Coder


Medals: 10


falling into the abyss of reality


« Reply #16 - Posted 2011-04-05 17:50:52 »

As primitives use antialiasing for sub-pixel accuracy, and images use interpolation for sub-pixel accuracy I fear you are asking for the impossible.

However, the difference might not be noticable - and it'll certainly make an animated image moving through floating point coordinates appear smoother.

So, set the necessary rendering hint for sub-pixel interpolation (RenderingHints.KEY_INTERPOLATION, to either VALUE_INTERPOLATION_BICUBIC or VALUE_INTERPOLATION_BILINEAR) and then use SimonH's 'plan B' of using an AffineTransform to supply the drawing coordinates in floating point form.

I don't know what the state of hardware acceleration is for the various interpolation & antialiasing rendering hints, so if performance is a concern you might want to rethink your strategy.
Such a rethink might involve moving away from Java2D entirely.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline mati

Senior Newbie





« Reply #17 - Posted 2011-04-05 18:35:38 »

1  
2  
3  
4  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);
g2d.fill(f);
g2d.drawImage(boxTexture, (int)Math.round(100 + x), (int)Math.round(250 + y), null);


planC

instead of g2d.fill(f)
could you try
g2d.fillrect(f.x, f.y, f.width, f.height);

It may require you to cast (int)  and use the same method as you do for your drawImage

either just leave "both (int)  with no round", or both "drawimage and fillrect with (int)math.round"


plan D

1  
2  
3  
4  
5  
g2d.setPaint(Color.red);
Rectangle2D f = new Rectangle2D.Double(100 + x, 250 + y, 32, 32);

g2d.fillrect((int)f.x, (int)f.y, f.width, f.height);
g2d.drawImage(boxTexture, (int)f.x, (int)f.y, null);


This should allow both the filled rect and image to be the same pixel locations
While maintaining the rectangles double precision(for collision detection or other "high resolution/ sub pixel accuracy"



edit:
Could I inquire to why you need both an image and a filled red rectangle occupying the same location?  Will the image or red rect not just obstruct the other from sight?
Because although I'd like to continue to help you solve your problem the method you'd like to. Perhaps there is another underlying better solution to the whole thing?



This is working just fine. The rectangle and image now are drawn at the same x and y pixel location. I use I high precision collision detection so the drawback of this approach is that a collision is detected before the two rectangles touch (there is one pixel gap between them or one box is 1 pixel on top of the other because double precision coordinates for collision detection are used). But this is not very noticeble and it solves my problem. The image doesn't move from left to right anymore (when the rectangle was moving fast it seemed like the image was shaking).

Yes, the image will obstruct the rectangle and the reason it was painted in red is just for debugging... Smiley
Thank you!
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #18 - Posted 2011-04-05 19:09:20 »

No problem, Hope it was what you wanted!
I hope to see a demo of your game at some point!


"Experience is what you get when you did not get what you wanted"
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (72 views)
2014-04-15 18:08:23

BurntPizza (68 views)
2014-04-15 03:46:01

UprightPath (79 views)
2014-04-14 17:39:50

UprightPath (65 views)
2014-04-14 17:35:47

Porlus (80 views)
2014-04-14 15:48:38

tom_mai78101 (104 views)
2014-04-10 04:04:31

BurntPizza (164 views)
2014-04-08 23:06:04

tom_mai78101 (260 views)
2014-04-05 13:34:39

trollwarrior1 (210 views)
2014-04-04 12:06:45

CJLetsGame (220 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!