I have this function which returns x and y position an just adding up degrees, it make objects to move around in circular movements like a satellite around a planet.
In my case it moves like an ellipse because I added +30 to dist.
-(CGPoint)circularMovement:(float)degrees moonDistance:(CGFloat)dist
{
if(degrees >=360)degrees = 0;
float x = _moon.position.x + (dist+30 + _moon.size.height/2) *cos(degrees);
float y = _moon.position.y + (dist + _moon.size.height/2) *sin(degrees);
CGPoint position= CGPointMake(x, y);
return position;
}
What I would like is to reverse this function, giving the x and y position of an object and getting back the dist value.
Is this possible?
If so, how would I go about achieving it?
If you have an origin and a target, the origin having the coordinates (x1, y1) and the target has the coordinates (x2, y2) the distance between them is found using the Pythagorean theorem.
The distance between the points is the square root of the difference between x2 and x1 plus the difference between y2 and y1.
In most languages this would look something like this:
x = x2 - x1;
y = y2 - y1;
distance = Math.SquareRoot(x * x + y * y);
Where Math is your language's math library.
float x = _moon.position.x + (dist+30 + _moon.size.height/2) *cos(degrees);
float y = _moon.position.y + (dist + _moon.size.height/2) *sin(degrees);
is the way you have originally calculated the values, so the inverse formula would be:
dist = ((y - _moon.position.y) / (sin(degrees))) - _moon.size.height/2
You could calculate it based on x as well, but there is no point, it is simpler based on y.
Related
I have two points in my coordinate system (x,y) that I want to know the angle of their line and x-axis.
I use swift for solving this but I can't get the angle.
I need this angle in radians to use it in the following equation:
(x0 + r cos theta, y0 + r sin theta)
r : radius of circle
If you have two points, (x0, y0) and (x1, y1), then the angle of the line joining them (relative to the X axis) is given by:
theta = atan2((y1 - y0), (x1 - x0))
The angle between a line, for reference, let's call this A, defined by two points p1=(x1,y1),p2=(x2, y2) and the x-axis is related to finding the slope/ gradient of the line, A.
# To solve a problem you sometimes have to simplify it and then work up to the full solution"
Let's start by obtaining the gradient of the line A.
The gradient of line A:
slope = (y2 - y1)/(x2 - x1)
for a straight line, that makes an angle theta with the x-axis
tan(theta) = slope = (change in y) / (change in x)
Therefore, theta = tan_inverse (slope)
theta = atan(slope)
I'm trying to convert Twist to the left and right wheels' speed with the formula:
float speed_wish_right = (cmd_vel.angle*WHEEL_DIST)/2 + cmd_vel.speed;
float speed_wish_left = cmd_vel.speed*2-speed_wish_right;
Twist.angular is a vector [x, y, z] and so is Twist.linear. What do x, y, z mean in the vector and how can I get angles and speed out of the two vectors?
This is my callback function in Arduino
const int WHEEL_DIST = 16;
void velCallback(geometry_msgs::Twist vel) {
float linear = vel.linear.x;
float angle = vel.angular.z;
float speed_wish_right = (angle * WHEEL_DIST) / 2 + linear;
float speed_wish_left = linear * 2 - speed_wish_right;
motors.setSpeeds(speed_wish_left, speed_wish_right);
}
Consider that you are in some space, then there are 3 axes - x, y and z which are mutually perpendicular to each other and their point of intersection is called the origin (x = 0, y = 0, z = 0). This can be a frame of reference i.e. you can define various points and directions w.r.t. them.
The x, y, and z in Twist.linear are the linear velocities in x, y and z directions w.r.t. that frame of reference.
Similarly, the x, y, and z in Twist.angular are the angular velocities about the x, y and z directions respectively w.r.t. the same frame of reference.
Since you have a ground robot, most probably your angular velocity will be in z i.e. robot's turning speed. And your linear velocity will be mostly in x i.e. robot's moving straight speed. This is the case for the Turtlebot 2 at least.
This is my method to move squares around a circle like satelites does on planets:
-(CGPoint)circularMovement:(float)degrees radius:(CGFloat)radius{
float x = (planet.position.x + planet.radius) *cos(degrees);
float y = (planet.position.y + planet.radius) *sin(degrees);
CGPoint posicion = CGPointMake(x, y);
return posicion;
}
As you can see, I get an x and y position of my satelite, and calling this method with degrees++ I got a circular movement around planets.
But my problem with this movement sistem is I need the degrees of satelite.position.x+satelite.size.width/2 to detect collisions with another object moving around with the same movement-sistem.
Anybody knows how to get this value??
Just do same calculations, but backwards.
In your example you knew: planet.position, planet.radius, degrees and you had to find x and y for that CGPoint.
Now you know: planet.position, planet.radius and that CGPoint and you need to find degrees.
From your formula:
float x = (planet.position.x + planet.radius) *cos(degrees);
you can find your degrees:
cos(degrees) = x / (planet.position.x + planet.radius);
For example:
cos(x) = 1 / 2;
then
x = acos(1/2);
x = 60 degrees or Pi/3 rads
I was wondering if someone helps me understand how to convert the top image to the bottom image.
The images are available in the following link.The top image is in Cartesian coordinate. The bottom image is the converted image in polar coordinate
This is a basic rectangular to polar coordinate transform. To do the conversion, scan across the output image and treat x and y as if they were r and theta. Then use them as r and theta to look up the corresponding pixel in the input image. So something like this:
int x, y;
for (y = 0; y < outputHeight; y++)
{
Pixel* outputPixel = outputRowStart (y); // <- get a pointer to the start of the output row
for (x = 0; x < outputWidth; x++)
{
float r = y;
float theta = 2.0 * M_PI * x / outputWidth;
float newX = r * cos (theta);
float newY = r * sin (theta);
*outputPixel = getInputPixel ( newX, newY ); // <- Should probably do at least bilinear resampling in this function
outputPixel++;
}
}
Note that you may want to handle wrapping depending on what you're trying to achieve. The theta value wraps at 2pi.
How to get points to adding identical intervals?
This code works for circle where theta increment by a fixed value
for (theta = 0 -> 360 degrees)
{r = ellipse_equation(theta);
x = r*cos(theta) + h;
y = r*sin(theta) + k;
}
But if increment is fixed for ellipse turns non identical intervals
This doesn't look right to me:
x = r*cos(theta) + h;
y = r*sin(theta) + k;
Shouldn't that actually be
x = cos(theta) * h;
y = sin(theta) * k;
?
And could you please clarify what you mean by "identical intervals"?
Edit:
I don't think there is an 'easy' way to get what you want. Unlike a circle, an ellipse's circumference cannot be trivially calculated: http://en.wikipedia.org/wiki/Ellipse#Circumference, or http://en.wikipedia.org/wiki/Elliptic_integral