I got an extended JLabel class where I draw my Map using the code below :
the new AffineTransform() is the identity to left my image as it is (0,0,w,h)
mygraphics2D = (Graphics2D) getGraphics();
graphics2D.scale(2.0,2.0) ;
graphics2D.rotate(....
graphics2D.drawImage(myImageIcon.getImage(),new AffineTransform(), this);
now when I click on my JLabel using this event :
public void mouseClicked(MouseEvent e) {
x =e.getX() ;
y = e.getY();
NewX = ????
NewY = ????
}
I want to retrieve my new coordinates "the scaled,rotated ... coords" I tried
Point2D ptSrc = new Point2D.Double(x, y);
Point2D ptDst = new Point2D.Double(0, 0);
mygraphics2D.getTransform().transform(ptSrc, ptDst);
but the ptDst is different from the (scaled,rotated,..) coordinates, any help please !!!
It sounds like you need both a forward and inverse transform to translate between the two co-ordinate systems. In this example, the scaling equations are explicit; in this alternate approach, a second AffineTransform is used.
Its not so hard ;-)
When you repaint the Component save the AffineTransform after the transforming with g2.getTransform()
Then call the function invert() on it
In the mouseClicked() event us the following code:
Point2D p= trans.transform(new Point2D.Double(evt.getX(), evt.getY()), null);
System.out.println("click x="+p.getX()+" y="+p.getY());
Thats it!
I found these:
http://www.javalobby.org/java/forums/t19387.html
http://www.java.net/node/685054
Don't know if they will help or not.
Related
i am working in a game like Geometry dash on java , i got all of the mechanics like , wave , ball , ufo , ship.... anyway i am trying to achieve the effect of the square rotating when it jumps like the original game y try to do this using affineTransform but it doesnt work like the original game
i use this code to rotate , but looks weird
public void rotate(){
tx.rotate(Math.toDegrees(degrees),width/2,width/2);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
}
here is a capture of my game looking right now
here is a link of geometry dash were you can see how the square rotate in middle air(what i am trying to do)
got any ideas? please help me :c
hmmm, I would actually use an AffineTransform but in another way...
if you have the two functions
public void tick()
{
}
public void render(Graphics g)
{
}
I would do something like:
AffineTransform at;
rotation = 0;
public Player()
{
at = AffineTransform.getTranslateInstance(x, y);
}
public void tick()
{
at = AffineTransform.getTranslateInstance(x, y);
if(isInAir)
{
rotation++;
at.rotate(Math.toRadians(rotation), width / 2, height / 2);
}
else
{
rotation = 0;
}
}
public void render(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(sprite, at, null);
}
I know it's not that practical, always creating another AffineTransform but it worked for me. Another way to do it in the render method, not using any AffineTransform would be:
Graphics2D g2d = (Graphics2D) g;
g2d.rotate(Math.toRadians(rotation));
g.drawImage(sprite, x, y, null);
g2d.rotate(Math.toRadians(-rotation));
I'm not quite sure if you would need Math.toRadians here, but if not just delete it.
Hope I could help!
I have a point with [x, y] coordinate, for example
Point p = new Point(1, 2). I want to visualize it. However, I want this point to an oval, like in the picture below.
How can I do that using java Swing?
Determine the size of the oval you want, for example 10 px. Then draw the oval with the x and y points starting at the Point (x and y), minus half the size. Something like:
public class PointsPanel extends JPanel {
List<Point> points = new ArrayList<Point>();
int size = 10;
...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point p : points) {
int x = p.x - size/2;
int y = p.y - size/2;
g.drawOval(x, y, size, size);
}
}
}
For more general details on painting, see Performing Custom Painting. Also see the Graphics API for other drawXxx and fillXxx methods.
From the image you posted, what you need is a graph layout library like JUNG(not sure about current status of this project). You can follow peeskillet's answer but need to take care of problems like overlapping ovals etc.
I make a game and when I animate entity with low velocity I use g.FILL(new Ellipse2D.Float(x, y, r, r)); because it renders smooth and fluent motion.
It work fine (in Example blue left circle). But when I needed just an outline of circle I used g.DRAW(new Ellipse2D.Float(x, y, w, h)); and it didn't work and I absolutely don't know what's wrong. No fluent motion, circle jumps pixel over pixel and it looks ugly (in Example red right circle). Graphics2D.draw(Shape) count float values like int values.
This Example code demonstrate it, don't study it a lot, just import, run and watch.
public class Example extends JFrame {
public static void main(String[] args) { new Example(); }
public Example() {
setBounds(50, 50, 400, 400);
setVisible(true);
while(true) {
x1 += 0.01;
y1 += 0.01;
x2 -= 0.01;
y2 += 0.01;
try {
Thread.sleep(16);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
double x1 = 50 , y1 = 50;
double x2 = 250, y2 = 50;
#Override
public void paint(Graphics gg) {
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.BLUE);
g.fill(new Ellipse2D.Double(x1, y1, 100, 100));
g.setColor(Color.RED);
g.draw(new Ellipse2D.Double(x2, y2, 100, 100));
}
}
So how can I fix it without tricks like filling two cirle or moving image of circle? Thanks for every answer.
I would guess the problem is that you didn't invoke super.paint(...) as the first statement in the method which means you lose some of the default painting functionality.
However, that is NOT the proper solution as you should NOT be overriding the paint() method of a JFrame at all. Custom painting is done by overriding the `paintComponent(...) method of a JPanel and then you add the panel to the frame. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
Also, don't use a while true loop for animation. Instead you should be using a Swing Timer to schedule the animation (the tutorial has a section on Swing Timers). Your code only works because you are NOT creating the GUI correctly. The GUI should be created on the Event Dispatch Thread. The Custom Painting tutorial shows you how to use the invokeLater(...) method to do this. The tutorial also has a section on Concurrency in Swing which explains this concept in more detail.
With drawing circles/ovals/ellipses in Java, the "pure" mode often helps drawing it with subpixel accuracy:
g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE)
My other answer has more details: https://stackoverflow.com/a/31221395/1143274
I m making desktop app in java swing. i made 3D image from my 2D image using PointArray[]. now i want to rotate image using MouseListener and MouseMotionListener.I used MouseRotate object to rotate myImage, but it not works well for that, MouseRotate rotate image with origin(0,0,0). but i want to rotate image using center point of image. means rotate image using center point not origin point. So, How can i do that?
Hmm, it's hard to tell without code, but I think you can just set up a transformation matrix and rotate it with that. Assuming the image is facing the front of the screen, you can try something like this:
public void mouseDragged(MouseEvent e)
{
int dx = e.getX() - x; //x should be a global variable
int dy = e.getY() - y; //same applies here
x = e.getX(); //to set x for the next update loop
y = e.getY();
double rotation = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
Transform3D transform = new Transform3D();
Matrix3d matrix = new Matrix3d();
transformG.getTransform(transform); //assuming the TransformGroup your image is in is transformG
transform.getRotationScale(matrix);
transform.rotZ(rotation);
transformG.setTransform(transform);
}
You can set up the rotation amount differently if you want, but this should give you an idea
I have a strange behaviour when drawing a Path2D on a JPanel.
Some of the shapes get kind of a tail as you can see on this screenshot:
When I change the type to Line2D.Double, it is as I'd expect it:
Here's the code that draws the path / line:
Path2D.Double path = new Path2D.Double();
Graphics2D g = (Graphics2D)this.getGraphics();
for(int i=0; i<geom.size(); i++)
{
double x = ddGeom.getX(geom.get(i));
double y = ddGeom.getY(geom.get(i));
if(i==0)
path.moveTo(x-draw_center.x, y-draw_center.y);
path.lineTo(x-draw_center.x, y-draw_center.y);
}
g.draw(path);
Do you have an idea where the 'tails' in Screenshot1 come from? I use SDK Version 6.
Thank you very much for your help
Edit: When changing the code snippet to
if(i==0)
path.moveTo(x-draw_center.x, y-draw_center.y);
else
path.lineTo(x-draw_center.x, y-draw_center.y);
most (maybe 75%) of the tails disappear. Any idea why this happens?
I finally got it. Thanks to HovercraftFullOfEels hint 'strange Stroke' I played around with my strokes.
Original stroke:
BasicStroke stroke = new BasicStroke(2.0f);
Changed to:
BasicStroke stroke = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL);
With the new Stroke all the 'tails' disappeared. I'm still not understanding why this happens, but if someone has the same problem, this workaround could help.
I'd still be very interested in an explanation for this behaviour.
Thank you for your great help
What you are seeing in your first image looks almost like ''miters''. Miters are a way to draw line joins in a path where the two outer borders of the lines that are joined are extended until they intersect and the enclosing area is filled as well.
Is it possible that your geometry contains consecutive points with almost the same coordinates? The following example exhibits the same problem because of the last two points with have almost identical coordinates.
JFrame frame = new JFrame();
frame.setSize(300, 300);
frame.setContentPane(new Container() {
#Override
public void paint(Graphics graphics) {
Graphics2D g2 = (Graphics2D) graphics;
g2.setStroke(new BasicStroke(5));
g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
g2.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE);
Path2D.Double path = new Path2D.Double();
path.moveTo(200, 100);
path.lineTo(100, 100);
path.lineTo(101, 100.3);
g2.draw(path);
}
});
frame.setVisible(true);