Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  Rotate Image to Face Mouse - Loss of accuracy  (Read 2520 times)
0 Members and 1 Guest are viewing this topic.
Offline ghostsoldier23

Junior Member


Medals: 1



« Posted 2011-12-25 03:14:27 »

I have following code to calculate rotation (theta) based on the mouse position and player position (player pos is always the same):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   private void calculatePlayerRotation(int x, int y) {
      double xd = x - this.x;
      double yd = y - this.y;
      if(xd == 0)
         xd = -90;
      if(yd==0)
         yd = 90;
      theta = atan2(yd,xd);
      theta = toDegrees(theta);
      theta+=180.0;  //This is because of the orientation of what is on the image.
  }


It seems, however, that when xd is negative, the image rotation is slightly off from where the mouse is.

There also seems to every now and then be some odd stuttering of the image while it rotates.

Does anyone have and idea of what might be causing this or how to improve it?

Oh and if it helps, theta is just passed to an AffineTransform which is used to draw the image.
Offline theagentd
« Reply #1 - Posted 2011-12-25 14:12:35 »

1. Math.atan2(dy, dx) handles the special cases you check for you, so you don't have to do that yourself.
2. AffineTransform uses radians, degrees.
EDIT:
3: xd and yd are not degrees. Setting them to 90 and -90 makes no sense for a special case in the first place. Just get rid of them and use Math.atan2(yd, xd);
4: I've always called differences d<name>, not <name>d. dx, dy, dz, dDistance, dAngle, e.t.c.

Myomyomyo.
Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #2 - Posted 2011-12-28 05:05:18 »

Sorry I should've specified.... the actual rotation is being done by code from an API I've made (am making) and it takes degrees.  The rotation method converts the degree input to radians.

I changed the variable names and removed the checks.  That helped but there still seems to be an accuracy problems.

Updated code:

1  
2  
3  
4  
5  
      double dx = x - this.x;
      double dy = y - this.y;
      theta = atan2(dy, dx);
      theta = toDegrees(theta);
      theta+=180.0;
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2011-12-28 05:30:37 »

How bad are the accuracy problems? could you show us a screenshot of this?

Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #4 - Posted 2011-12-28 14:57:39 »

How bad are the accuracy problems? could you show us a screenshot of this?


The white box is where the mouse was

That's about as bad as it gets.  At some points in the rotation it's fine, but then at others it looks like that.

The image had been rotated approximately 270 degrees in that shot.
Offline theagentd
« Reply #5 - Posted 2011-12-28 16:09:33 »

Print out the degree that atan2 returns.

Myomyomyo.
Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #6 - Posted 2011-12-28 18:10:06 »

Print out the degree that atan2 returns.

Around 1.5 radians
Offline theagentd
« Reply #7 - Posted 2011-12-28 19:34:01 »


For what input? -_-
0S0
Never mind, can you post the minimal code needed to show the problem? Preferably a runnable version, as my head doesn't like being javac.exe and java.exe. At least not in real-time. =S

Myomyomyo.
Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #8 - Posted 2011-12-29 05:27:04 »

If I post just the rotation and calculation code would that suffice?  There "runnable" version would require quite a bit of my source...

You could whip up your own small test app to draw a couple shapes on a component I suppose.

AffineTransform based Rotation Method (from the 2DX-GL API)
1  
2  
3  
4  
5  
6  
7  
   public static AffineTransform rotateImage(Image img, Point location, Graphics2D g2d, double degrees) {
      AffineTransform affine = new AffineTransform();
      affine.setToTranslation(location.getX(), location.getY());
      affine.rotate(Math.toRadians(degrees), img.getWidth(null)/2, img.getHeight(null)/2);
      g2d.drawImage(img, affine, null);
      return affine;
   }


Current Mouse-Image Relation Calculation Code (theta is a volatile double value being modified by separate threads)
1  
2  
3  
4  
5  
6  
7  
   private void calculatePlayerRotation(int x, int y) {
      double dx = x - this.x;
      double dy = y - this.y;
      theta = atan2(dy, dx);
      theta = toDegrees(theta);
      theta+=180.0;
   }
Offline theagentd
« Reply #9 - Posted 2011-12-29 13:12:29 »

