I am drawing an imaginary circle around the middle of a button.
The radius of the circle is the Height/2 if Height>Width or Width/2 if Width>Height.
Now i have to calculate which coordinates (in pixels) are in this circle.
The idea is that if e.g. the mouse cursor hovers over that circle, something happens.
Calculating each co-ordinate is overkill; just compare the distance to the center. For example:
int radius = 5; // whatever
int deltaX = originX - mouseX, deltaY = originY - mouseY;
// compare the square distance, to avoid an unnecessary square-root
if((deltaX * deltaX) + (deltaY * deltaY) <= (radius * radius)) {
// inside the circle, or on the edge
}
To avoid a little math, you could also do a quick bounding-box check, i.e. checking the rectangular region (just addition/subtraction). This can be used in combination, i.e.
check the bounding box
if it isn't in the bounding box it certainly isn't in the circle
if it is in the bounding box, do the math to compare the square-distance
You are inside the circle when this equation is satisfied:
Math.pow(mouse_pos_x-center_circle_x,2)+Math.pow(mouse_pos_y-center_circle_y,2)<Math.pow(radius,2)
The area of a a circle by definition is a group of points whose distance is equal to or less than the center.
All you must do to test if a point is within a circle is to calculate the distance between it and the center point. If this distance is smaller than the radius of the circle, the point is within the circle.
double Distance(Point p1, Point p2)
{
int x = p1.X - p2.X;
int y = p1.Y - p2.Y;
return Math.Sqrt(x * x + y * y);
}
You can use next condition:
x^2+y^2<R^2
Where R - radius,
All this points are in circle.
Related
I have got a square with the bounds of (0,0) to (800,600) In this raster I have to draw a line, given to me are the Angle and Radius of a line, starting from point (0,0).
These bounds are based on a screen with a resolution of 800x600
I know how to calculate the (X,Y) points from this point,
X = Radius * Cos(Angle)
Y = Radius * Sin(Angle)
But from this point I don't know how to continue. In the images below I've defined my use cases. (X3,Y3) are the points I know how to calculate as told above. But how do I find (X1, Y1) and (X2, Y2)?
The Angle and Radius can be all kinds of values, see for example the values below. When both X3 and Y3 are a negative value I know the (X1,Y1) and (X2, Y2) will not fall in the raster.
I think this isn't to dificult to calculate, but I just don't know how to do this.
The line from the origin can be expressed by the equation
y = mx
where the slope m = y3/x3. You will need a line perpendicular to your first line, which means it has a slope of
m' = -1/m
Therefore it can be expressed by the equation
y = m'(x-x3) + y3
The point (X1,Y1) will have X1 = 0 and Y1 can be calculated via Y1 = m'x + y3. The point (X2,Y2) will have Y2 = 0 and X2 = (y - Y2)/m' + x3.
The problem I want to solve is:
Calculate the intersection of the ball and the circle with the following information.
Known information about the circle:
1. The coordinates of the center A are known, and the center A is on the spherical surface.
2. The radius ra of the circle A is known.
3. Know the coordinates of a point B on the circle
Known information about the ball:
1. The coordinates of the spherical center B of the known ball.
2. The radius of the known ball rb.
Picture is as follows
Icon
With the above information, I hope to calculate the coordinates of the intersection point.
Then put the algorithm into C# so that the associated points on the plane can be placed on the sphere and the distance between these points does not change.
If the above method works, I can place many points equidistant from A on the sphere, and after placement, the distance between these points and A is unchanged.
I tried before:
1. Solve the problem with simultaneous equations, but unfortunately the final result is not available.
2. Try to get the result by the intersection of two circles, but the circle and the circle are both in a plane relationship, only the coordinates of x, y can be obtained, and the coordinates of z cannot be obtained.
I successfully put some points on the sphere through the following code, but the distance between the points and the points has changed, and the more the number of points, the more obvious this change, I don't want their distance to change, so I came up with it. Determine the position of these points by intersecting the circle with the ball。
The parameter (List atoms ) stores some points on the plane, and (double r) is the radius of the ball. By this method, the point on the plane will be "sticked" to the sphere.
/// <summary>
/// Stick the atom to the sphere
/// </summary>
private void BendAtom(List <Atom> atoms,double r)
{
double L = 2d * Math.PI * r;
double w = L;// * 2d;
double h = L / 2d;
for (int i = 0; i < atoms.Count; i++)
{
atoms[i].Point.x = (float)((360 / w) * atoms[i].Point.x - 180);
atoms[i].Point.y = (float)((180 / h) * atoms[i].Point.y - 90);
}
for (int i = 0; i < atoms.Count; i++)
{
double lat = atoms[i].Point.x;
double lng = atoms[i].Point.y;
double phi = ((90d - lat) * Math.PI) / 180d;
double theta = ((180 - lng) * Math.PI) / 180d;
double x = r * Math.Sin(phi) * Math.Cos(theta);
double y = r * Math.Cos(phi);
double z = r * Math.Sin(phi) * Math.Sin(theta);
atoms[i].Point.x = (float)x;
atoms[i].Point.y = (float)y;
atoms[i].Point.z = (float)z;
}
}
I hope that after the point is "posted" on the ball, the distance of the points does not change, but as a result, they change, and the more the number of points, the greater the change.
My math level is limited. If you have a better way to solve this problem, thank you very much and thank you for your help.
The result of the above code
It's been 10 years since I did any math like this... I am programming a game in 2D and moving a player around. As I move the player around I am trying to calculate the point on a circle 200 pixels away from the player position given a positive OR negative angle(degree) between -360 to 360. The screen is 1280x720 with 0,0 being the center point of the screen. The player moves around this entire Cartesian coordinate system. The point I am trying trying to find can be off screen.
I tried the formulas on article Find the point with radius and angle but I don't believe I am understanding what "Angle" is because I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
So for example I have...
1280x720 on a Cartesian plane
Center Point (the position of player):
let x = a number between minimum -640 to maximum 640
let y = a number between minimum -360 to maximum 360
Radius of Circle around the player: let r always = 200
Angle: let a = a number given between -360 to 360 (allow negative to point downward or positive to point upward so -10 and 350 would give same answer)
What is the formula to return X on the circle?
What is the formula to return Y on the circle?
The simple equations from your link give the X and Y coordinates of the point on the circle relative to the center of the circle.
X = r * cosine(angle)
Y = r * sine(angle)
This tells you how far the point is offset from the center of the circle. Since you have the coordinates of the center (Cx, Cy), simply add the calculated offset.
The coordinates of the point on the circle are:
X = Cx + (r * cosine(angle))
Y = Cy + (r * sine(angle))
You should post the code you are using. That would help identify the problem exactly.
However, since you mentioned measuring your angle in terms of -360 to 360, you are probably using the incorrect units for your math library. Most implementations of trigonometry functions use radians for their input. And if you use degrees instead...your answers will be weirdly wrong.
x_oncircle = x_origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_origin + 200 * sin (degrees * pi / 180)
Note that you might also run into circumstance where the quadrant is not what you'd expect. This can fixed by carefully selecting where angle zero is, or by manually checking the quadrant you expect and applying your own signs to the result values.
I highly suggest using matrices for this type of manipulations. It is the most generic approach, see example below:
// The center point of rotation
var centerPoint = new Point(0, 0);
// Factory method creating the matrix
var matrix = new RotateTransform(angleInDegrees, centerPoint.X, centerPoint.Y).Value;
// The point to rotate
var point = new Point(100, 0);
// Applying the transform that results in a rotated point
Point rotated = Point.Multiply(point, matrix);
Side note, the convention is to measure the angle counter clockwise starting form (positive) X-axis
I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
I think the reason your attempt did not work is that you were passing angles in degrees. The sin and cos trigonometric functions expect angles expressed in radians, so the numbers should be from 0 to 2*M_PI. For d degrees you pass M_PI*d/180.0. M_PI is a constant defined in math.h header.
I also needed this to form the movement of the hands of a clock in code. I tried several formulas but they didn't work, so this is what I came up with:
motion - clockwise
points - every 6 degrees (because 360 degrees divided by 60 minuites is 6 degrees)
hand length - 65 pixels
center - x=75,y=75
So the formula would be
x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))
where x and y are the points on the circumference of a circle, Cx and Cy are the x,y coordinates of the center, r is the radius, and d is the amount of degrees.
Here is the c# implementation. The method will return the circular points which takes radius, center and angle interval as parameter. Angle is passed as Radian.
public static List<PointF> getCircularPoints(double radius, PointF center, double angleInterval)
{
List<PointF> points = new List<PointF>();
for (double interval = angleInterval; interval < 2 * Math.PI; interval += angleInterval)
{
double X = center.X + (radius * Math.Cos(interval));
double Y = center.Y + (radius * Math.Sin(interval));
points.Add(new PointF((float)X, (float)Y));
}
return points;
}
and the calling example:
List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);
The answer should be exactly opposite.
X = Xc + rSin(angle)
Y = Yc + rCos(angle)
where Xc and Yc are circle's center coordinates and r is the radius.
Recommend:
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles)
{
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
You can use this:
Equation of circle
where
(x-k)2+(y-v)2=R2
where k and v is constant and R is radius
I'm making an inventory screen for a game I'm working on, and I'd like to be able to draw a series of panels representing each item in the inventory. I want to be able to fit those panels on a circular path.
Here's a mock up I made of what I mean
http://fc02.deviantart.net/fs70/f/2010/280/7/2/khmp_magic_menu_concept_by_magna_alphamon-d30a7em.png
basically I'd like to be able to, give a radius, a center point, and the y co-ordinate to start drawing at, draw this series of panels so they align with the path of the circle like in the image.
Computing the y dimension is easy, its just the startposition y + panel height * panel index, but I'm unsure how to compute the x for a variable radius/center point circle.
Any help would be appreciated.
This is in C#, but something similar in C/C++ will be fine as long as I can convert it
Thanks in advance
EDIT: To calirify, y's position is relative to the top or bottom of the screen and is independent of the circle. If a given y does not map to a point on the circle, then I'll discard that point and not draw the panel.
While ideally I'd like to be able to use any elliptical shape (given two radii), a circle would be good too
Let cx, cy be the coordinates of the center point. Let r be the radius of the circle. Let y be the drawing y-coordinate and x, the x-coordinate. You observe that y = cy + panel height * panel index. By the magic of right triangles, this means that x^2 + y^2 = r^2. Solving for x, we get x = cx + sqrt(r^2 - (y-cy)^2).
EDIT: Converting to code:
#include <math>
float ordinate(float cx, float cy, float r, float y) {
// assumes cx and cy are in the same coordinate system as x and y
// assumes the coordinate origin is in the lower left corner.
return cx + sqrtf(powf(r,2) - powf(y-cy,2));
}
I'm dumb. After seeing Eric's answer, I remembered I can just rearrange and solve the equations of a circle or elipse as necessary.
Thanks
You can use a rotational matrix for this. Here is a simple algorithm that finds the next point {x, y} such that it is rotated theta radians around a circle. You can start with the first item at x=radius and y=radius (wherever really, just a point that you know will contain an item), and then just continue to increment theta as you loop through your items.
Point Rotate(int x, int y, float theta)
int x_p = (x * Math.Cos(theta)) - (y * Math.Sin(theta));
int y_p = (y * Math.Cos(theta)) + (x * Math.Sin(theta));
return new Point(x_p, y_p);
end
On a side note; I always preferred "Bolt1, Bolt2, Bolt3" to "Thunder, Thundara, Thundaga" =P
I am developing in application in XNA which draws random paths. Unfortunately, I'm out of touch with graphing, so I'm a bit stuck. My application needs to do the following:
Pick a random angle from my origin (0,0), which is simple.
Draw a circle in relation to that origin, 16px away (or any distance I specify), at the angle found above.
(Excuse my horrible photoshoping)
alt text http://www.refuctored.com/coor.png
The second circle at (16,16) would represent a 45 degree angle 16 pixels away from my origin.
I would like to have a method in which I pass in my distance and angle that returns a point to graph at. i.e.
private Point GetCoordinate(float angle, int distance)
{
// Do something.
return new Point(x,y);
}
I know this is simple, but agian, I'm pretty out of touch with graphing. Any help?
Thanks,
George
If the angle is in degrees, first do:
angle *= Math.PI / 180;
Then:
return new Point(distance * Math.Cos(angle), distance * Math.Sin(angle));
By the way, the point at (16, 16) is not 16 pixels away from the origin, but sqrt(16^2 + 16^2) = sqrt(512) =~ 22.63 pixels.
private Point GetCoordinate(float angle, int distance)
{
float x = cos(angle) * distance;
float y = sin(angle) * distance;
return new Point(x, y);
}
Note that the trigonometric functions probably take radians. If your angle is in degrees, divide by 180/Pi.
in general:
x = d * cos(theta)
y = d * sin(theta)
Where d is the distance from the origin and theta is the angle.
Learn the Pythagorean Theorem. Then this thread should have more specific details for you.