I am trying to create custom components in Android using Surfaceview and canvas drawing. The components are re-sizable and rotatable by touching. Consider creating an image view its Top,Right,Bottom, and Left edges are scalable by touching and dragging the required edge. I am using RectF to keep the bounds of the component, For rotation I am using canvas.rotate(angle, bounds.centerX(),bounds.centerY()) method. The problem is while resizing top edge, the Let , Right and Bottom edges should be fixed, and I cannot able to fix it if the rotation angle is other than 0 degrees. I need a math solution to find out the x,y coordinates of a rotated rectangle with respect to the actual rectangle's bounds.
I can explain it with the help of some images.
The following Figure displays two rectangles whose bounds are also known and displayed in respective colors. Consider the Green Rect as the components initial bounds, ie. rotated by -45 Degrees, Center is (10,10). Now going to re-size the Top edge of the rectangle and displayed in next Figure 2.
From the Figure 2 it is understood that the Y position is reduced to 4 from 6. The rotated Rectangle is also shown in pink color. Remember I am doing resizing while the component is at rotation angle -45 degrees, so while dragging Top Edge rectangle's Left, Right and Bottom positions should not be changed. So the Figure 2's Pink Rectangle should have Left, Right, and Bottom coordinates same as Figure 1's Green Rectangle. Comparison of the obtained and expected rectangle is shown in Figure 3.
In Figure 3 the yellow color rectangle is the Expected/Required out put. The obtained rectangle Pink color is shifted upwards compared to the Green rotated rectangle and that is varying depends on the Angle of rotation.
I have rotation angle = -45 degree
Bounds of Actual (Not re-sized) rectangle.
Bounds of Actual (Not re-sized) rectangle at Rotation = -45 degrees.
Bounds of Re-sized rectangle.
Bounds of Re-sized rectangle at Rotation = -45 degrees.
How do I calculate the Bounds / Center of the Yellow Rectangle. So that I can implement the resizing of my components correctly? Let me know is there is any mathematics that can be applied?
The required points / coordinates are marked as Red color circles in Figure 3.
The key is this: "I cannot able to fix it if the rotation angle is other than 0 degrees."
Let's say your rectangle is rotated 10 degrees.
1) rotate the mouse coordinate around some point on the screen by -10 degrees
2) rotate the center of the rectangle by -10 degrees
... now you reduced the problem to a rectangle that is at 0 degrees. The rectangle moved, yes, the mouse moved, but they are relative to each other as they should be.
3) Now do the the rectangle manipulation. The rectangle center will shift.
4) Rotate the new rectangle center by 10 degrees
This way you do not have to think about it and you are always working in un-rotated coordinates.
Point at [x, y] rotated by angle a will end up at [x*cos(a) - y*sin(a), x*sin(a) + y*cos(a)]
All colors in this answer refer to your figure 3.
If I understood your question correctly, you know how to compute all the details about the pink rectangle as well as the green rectangle. So simply take the difference between one corner of the pink rectangle and the corresponding corner of the green rectangle. Adding that difference (a two-element vector, i.e. x and y difference separately) to the center of the pink rectangle will give you the desired center of the yellow triangle.
If you need to compute the dimensions of the pink rectangle as well, you might want to do so in the unrotated coordinate system. Take your green rectangle together with the coordinates of the point towards which you want to extend the rectangle, and rotate them back by +45°. Then you can extend the height of the rectangle to the value you desire, which will give you the blue rectangle, and from that by rotation the pink rectangle.
Related
Is it possible to have a pulsing animation, like the sonar pulsation, on a circle that I have drawn in a custom view canvas? For now I was able to have a second circle drawn at the same position and having its size changed using ObjectAnimator.
All circles are bouncing slowly on the canvas. I want to have that animatioon be applied to "BOSS" circle. Right now, I have another circle drawn behind it that is haviing its size changed from 0 to BOOS circle's size + some values.
Any help is appreciated.
I have took text on canvas applying rotation on it. Now I want to move the text horizontally but it's moving on cross. For rotation i have done something like below.
canvas.save();
canvas.rotate(-45,150,150);
canvas.drawText("Some Text", xAxis, 55, paint);
canvas.restore();
It's not moving straight because of the rotation applied to the whole canvas. Now I want this text to move horizontally straight line.
Is there any way around?
The output of the above code is like this
Right not if I increase the value of xAxis it's moving like the line red. I want it to move like line green in the picture.
In your code you rotated whole Canvas itself. Imagine you rotate your screen 45 degrees and move mouse horizontally - it will move with that rotation. You need another approach to rotate text, or you'll be needed to calculate move point depending on rotation angle (rotate point around point).
I wanted to draw a rectangle with rounded corners in OpenGL|ES.
The user will input 3 things:
Coordinates of top left corner (X1,Y1).
Coordinates of bottom right corner (X2,Y2).
radius for the roundness of the corner (r).
The approach I am currently taking is that I will draw 3 rectangles based on the input given by the user and then will draw four arcs on each of the four corners of the rectangle.
is it the right way of doing it or is there some better approach for this ?
I am currently creating an android game and implemented collision detection a while back. I am simply drawing a Rect around sprites using their position, width and height and seeing if they intersect other Rects. However, my sprites now rotate depending on their trajectory, but I cannot find how to rotate the Rect so the bound is correct. Any suggestions?
Thanks
Andy
Rect objects are usually axis-aligned, and so they only need 4 values: top, left, bottom, right.
If you want to rotate your rectangle, you'll need to convert it to eight values representing the co-ordinate of each vertex.
You can easily calculate the centre value by averaging all the x- and y-values.
Then it's just basic maths. Here's something from StackOverflow:
Rotating a point about another point (2D)
Your eight values, or four corners are (assuming counter-clockwise from the top right):
v0 : (right, top)
v1 : (left, top)
v2 : (left, bottom)
v3 : (right, bottom)
Create your own rectangle object to cope with this, and compute intersections etc.
Note that I've talked about how to rotate the rectangle's vertices. If you still want a bounding box, this is normally still considered to be axis-aligned, so you could take the max and min of the rotated vertices and construct a new (larger) rectangle. That might not be what you want though.
I'm rotating a view containing an arrow in my app using the Matrix class. However, the arrow doesn't rotate around its center but moves a bit horizontally and vertically when rotating. I've experimented with margins and padding but without success.
Any hints much appreciated.
The setRotate method in Matrix defaults to the (0,0) point of the view, which is the top left corner. You can set the point you want to rotate around by using the setRotate(float angle, float px, float py) method in the Matrix class. The x and y parameters are local to the view so you can get the center point from the bounds of the view or from getWidth and getHeight.
I think the translation works as you expect. It is the way you draw the resulting image which leads to imprecision. I have just answered a similar question Android problem with Image Rotate and Matrix