Current Mouse-Image Relation Calculation Code (theta is a volatile double value being modified by separate threads)
1  
2  
3  
4  
5  
6  
7  
   private void calculatePlayerRotation(int x, int y) {
      double dx = x - this.x;
      double dy = y - this.y;
      theta = atan2(dy, dx);
      theta = toDegrees(theta);
      theta+=180.0;
   }

Wowowowow! Modifying theta like that is dangerous as hell, even if it is volatile! You overwrite theta on every call to calculatePlayerRotation, but the value may be overwritten by another thread in between the 3 manipulations to theta, meaning that 180 may be added to a completely different value if it was overwritten after atan2() but before theta+=180.0; You need to use a synchronized block (with a non-volatile double) or set theta with a single call so the calculation can't be modified in between the last 3 lines.

For the second solution:
1  
2  
3  
4  
5  
6  
7  
8  
   private void calculatePlayerRotation(int x, int y) {
      double dx = x - this.x;
      double dy = y - this.y;
      double th = atan2(dy, dx);
      th = toDegrees(th);
      th+=180.0;
                theta = th;
   }

This would work, but there are other solutions too.

Sadly, I doubt that this is the problem with your inaccurate angle, as the theta bug was a race condition. The code you posted looks fine otherwise, so it's hard to determine where things go wrong. It's your code, you know how it works (well, hopefully Grin), so it's easier for you to debug it yourself rather than explaining everything. Add lots of System.out.println("Variable: " + variable); to your code to make sure that variables have the right values or even better, use a debugger so you can inspect all variables while it's running. That should be enough to figure out where things are going wrong. In a wild guess, I'd suspect you treat the angle as degrees sometimes and as radians sometimes...

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #10 - Posted 2011-12-29 19:04:30 »

Adding lots of SOPs is going to get ugly, it is best to run the debugger.

Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #11 - Posted 2011-12-29 21:14:38 »

WOW!  Holy crap!  How did I not see that concurrent modification bug?

Ok patched that up...

1  
2  
3  
4  
5  
6  
      double dx = x - this.x;
      double dy = y - this.y;
      double val = atan2(dy, dx);
      val = toDegrees(val);
      val+=180.0;
      theta = val;


But like you predicted it didn't solve the issue.

Let me do some more investigating and I will post back here in a bit.
Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #12 - Posted 2011-12-29 21:24:34 »

Ok I tried putting SOPs in that showed the current value of theta both when calculating and when drawing.

The modification always went through fine and the Drawing lines ALWAYS matched their last calculation line.

I'm so confused...
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2011-12-29 21:36:29 »

Well maybe in the end your math is correct but the rendering is wrong Smiley

Online Riven
« League of Dukes »

JGO Overlord


Medals: 797
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2011-12-29 21:54:28 »

Well maybe in the end your math is correct but the rendering is wrong Smiley
Well obviously, I thought we already established that? How can atan2(dy, dx) possibly be wrong?

He's simply not rotating around the center of the image, or if he is, the image is not rotating around this.x and this.y.


Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2011-12-29 22:00:15 »

Well his drawing code looks fine so maybe it might be his picture is offcenter.

Offline ghostsoldier23

Junior Member


Medals: 1



« Reply #16 - Posted 2011-12-29 22:10:36 »

He's simply not rotating around the center of the image

Yep.  That was it.  Fixed the problem:

1  
2  
3  
4  
5  
6  
7  
   private void calculatePlayerRotation(double x, double y) {
      double dx = x - (this.x+wt/2);
      double dy = y - (this.y+ht/2);
      double val = atan2(dy, dx);
      val+=Math.PI;
      theta = val;
   }
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.

Dwinin (23 views)
2014-09-12 09:08:26

Norakomi (56 views)
2014-09-10 13:57:51

TehJavaDev (69 views)
2014-09-10 06:39:09

Tekkerue (34 views)
2014-09-09 02:24:56

mitcheeb (56 views)
2014-09-08 06:06:29

BurntPizza (40 views)
2014-09-07 01:13:42

Longarmx (25 views)
2014-09-07 01:12:14

Longarmx (31 views)
2014-09-07 01:11:22

Longarmx (31 views)
2014-09-07 01:10:19

mitcheeb (38 views)
2014-09-04 23:08:59
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!