Java - Move image to old coordinates after rotating - java

After I saw this Website here I tried to use it as good as I could. I want to rotate my image by 90 degrees and have it at the same position as before the rotation. I tried it like this:
int xold = charX;
int yold = charY;
charX = 0;
charY = 0;
//g.drawImage(man, charX, charY, man.getWidth(), Man.getHeight(), null); -> I have tried it with and without this line.
g.rotate(Math.toRadians(90)); //After I moved the picture to (0, 0) I rotate it by 90°.
charX = xold; //After this I move the (rotated) picture to the old place
charY = yold;
g.drawImage(man, charX, charY, man.getWidth(), man.getHeight(), null); //And finally I print int using my Graphics2D object
Well something must be wrong. If I now execute this code, the picture just dissapears and finally returns in its old state.
Does somebody get the mistake?

Related

Issues with coordinates

I'm working on something that involves clicking specific points on a buffered image in a JPanel. I had issues with this earlier in the project (affine transform translation not working properly), but nothing I found fixed it so I decided I would come back to it later.
I'm not entirely sure how to trouble shoot it since I'm a novice, but I think it's reading my y coordinates too low. I made a mouse input listener that tracks the number of times the user has clicked and gets the mouse pointer's location for functions I haven't made yet. For testing I have it output the coordinates and number of clicks then make a circle centered where the mouse clicks.
#Override
public void mouseClicked(MouseEvent e) {
Point mouseCursor = MouseInfo.getPointerInfo().getLocation();
panel.drawCenteredCircle(mouseCursor.getX(), mouseCursor.getY(), 100);
System.out.println(String.valueOf(mouseCursor));
System.out.println(String.valueOf(clickCount));
clickCount++;
}
Here is drawCenteredCircle in my custom panel class:
public void drawCenteredCircle(double x, double y, int r) {
imgG2 = image.createGraphics();
imgG2.setPaint(Color.RED);
x = (x-r/2.0);
y = (y-r/2.0);
imgG2.fillOval((int)Math.round(x), (int)Math.round(y), r, r);
this.repaint();
imgG2.dispose();
}
I tried taking a screenshot to show what happens, but the circle properly centers on the x coordinate, but not the y coordinate. Instead it draws the circle with the pointer at the top center edge.
I overrided the paintComponent of my JPanel to implement a zoom feature:
#Override
protected void paintComponent(Graphics g) {
//Implimenting zoom
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g.create();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
/*Supposed to counter the movement from the scale, not working properly
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double x = (w - scale * imageWidth)/2;
double y = (h - scale * imageHeight)/2;*/
AffineTransform at = new AffineTransform()/*.getTranslateInstance(x, y) */;
at.scale(scale, scale);
g2.drawRenderedImage(image, at);
//g2.dispose(); I was told to put this, but I'm not sure if it's necessary or what it does entirely
}
My confused notes are because I got this code from an example someone made and, as I said earlier, the affine translation wasn't working (I took the actual translation out). They're irrelevant to the question.
The reason I put this is because I initially had code that was meant to fit the image to the screen/frame depending if it was fullscreen or not:
int x = image.getWidth();
int y = image.getHeight();
double frameW = frame.getBounds().getWidth();
double frameH = frame.getBounds().getHeight();
//Rectangle winSize = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
double screenW = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
double screenH = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
if (!isFullScreen) {
if (x/y > frameW/frameH) {
scale = frameW/x;
} else {
scale = frameH/y;
}
} else {
if (x/y > screenW/screenH) {
scale = screenW/x;
} else {
scale = screenH/y;
}
}
It uses my zoom function which scales the image with the double "scale." I noticed that when I zoomed in or out, it would change where the dots would appear relative to the pointer. It wasn't until I removed the code for the image to start fitted to the window and had it start at 100% that I received the result of the pointer being at the top center of the circle.
I also tried removing the part that's supposed to center the circle and the result was the pointer being on the left side and having a gap between it and the top of the circle.
Sorry if this is too much stuff. I'm pretty novice and learned just as much about java (the only coding language I know) working on this project as I knew when I first started it. I'm not sure what information I have that could be helpful in this, so I just threw in everything I thought could help. I appreciate any help, even irrelevant to my question.

Issue drawing using graphics Java

