Android: Rotate image by dragging a specific part of it - android

I have this ImageView:
I need to be able to rotate the whole image (The circle and the two "30" circles)
when I drag the outside circles around. It should rotate only if I start dragging from the outside "30" circles
They should all rotate around the dot in the center.
I managed to make this image rotate when I drag it in any part of it using a View.OnTouchListener and by calculating the angle between the touch event coordinates and the pivot point, and then rotate the imageView.
How can I detect when the motion event is in the outer circles only, to prevent the image from rotating when dragging inside the big circle?

In OnTouchListener's onTouchEvent method, you can utilize the ACTION_DOWN event to check, if a TouchEvent starts inside the little outer circles. If this is true, set a boolean to true. In the ACTION_MOVE event, you just have to check the boolean and only rotate if it is set to true. Then, use ACTION_UP and ACTION_CANCEL to set the boolean to false again.
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
boolean rightPosition = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// When the event is in the little circles rightPosition=true
break;
case MotionEvent.ACTION_MOVE:
if(rightPosition) yourRotationCode();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
rightPosition = false;
}
return false;
}
How do you know, if the drag starts in the little circles?
Tl;dr: Keep track of the polar coordinates of the little circles and compare them with the ACTION_DOWN event's coordinates.
To determine, if the ACTION_DOWN event occurs inside the little circles, keep track of the angle, your ImageView is rotated from it's 'zero position'. In the beginning, the little circles are at 45° and 125°. Offset them against the current rotation of your ImageView, get the angle between 12 o'clock and the ACTION_DOWN event and compare them. Also take into account the distance between the point of rotation and the event. As you already calculate the needed rotation, I think you know how to determine these angles.
The right distance from the point of rotation should be calculated from the ImageView's height and width, so you remain density independent. This needs some pixel counting and calculating the ratio, based on the original image resource, done by hand. This ratio can then be hard coded to a constant value.
As the position of an TouchEvent is precise to one pixel, you should add some offset around the calculated center of the little circles. I would recommend a square around the little circle. Its side length has again to be calculated in aspect to the ImageView's height and width. Again you can determine the ratio of your 'valid area' to the size of the ImageView by hand and provide it as a constant. Then you just have to check if the starting point's coordinates are within +/-(side length / 2) of the center of the little circles.

Related

Resize a circle in android when User Moves touchscreen

I'm trying to draw a resizable Circle in android with user Touch events.
I need that when user touch the scree, the circle will be drawn, then if he moves the finger outter of its center the circle will be go bigger and vice versa, how can i do that??
Also, he is like redrawing the circle, that's because in the ACTION_MOVE there is this sentence that says:
canvas.drawCircle(...)
But how can i work with the starting circle and make it bigger or smaller??
I have already tried a lot of things(for like 6 hours) and I don't know what else to try, this is my current code:
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
cacheCanvas.drawCircle(event.getX(),event.getY(),50,paint);
pX= event.getX();
pY = event.getY();
circleDiam = (event.getX()+event.getY())/2;
break;
case MotionEvent.ACTION_MOVE:
cacheCanvas.drawCircle(event.getX(),event.getY(),(event.getX()+event.getY())/2,paint);
break;
case MotionEvent.ACTION_UP:
break;
}
invalidate();
return true;
}
This is the result i got:
http://i.stack.imgur.com/J0y7s.png
Very thanks in advance!
You want to use a SurfaceView to draw the circle and then
listen to the touch events on the surface view.
http://developer.android.com/reference/android/view/SurfaceView.html
There are some very good examples of using surface views available online
if you google for them.
If you only have a couple of sizes and you want to go cheesy on it you could define drawables and swap them in as the user drags. This would not be graceful or smooth.

In Android, OpenGL, I want to draw a circle dynamically using motion event with centre as midpoint of device screen, but not getting desired output

The following is the code that I used to draw a circle by getting the touch position from the screen and calculating the radius from the origin to the touch point and passing to the renderer to draw the circle.
public boolean onTouchEvent(MotionEvent e) {
float ex=0, ey=0;
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
ex = (e.getX()/(getWidth()/2))-1;
ey = 1-(e.getY()/(getHeight()/2));
dist = (float) (Math.sqrt(Math.pow(ex, 2)+Math.pow(ey, 2)));
}
mRenderer.radius = dist;
requestRender();
return true;
}
But I am getting the circle drawn at a radius lesser compared to the touch point I give for radius. i.e. the output doesn't coincide with the touch event. I want to know is there any Touch Scale Factor for arriving the touch posistion and how to employ it in the code ?
That's because you need to consider the projection and view matrices,as 5agado pointed out.
You can use Ray Picking for that: it basically consists in tracing a Ray from the touched point in the screen to your scene. In your case, you need to compute the intersection point of this Ray with your drawing surface.
You can take a look at this and that

