Everything seemed so plain and simple until I had to actually program it.
What I've got
I uploaded an image to explain it better.
I have a circle and I know
it's radius
center point coordinates
each button's initial coordinates (the red circles).
I want to be able, when I rotate the gray circle image, with 10 degrees, to calculate red buttons new coordinates (x1y1, x2y2).
This shouldn't be hard to achieve for someone who knows math, but I didn't manage to find a suitable solution. I've also searched around here and couldn't find a working solution. Any help is greatly appreciated.
Thank you
The working solution, as Felice stated below is:
-first take care of rotation angle, on each redraw simply increment it
angle = angle+mainRotationAngle;
float x = (float) (center.X + Math.cos(angle*Math.PI / 180F) * radius
float y = (float) (center.Y + Math.sin(angle*Math.PI / 180F) * radius
button.setX(x);
button.setY(y);
It is easyer if you keep with you the button initial angles, then modify the angle to produce the rotation. so in pseudocode:
newAngle = Angle+rot;
xbutton = center.x+cos(newAngle)*radius;
ybutton = center.y+sin(newAngle)*radius;
If you really just have the coordinates of the buttons, you can convert them to the angle by using the function atan2, in pseudocode:
buttonAngle = atan2(button.y-center.y,button.x-center.x);
x1 = x + r sin 10
y1 = y + r cos 10
x2 = x - r sin 10
y2 = y - r cos 10
Related
Can anyone explain to me what is the cause of this behavior?
The problem is that, from "off" to "2" always shows perfectly, above the radius I gave.
Radius is +35 than the circle's radius.
Now when I write digits, as it goes down, it starts to mess up.
And in terms of alphabets, it touches the edge and overlaps it.
can anyone tell me the reason for this? because radius is always more than the current circle's radius so the alphabets should appear similarly like "off".
computation of xy points...
// Angles are in radians.
val startAngle = Math.PI * (9 / 8.0)
val angle = startAngle + pos.ordinal * (Math.PI / 4)
x = (radius * cos(angle)).toFloat() + width / 2
y = (radius * sin(angle)).toFloat() + height / 2
I played around with the degrees and it seems like the closer to 0 degree starts to mess up, as the degrees increase, it keeps adding more space in radius.
Illustrated here... I would like to what what is causing this behavior, or just explain the reason/ math behind it. thanks
From the comments it looks like you are following this code lab code https://github.com/google-developer-training/android-advanced/tree/master/CustomFanController
You just need to take into account text ascent and decent. So draw the numbers on the circumference of the circle
val yPos = (pointPosition.y - (paint.descent() + paint.ascent()) / 2).toInt()
canvas.drawText(label, pointPosition.x, yPos.toFloat(), paint)
The above is based on Android Center text on canvas
This does draw the text at the correct place, but if the text is too large it does overlap
I have a virtual ruler being drawn on the screen. I want to be able to draw a straight line like the blue line above when touch event happen within the grown rectangle. but because touch can't be 100% straight, the movement might be like the red line. that's why I set a rectangle to listen to all the nearby touch events then draw a blue line.
I currently have
mRulerRect.set(mRulerCenter.x - mRulerBitmap.getWidth() / 2,
mRulerCenter.y - mRulerBitmap.getHeight()),
mRulerCenter.x + mRulerBitmap.getWidth() / 2,
mRulerCenter.y);
mPath.addRect(mRulerRect, Path.Direction.CCW);
mRulerMatrix.setRotate(mRulerAngle, mRulerCenter.x, mRulerCenter.y);
mPath.transform(mRulerMatrix);
mRegions.setPath(mPath, new Region(mRulerRect));
then I check if the touch even happen within brown rectangle by mRegions.contains(x,y). works perfect so far for touch detection, but the problem I have now is how to draw a straight line. I tried to fix X point then calculate Y. it works fine when ruler is horizontal then starts to behave very weird when turning from horizontal to vertical. I'm out of idea how to accomplish this. Please help! thank you.
Things that you know:
The center of that brown rect is mRulerCenter.x, mRulerCenter.y
The line that you want to draw pass through that point
The angle of the line is mRulerAngle
We're missing just one element, which is, the length of the line we want to draw. That's probably going to be a portion of the ruler's width and it should be very easy to compute mRulerRect.width() * someFactor
Now, we want to know what are the start and the end of the line, we can compute that with trigonometry functions
float halfLineLength = mRulerRect.width() * someFactor;
float startAngle = (float) Math.toRadians(mRulerAngle);
float endAngle = (float) Math.toRadians(mRulerAngle + 180);
float startX = mRulerCenter.x + (float) Math.cos(startAngle) * halfLineLength;
float startY = mRulerCenter.y + (float) Math.sin(startAngle) * halfLineLength;
float endX = mRulerCenter.x + (float) Math.cos(endAngle) * halfLineLength;
float endY = mRulerCenter.y + (float) Math.sin(endAngle) * halfLineLength;
and then draw your line from (startX, startY) to (endX, endY), actually doesn't really matter which is start and which is end
I'd like to calculate two points that align with the real horizon (presuming the user is holding the device virtually). I'd like the line connecting those 2 points to pass through a center point of my choosing.
I'm collecting Sensor.TYPE_ACCELEROMETER and Sensor.TYPE_MAGNETIC_FIELD vectors and have found sample code to rotate bitmaps with rotationmatrix but can't get my mind around calculating just the 2 points I need in terms of the screen's X and Y.
Any hints greatly appreciated!
If I understood everything right, that should be an easy trigonometric question.
You should find the angle to horizon and then It will look like this
X1 = 0
Y1 = Yc + Xc * tan(a)
X2 = screenWidth
Y2 = Yc - (screenWidth - Xc) * tan(a)
i want to calculate how many pixels there are between 2 points on my screen.
I've seen that i can draw a straight line between 2 points using Path class, but i don't really want to draw that line, i only want to know how long is it in pixels..
i really need it for my MapView clusters implementation..
i can get each marker position on screen with no problem, but don't know how to calculate pixel's "distance" between them ...
i know that there are cluster's implementations available but i want to try and create one of my own
help will be appreciated :)
This is very straightforward using a bit of algebra :)
Take the co-ordinates of both points and calculate the difference between their x and y values e.g.
dx = p1.x - p2.x;
dy = p1.y - p2.y;
distance = Math.sqrt( (dx * dx) + (dy * dy) );
Where p1 and p2 are the points you want get find the distance between, and distance is the result. It will be a double but you can round it to the nearest int if you wish
If my X co-ordinates increment every time a frame is drawn, what formula can I employ from the math library in order to have the Y co-ordinate moving around the circumference of a circle frame by frame, creating the illusion of an orbiting object around a continuously moving central point?
I have seen it may involve sin or cos but am not sure how to adjust the variables accordingly per frame.
Many thanks for your help
You can't make a complete circle if your X coordinate increments every time, because half the time your X coordinate has to be decrementing.
What you want is polar coordinates: theta for angle and r for radius. Your r will remain constant, and your theta will increment continuously. Then your x and y are:
x = r * cos(theta)
y = r * sin(theta)
let ox,oy be the origin of your circle, and px,py be a point on the edge of the circle, with a radius of r
given: (px-ox)^2 + (py-oy)^2 = r^2 definition of circle
solve for py:
(py-oy)^2 = r^2 - (px-ox)^2
(py-oy) = sqrt(r^2 - (px-ox)^2)
py = sqrt(r^2 - (px-ox)^2) + oy <---
So as you increment px with your frames, you can find the appropriate py by recalculating the above formula.