I am trying to draw an Oval with a for loop iterating through a list of coordinates that each contain an x value and y value. Currently, it does not seem to be drawing anything after I start the program. It draws the first time, but when I try drawing when the program is running, it doesn't seem to be drawing.
Here is the code for drawing:
private void render(){
bs = display.getCanvas().getBufferStrategy();
if(bs == null){
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
//Draw Here!
DrawGrid(g);
g.fillOval(100, 100, 10, 10);//this seems to draw
for(int i = 0; i < points.size();i++){//this doesn't draw....
System.out.println(points.get(i));
g.drawString(points.get(i).toString(), points.get(i).x*100-5+100, points.get(i).y-5-300);
g.fillOval(points.get(i).x*100-5+100, points.get(i).y-5-300, 10, 10);
}
//End Drawing!
bs.show();
g.dispose();
}
If you need more details, I am using graphics from java.awt library. Also, I have done this in the past, but I don't know why it isn't working this time.
This part is your issue:
points.get(i).x*100-5+100
Specifically x*100
You are drawing off screen. We can see this by breaking it down:
Lets assume that you have a point of x=28.
Lets do the math on that:
For X = 28 you will have the following calc: (28 * 100) - (5 + 100) = 2695
That X point of 2695 looks very large to me. You would need a 4k screen or ultrawide screen to see it.
The solution:
Have a think about why you are using x*100, and reduce it so that the point fits on your screen. Also, if you have a small y point, then it will be in the negatives (Example: 15-5-300 = -290), and will probably draw above your screen and out of sight.

Android camera2.params.face rectangle placement on canvas

I'm trying to implement face detection in my camera preview. I followed the Android reference pages to implement a custom camera preview in a TextureView, placed in a FrameLayout. Also in this FrameLayout is a SurfaceView with a clear background (overlapping the camera preview). My app draws the Rect that is recognized by the first CaptureResult.STATISTICS_FACES face's bounds dynamically to the SurfaceView's canvas, every time the camera preview is updated (once per frame). My app assumes only one face will need to be recognized.
My issue arises when I draw the rectangle. I get the rectangle in the correct place if I keep my face in the center of the camera view, but when I move my head upward the rectangle moves to the right, and when I move my head to the right, the rectangle moves down. It's as if the canvas needs to be rotated by -90, but this doesn't work for me (Explained below code).
in my activity's onCreate():
//face recognition
rectangleView = (SurfaceView) findViewById(R.id.rectangleView);
rectangleView.setZOrderOnTop(true);
rectangleView.getHolder().setFormat(
PixelFormat.TRANSPARENT); //remove black background from view
purplePaint = new Paint();
purplePaint.setColor(Color.rgb(175,0,255));
purplePaint.setStyle(Paint.Style.STROKE);
in TextureView.SurfaceTextureListener.onSurfaceTextureAvailable()(in the try{} block that encapsulates camera.open() :
Rect cameraBounds = cameraCharacteristics.get(
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
cameraWidth = cameraBounds.right;
cameraHeight = cameraBounds.bottom;
in the same listener within onSurfaceTextureUpdated() :
if (detectedFace != null && rectangleFace.height() > 0) {
Canvas currentCanvas = rectangleView.getHolder().lockCanvas();
if (currentCanvas != null) {
currentCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
int canvasWidth = currentCanvas.getWidth();
int canvasHeight = currentCanvas.getHeight();
int l = rectangleFace.right;
int t = rectangleFace.bottom;
int r = rectangleFace.left;
int b = rectangleFace.top;
int left = (canvasWidth*l)/cameraWidth;
int top = (canvasHeight*t)/cameraHeight;
int right = (canvasWidth*r)/cameraWidth;
int bottom = (canvasHeight*b)/cameraHeight;
currentCanvas.drawRect(left, top, right, bottom, purplePaint);
}
rectangleView.getHolder().unlockCanvasAndPost(currentCanvas);
}
method onCaptureCompleted in CameraCaptureSession.CameraCallback called by CameraCaptureSession.setRepeatingRequest() looper:
//May need better face recognition sdk or api
Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
if (faces.length > 0)
{
detectedFace = faces[0];
rectangleFace = detectedFace.getBounds();
}
All variables are instantiated outside of the functions.
In case you can't quite understand my question or need additional information, a similar question is posted here:
How can i handle the rotation issue with Preview & FaceDetection
However, unlike the above poster, I couldn't even get my canvas to show the rectangle after rotating my canvas, so that can't be the solution.
I tried to rotate my points by -90 degrees using x=-y, y=x (left=-top, top=left), and it doesn't do the trick either. I feel like some kind of function needs to be applied to the points but I don't know how to go about it.
Any ideas on how to fix this?
For future reference, this is the solution I ended up with:
set a class/Activity variable called orientation_offset :
orientation_offset = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
This is the angle that the camera sensor's view (or rectangle for face detection) needs to be rotated to be viewed correctly.
Then, I changed onSurfaceTextureUpdated() :
Canvas currentCanvas = rectangleView.getHolder().lockCanvas();
if (currentCanvas != null) {
currentCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
if (detectedFace != null && rectangleFace.height() > 0) {
int canvasWidth = currentCanvas.getWidth();
int canvasHeight = currentCanvas.getHeight();
int faceWidthOffset = rectangleFace.width()/8;
int faceHeightOffset = rectangleFace.height()/8;
currentCanvas.save();
currentCanvas.rotate(360 - orientation_offset, canvasWidth / 2,
canvasHeight / 2);
int l = rectangleFace.right;
int t = rectangleFace.bottom;
int r = rectangleFace.left;
int b = rectangleFace.top;
int left = (canvasWidth - (canvasWidth*l)/cameraWidth)-(faceWidthOffset);
int top = (canvasHeight*t)/cameraHeight - (faceHeightOffset);
int right = (canvasWidth - (canvasWidth*r)/cameraWidth) + (faceWidthOffset);
int bottom = (canvasHeight*b)/cameraHeight + (faceHeightOffset);
currentCanvas.drawRect(left, top, right, bottom, purplePaint);
currentCanvas.restore();
}
}
rectangleView.getHolder().unlockCanvasAndPost(currentCanvas);
I'll leave the question open in case somebody else has a solution to offer.

Can't detect collision properly

i am writing a game using Libgdx and i need to detect when the user touches a sprite.
I tried to do so with this following code:
this code set the rect's position
for(int i = 0;i<circlesArray.length;i++)
{
rect[i] = new Rectangle(circles.getPosition(i).x,circles.getPosition(i).y,height/8,height/8);
}
and this code set the click as rectangle and checks if it overlaps the sprite
if(Gdx.input.isTouched())
{
click = new Rectangle(Gdx.input.getX(),Gdx.input.getY(),Gdx.input.getX(),Gdx.input.getY());
if(Intersector.overlaps(click,rect[1]));
{
System.out.println("clicked");
x[1] = 0;
}
}
From some reason that i cant understand the program detects a collision even when it is not happened, when i tap anywhere on the screen it says that i pressed the sprite.
What should i do to fix it?
This is your issue:
click = new Rectangle(Gdx.input.getX(), Gdx.input.getY(), Gdx.input.getX(), Gdx.input.getY());
Should be:
click = new Rectangle(Gdx.input.getX(), Gdx.input.getY(), 1, 1);
The last two parameters of a Rectangle are width and height. Here we give the rectangle a width and a height of 1 pixel but you can set it to whatever you like. You were setting those parameters as the inputs x and y which are different every time giving you varying results.
Edit:
To translate the input coordinates to your game world's coordinates based on the camera you have to do this:
Vector3 clickPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(clickPos);
click = new Rectangle(clickPos.x, clickPos.y, 1, 1);
When you use camera.unproject(Vector) it translates your inputs coordinates to work based off of where your camera is positioned in the game world. So now we're using a vector clickPos.
The reason we use a Vector3 is because this is what is required by the unproject function. We supply this vector with the inputs x and y but give it a 0 for the third parameter z since this is a 2d world.

Processing -- moving image leaving trail

I'm working on trying to make an image move in processing, but the image is leaving a trail. The important part which is tripping me up is that I cannot declare the background in draw(), because I have other functions which place images. Here is the relevant code:
void setup()
{
size(752,500);
background = loadImage("prairie.jpg");
background(background);
noStroke();
animal = loadImage("squirrel.png");
bird = loadImage("bird.gif");
rock = loadImage("rock.png");
cloud = loadImage("cloud.png");
jeep = loadImage("jeep.png");
flower = loadImage("flower.png");
}
float jeepX = 752;
float jeepY = 250;
float size = 100;
void draw()
{
image(jeep,150,350,125,125);
image(jeep,jeepX,jeepY,size,size);
jeepX--;
jeepY = jeepY + .25;
size += .25;
image(jeep,jeepX + 1,jeepY - .25, size -.25, size - .25, 0,0,0,0);
if(jeepY > height)
{
jeepX = 752;
jeepY = 250;
size = 100;
}
}
This is for lab and the TA didn't know how, and I didn't have a chance to ask the professor yet.
If no one knows the answer and/or it has something to do with other functions (which place images), i'll post the relevant code.
For moving objects not to leave a trail, you must first clear the frame before redrawing the picture.(don't forget to reset the background if you don't have one)
As it is, it draws one jeep, then another on top of it.
If you don't want the trail, you got clear the background. If not completely, at least part of it, or redraw every image not supposed to move every frame.
Like this:
Sample Code
PImage bg, still, moving;
void setup() {
while ( bg == null) {// got wait as size depends on this...
println("loading bg image...");
bg = loadImage("http://dc489.4shared.com/img/f9EaWk5w/s3/13757197c08/Black_Background_Metal_Hole_-_.jpg");
}
size(bg.width, bg.height);
still = loadImage("http://www.renderosity.com/mod/bcs/photos/Thumb85619.jpg");
moving = loadImage("https://cdn1.iconfinder.com/data/icons/humano2/128x128/apps/alienblaster.png");
}
void draw() {
background(bg);
image(still, 100, 100);
image(moving, 200, frameCount%height);
}
You need to redraw your background in the 'draw' method. To do this, simply add the following line of code to your 'draw' method:
background(red,green,blue);
You can use the Colour Selector in Processing (found under Tools) to find the correct rgb code for the colour you want.
The reason for this is that the draw method is run 60 times a second, whereas the 'setup' method is only run once when the program is executed. As such, when you move the image, if the background colour is not in the 'draw' method, then it will not be redrawn when the image is moved, thus leaving a trail.

Categories

Resources