Android: MotionEvent's x and y pixel do not translate to image coordinates

I am using the getX() and getY() functions in MotionEvent to get the x and y positions of where the user touched the screen. I am also capturing images using the android camera. These images are 480x640. My intention is to use have the user draw a box and the get the start and end x,y positions and use them to create a box and crop the image.
Unfortunately, even if the user boxes the correct area using the android screen (which shows video from the camera), the coordinates from MotionEvent do not relate at all to the correct location on the image. Sometimes the x,y coordinates I get from the MotionEvent are actually more than 480 or 640.
Are the dimensions of the android screen different than the image's? Or do the x,y positions from MotionEvent correspond to something else
The coordinates returned depend on the pointer being used but in general are in screen coordinates, so to get the coordinates relative from the view you need to offset by the views position.
See:
http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_X
For offset of the view use:
https://developer.android.com/reference/android/view/View.html#getLeft()
https://developer.android.com/reference/android/view/View.html#getTop()

How to achieve tilt effect on Android like on Windows Phone?

I want to achieve a tilt effect when a button is clicked, on Android OS.
Tilt Effect: Not the whole button will be seen as pressed. Only the part that touch event occured should seem to be pressed.
Is this easily possible on Android?
A simple way would be to use canvas draws to draw 4 sided shapes.
Consider each 4 corners. The "untouched" rectangle would be full size the touched rectangle would be smaller.
You just need to draw your four sided shape using a point you calculate for each part of the rectangle. You can get the touch position, then figure out how much "weight" to give each point.
to calculate each corner, you need to figure out how much "weight" to give the touched coordinate, and how much "weight" to give the untouched coordinate. If you touch the top left corner, that corner would use 100% of the touched coordinate, and the other three corners would all use the untouched coordinate.
If you touched the top middle, you would get a shape like this:
We can calculate the corners for any touch spot, by calculating how far from the corner your touch is
float untouchedXWeight1 = Math.abs(xt - x1)/width;
//maximum of 1, minimum of 0
float untouchedYWeight1 = Math.abs(yt - y1)/height;
float untouchedWeight1 = (untouchedXWeight1 + untouchedYWeight1)/2;
//also maximum of 1, minimum of 0
float touchedWeight1 = 1 - untouchedWeight1;
so with those weights, you can calculate your x and y positions for that corner:
x1 = xUntouched1 * untouchedWeight + xTouched1 * touchedWeight1;
y1 = yUntouched1 * untouchedWeight + yTouched1 * touchedWeight1;
Then do similarly for the other 3 corners.
I've created a first draft here : https://github.com/flavienlaurent/TiltEffect
In a second step, I will make it usable with Button etc.
Unfortunatly, I didn't use the very good (but too mathematical for me) answer of HalR

Problems with touch event

Speaking of events we know that the touch screen method onTouchEvent (MotionEvent events) allows you to capture touch events on the screen and event.getX () and
event.getY () give me the coordinates of the touch as float values ​​(ie values ​​with a comma).
Specifically, I realized that taking logcat using the fixed point the finger in a mobile phone screen and not moving it, the event is not only perceived but MotionEvent.ACTION_DOWN MotionEvent.ACTION_MOVE and returned coordinates are manifold. This i can understand because the surface of the finger touches more points and more by reading the device coordinates believe that the finger moves while holding it.
My problem is that I would read the color of one pixel of a color image when I hold your finger still. In particular I need the central area occupied by the finger.
First, assuming you have a Bitmap object, I have to round to integer coordinates of the touch as the getPixel (intX, int y) coordinates of the entire Bitmap wants to return the pixel color.
Then how do I get the central point of touch? Be that there is a function that can help me? Keep in mind that while I stopped and read the value of a pixel on the image then I start to move slowly and even though I always record every move the center pixel. I need this because every move, if you change the color of the image in pixels, I want to vibrate or not the device.
If I could stop thinking about themselves in a dynamic array to store the coordinates of different pixels and search for the center of gravity, but moving I do not know what to do. I think however, that the research center of gravity, if not done very efficiently, can be slow during the move and then give the wrong results. If the CG is not quite enough for me to another point belonging to the environment.
I hope you can help me maybe with a few lines of code sketched.
Thanks in advance.
To get the touch position of finger, just cast the getX() and getY() to int and perform your desired tasks.
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN ) {
getPixelAt((int)event.getX(), (int)event.getY());
}
}
you can put you on main activity class when you can want to touch event occurs. let see you can put following code or not ? and return is most important as well.
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mDistanceX = 0;
}
return super.onTouchEvent(event);
}

Categories

Resources