I am working on a mobile app in C# using the Xamarin framework. I am trying to move a point by a fixed angle on a map like in the first part of the gif below. I believe I am using the right mathematical functions to compute the coordinates of the shifted points since in first part of the GIF, in GeoGebra, everything seems to be fine.
But when it comes to the actual in-app implementation, the results are quite weird : the angle is not consistent and the distance between the center and the points varies by moving the target.
The GIF showing the issue
I don't have a clue about what is wrong with the code. In the code below I use polylineOptions to draw the lines but I've tried with a Polygon and it displays the same results. Maybe it's because customMap.UserPin.Position returns the coordinates in Decimal Degree format (i.g. 34.00462, -4.512221) and the gap between two position is too small for a double.
Here are the two functions used to draw the lines.
// Add a cone's side to the variable coneLines
private void addConePolyline(double angle, CustomMap customMap, LatLng userPos)
{
// The coordinates of the end of the side to be drawn
LatLng conePoint = movePoint(angle, customMap.UserPin.Position, customMap.TargetPin.Position);
var polylineOptions = new PolylineOptions();
polylineOptions.InvokeWidth(10f);
polylineOptions.InvokeColor(Android.Graphics.Color.Argb(240, 255, 20, 147)); // Pink
polylineOptions.Add(userPos);
polylineOptions.Add(conePoint);
// Add the line to coneLines
coneLines.Add(map.AddPolyline(polylineOptions));
}
// Moves a point by the given angle on a circle of center rotationCenter with respect to p
private LatLng movePoint(double angle, Position rotationCenter, Position initialPoint)
{
// Compute the components of the translation vector between rotationCenter and initialPoint
double dx = initialPoint.Latitude - rotationCenter.Latitude;
double dy = initialPoint.Longitude - rotationCenter.Longitude;
// Compute the moved point's position
double x = rotationCenter.Latitude + Math.Cos(angle) * dx - Math.Sin(angle) * dy;
double y = rotationCenter.Longitude + Math.Sin(angle) * dx + Math.Cos(angle) * dy;
LatLng res = new LatLng(x, y);
return res;
}
I hope someone can help me with this!
Thank you.
Related
My issue is that I've been trying to check if a rectangle that is rotated by a certain amount of degrees contain a point, but I wasn't able to calculate that after many attempts with the help of some code samples and examples that I've found online.
What I got is the rectangle (X, Y, Width, Height, Rotation) and the point (X, Y) and I've been trying to create a simple function that lets me instantly calculate that, which would be something something like this:
public bool Contains(Rect Rectangle, float RectangleRotation, Point PointToCheck);
But as I mentioned, I wasn't able to do so, those mathematical calculations that include some formulas I found online are way too much for me to understand.
Could someone help me with calculating this? If you could provide the calculation in C# code form (not formulas) then that would be great! Thanks.
PS: Using the 2D Physics Engine that is available in Unity3D is not a option, my rectangle is not associated with a gameobject that I could attach a 2D collision component to, I need to do this mathematically without the involvement of gameobjects or components.
Edit: I forgot to mention, the rectangle is being rotated by the middle of the rectangle (center/origin).
Rather than checking if the point is in a rotated rectangle, just apply the opposite of the rotation to the point and check if the point is in a normal rectangle. In other words, change your perspective by rotating everything by -RectangleRotation, so that the rectangle does not appear rotated at all.
public bool Contains(Rect rect, float rectAngle, Point point)
{
// rotate around rectangle center by -rectAngle
var s = Math.Sin(-rectAngle);
var c = Math.Cos(-rectAngle);
// set origin to rect center
var newPoint = point - rect.center;
// rotate
newPoint = new Point(newPoint.x * c - newPoint.y * s, newPoint.x * s + newPoint.y * c);
// put origin back
newPoint = newPoint + rect.center;
// check if our transformed point is in the rectangle, which is no longer
// rotated relative to the point
return newPoint.x >= rect.xMin && newPoint.x <= rect.xMax && newPoint.y >= rect.yMin && newPoint.y <= rect.yMax;
}
I using microsoft visual 2010 with dynamic data display dll
I need to do an circle around a point by angle and radius.
I have been successful but it's wrong, I think so.
First of all, my source code:
I got the prePs from the mouseClick (it's not problem the point is perfect working you can see next in the picture)
// Get the X position of the pointClicked
cx = (double)prePs.X;
// Get the Y position of the pointClicked
cy = double.Parse(this.plotter.Viewport.Transform.DataTransform.ViewportToData(prePs).Y.ToString());
// Get the new X position of the pointClicked by the angel with math calculation
xEndP = (float)(double.Parse(txt_enterRadius.Text.ToString()) * Math.Cos(a * Math.PI / 180F)) + cx;
// Get the new Y position of the pointClicked by the angel with math calculation
yEndP = (float)(double.Parse(txt_enterRadius.Text.ToString()) * Math.Sin(a * Math.PI / 180F)) + cy;
Secondly what I actualy got :
At the middle I got exactly perfect circle, but in the north and south the circle is type of ellipse.
picture:
http://sizmedia.com/my.php?i=hm2zuv5yyenj.png
I would happy to understand :
Why? Is it good? Or I need to change something?
Becuase i thought about it and the Earth is circle and its type of reasonable.
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 have a problem that made me pull my last hair of my head.
I'm struggling to reproduce an angled elliptical arc in
my c# winform application using data extracted from DXF.
Data as follows:
Centerpoint at X : 597,5;
Centerpoint at Y : 185;
Endpoint of major axis, relative to the center (X): 35,9651502358374;
Endpoint of major axis, relative to the center (Y): 60,0542085828599;
Ratio of minor axis to major axis : 0,35714285714286;
Start parameter : 4,78575772944812;
End parameter : 7,78061288491105;
The code:
float ex = 597,5; //Centerpoint at X
float ey = 185; //Centerpoint at Y
float exb = 35,9651502358374; //Endpoint of major axis (X)
float eyb = 60,0542085828599; //Endpoint of major axis (Y)
float EllipseRatio = 0,35714285714286;
double sa = 4,78575772944812; //Start parameter
double ea = 7,78061288491105; //End parameter
sa = double.Parse(exb.ToString()) * Math.Cos(sa) + //Now it's a Start angle
double.Parse(eyb.ToString()) * Math.Sin(sa);
ea = 2 * double.Parse(exb.ToString()) * Math.Cos(ea) + //Now it's a sweep angle
double.Parse(eyb.ToString()) * Math.Sin(ea);
double angle = Math.Atan(exb / eyb); //Rotation angle
Graphics ellipse = this.CreateGraphics();
ellipse.TranslateTransform(ex, ey); //So I can rotate at center
ellipse.RotateTransform(float.Parse(angle.ToString()));
ellipse.DrawArc(PreviewPen, (0 - exb), eyb, 2 * exb, 2 * eyb * EllipseRatio,
float.Parse(sa.ToString()), float.Parse(ea.ToString()));
It should look like this;
Instead it looks like this:
As You can see, all the shapes are ok, except the ellipse.
I just can't get it right. Eider the position is wrong, or the
orientation is wrong, size, shape, angle...
At some point i got close, but then my thinking engine just blew up.
I'm not using e.graphics.
Please help in details if you can.
I am trying to make a user-defined arc with the Helix 3D toolkit. The user selects 3 points on the arc (start, middle, end) and the program finds the center of the circle and draws the arc from start to end. My problem is I'm not good at math and I am having problems making this work. My main problem is getting the start and end angles and having it draw arcs of all sizes accurately. Any help is appreciated. Here is my code:
private void Draw_Arc(object sender, MouseButtonEventArgs e)
{
linept = new List<Point3D>();
linept.Add(startPoint);
linept.Add(endPoint);
linept.Add((Point3D)GetPoints(e));
LinesVisual3D line = new LinesVisual3D();
line.Thickness = 2;
line.Color = Colors.Blue;
line.Points = linept;
port.Children.Add(line);
double startAngle, sweepAngle;
Point3D center = GetCenterOfArc(linept.ElementAt(0), linept.ElementAt(1), linept.ElementAt(2));
GetAngles(linept.ElementAt(0), linept.ElementAt(1), linept.ElementAt(2), out startAngle, out sweepAngle);
circle = new PieSliceVisual3D();
double RadiusX = Math.Abs(startPoint.X - center.X);
double RadiusY = Math.Abs(startPoint.Y - center.Y);
circle.Center = center;
if (RadiusX >= RadiusY)
circle.OuterRadius = RadiusX;
else
circle.OuterRadius = RadiusY;
circle.InnerRadius = circle.OuterRadius + 3;
circle.StartAngle = (180 / Math.PI * Math.Atan2(startPoint.Y - circle.Center.Y, startPoint.X - circle.Center.X));
circle.EndAngle = (180 / Math.PI * Math.Atan2(linept.ElementAt(2).Y - circle.Center.Y, linept.ElementAt(2).X - circle.Center.X));
port.Children.Add(circle);
}
I think that you have to know the center of the circle in order to know the starting and ending angle of the arc.
Say that you just have three points, and you want to find a circle that goes through all three, you basically have three equations with three variables:
(x-x0)^2 + (y-y0)^2 = R^2
(x-x1)^2 + (y-y1)^2 = R^2
(x-x2)^2 + (y-y2)^2 = R^2
Solving that can get a little tricky if you try to program that on your own and have average knowledge in math, but you can do it fairly easily using matrices. Read here for a bit information.
After you've solved the three equations, you should have X, Y, R.
X and Y will be the center point of the circle, and R - it's radius.
Now, as far as I remember, they count the arc's degrees starting from the positive X axis, going upwards. So you would need to calculate the angle between two lines - the line that stretches between the center to your floating point, and the line that stretches from your center point to the "limitless" right. You may just Google "calculate angle between two lines". Repeating that process for both your starting point and your ending point, will give each their respective entering/exiting angle.
The middle point isn't really used anymore, but the radius is. You just set it to be the radius and you're good to go.
I haven't really implemented anything - just giving you a fair direction. (and I bet that there's a much cleaner and nicer-to-work-with solution)