Rotate point test is failing. Why? - c#

This is my Point.cs file that is failing.
// Rotates the point counter-clockwise by deg degrees. For example, applying
// a 90 degree rotation to (1, 0) should give (0, 1).
public void rotate(double deg)
{
double rotCos = Math.Cos(deg * Math.PI / 180);
double rotSin = Math.Sin(deg * Math.PI / 180);
double oldX = x;
double oldY = y;
x = oldX * rotCos - oldY * rotSin;
y = oldX * rotSin + oldY * rotCos;
Point point = new Point(x, y);
}
I run this test and get the result:
"Message: Assert.AreEqual failed. Expected:<2>. Actual:<2>."
[TestMethod]
public void Rotate_Test()
{
double rotate = -90;
double i = 4;
double o = 2;
Point point = new Point(i, o);
double expectedX = 2;
double expectedY = 4;
point.rotate(rotate);
Assert.AreEqual(expectedX, point.getX());
Assert.AreEqual(expectedY, point.getY());
}

Doubles are not exact numbers. They should not be compared for equality without specifying an acceptable difference between them.
https://msdn.microsoft.com/en-us/library/ms243458.aspx
https://msdn.microsoft.com/en-us/library/ya2zha7s(v=vs.110).aspx
Try
Assert.AreEqual(expectedX, point.getX(), 0.001);

Related

Get random point on circle on a segment that has a specific heading

I have a circle, with a specific radius. Inside the circle I have a point with the X, Y coords. I also have a heading, for example 210. How can I get a random point INSIDE THE CIRCLE on the segment that I draw from the point to the margin of the circle? Thanks!
double radiusCircle = 10;
double y = -3;
double x = -Math.Sqrt(3 * 9);
double angleRad = Math.Atan2(y, x);
double angleDeg = angleRad * 180 / Math.PI; // 210 (-150) degrees
double distancePointCenter = Math.Sqrt(x * x + y * y);
double distancePointMargin = radiusCircle - distancePointCenter;
Random rand = new Random(123);
for (int i = 0 i < 10; i++)
{ // Generate 10 random points
double randomPointDistToCenter = distancePointCenter + distancePointMargin * rand.NextDouble();
double xRandomPoint = randomPointDistToCenter * Math.Cos(angleRad);
double yRandomPoint = randomPointDistToCenter * Math.Sin(angleRad);
}

How to decrease and increase values as a curve

I am trying to do a digging tool for my game, I have x and y coordinates of point A and B, what I want to do is create a curve between these points, nothing graphical I just need loop through the coordinates (float x, float y).
I am not good at explaining so here is a visual example;
The first image is what's happen if I just use a for loop to decrease the y value until middle and then increase it from the middle to end.
//Very specific code for my example
//I wrote it just for this example so I am not sure if it works
float y;
float x;
public void Example(float startX, float endX, float startY, float endY, float depth)
{
y = startY;
x = startX;
float changeAmountOfY = depth / (endX - startX);
for (int i = (int)startX; i < (startX + endX) / 2; i++)
{
x++;
y -= changeAmountOfY;
}
for (int i = (int)(startX + endX) / 2; i < endX; i++)
{
x++;
y += changeAmountOfY;
}
}
public void ChangeCoordinates()
{
Example(100f, 200f, 100f, 100f, 50f);
}
The second image is what I need.
I am developing the game on unity and I am using Vector2 for the coordinates but it is not important.
Pure C# or even C++ is welcome.
It is also fine if someone can just explain the math behind what I am trying to do.
Maybe this can help:
// Calculate radius
int radius = (B.X - A.X) / 2;
// Calculate middle
int middle_x = A.X + radius;
int middle_y = A.Y;
// or
int middle_y = (A.Y + B.Y) / 2;
// Coordinates for a semicircle
// 0 to 180 degree
for (int i = 0; i <= 180; i++)
{
double x_coordinate = middle_x + radius * Math.Cos(i * Math.PI / 180);
// Opened to bottom
double y_coordinate = middle_y + radius * Math.Sin(i * Math.PI / 180);
// or opened to top
double y_coordinate = middle_y - radius * Math.Sin(i * Math.PI / 180);
}
Take a look at unit circle.

C# - generating points along a fraction of a circles circumference

I have the below algorithm which generates a number of points along the circumference of a circle for collision events in my program. (This works perfectly as far as I can tell).
bool Collision_True = false;
for (int Angle = 0; Angle <= 359; Angle += 5)
{
int X = (CentreX + (Radius * Math.Cos(Angle));
int Y = (CentreY + (Radius * Math.Sin(Angle));
Point point = new Point(X, Y);
if (Collision_True == false)
{
Collision_True = Player_Collisions(point);
}
}
return Collision_True;
However I want to change this so it only generates points on the bottom third of the circle, I tried changing the values in the for loop as follows:
for (int Angle = 120; Angle <= 240; Angle += 5)
{
...
}
But the points generated are still around the complete circumference of the circle instead of just the bottom third.
Any ideas? Thanks.
You need to convert to radians
for (int angleDegrees = 120; angleDegrees <= 240; angleDegrees += 5)
{
double angleRadians = angleDegrees / 180 * Math.PI;
int X = (CentreX + (Radius * Math.Cos(angleRadians));
int Y = (CentreY + (Radius * Math.Sin(angleRadians));
...

GPS Calculator conversion, calculate lat/lon value for new point

Here is problem which i have:
I load image in C#. On that image I have to insert 2 points: point A and point B by clicking mouse on random possitions.
Point A have it cords (Xa, Ya) which is read from program and I need to manually insert its GPS coords (LatitudeA and LongtudeA) for it.
Point B have it own cords (Xb, Yb) which is also read from program and I need to manually insert its GPS coords (LatitudeB and LongtudeB) for it.
So main problem is next: on every next click on screen I have to know GPS cords for that point. Also for that point C i have (Xc, Yc).
Here is my ComputeLatitudeAndLogitude method, but it seems it doesnt works perfectly. I need this on street level size.
Example:
A (487, 361, 45.252464, 19.850337)
B (1167, 397, 45.252026, 19.853990)
C (810, 513, ??? , ???); results should be C(810, 513, 45.251592 , 19.852075)
PLEASE feel free to contact me so we can fix problem, mymailis hladnopivo1990#gmail.com
public void ComputeLatitudeAndLogitud (Wpf_Maps.Point point)
{
int diffX = pointA.X - pointB.X;
int diffY = pointA.Y - pointB.Y;
double diffLatitude = pointA.Latitude - pointB.Latitude;
double diffLongitude = pointA.Longitude - pointB.Longitude;
double latitudePerPixel = Math.Abs(diffLatitude / diffX);
double longitudePerPixel = Math.Abs(diffLongitude / diffY);
int diffXforA = pointA.X - point.X;
int diffYforA = pointA.Y - point.Y;
int diffXforB = pointB.X - point.X;
int diffYforB = pointB.Y - point.Y;
double newLatitudeFromA = pointA.Latitude + (diffXforA * latitudePerPixel);
double newLatitudeFromB = pointB.Latitude + (diffXforB * latitudePerPixel);
double newLongitudeFromA = pointA.Longitude + (diffYforA * longitudePerPixel);
double newLongitudeFromB = pointB.Longitude + (diffYforB * longitudePerPixel);
point.Latitude = (newLatitudeFromA + newLatitudeFromB) / 2;
point.Longitude = (newLongitudeFromA + newLongitudeFromB) / 2;
}
Depending on the distance you need to cover, linear extrapolation will not work too good; the earth is not plain, and latitude distances vary with longitude.
One approximation would be a sphere on which you calculate the Great-circle distance.
(GPS) coordinates are usually recorded relative to a (non-sphere) model of the earth, the WGS-84 ellipsoid being the most common today. So for maximum accuracy, you'll have to calculate distances based on the corresponding reference model.
Additionally, if the reference model of the image is different from that of the GPS coordinates you may need more than two reference points to determine the exact mapping.
I presume pointA and pointB are at opposite corners of the map, A being bottom left (or top left?)... meaning every point C is up and right of the point A.
Try this simplification:
public void ComputeLatitudeAndLogitud (Wpf_Maps.Point point)
{
int diffX = pointA.X - pointB.X;
int diffY = pointA.Y - pointB.Y;
double diffLatitude = pointA.Latitude - pointB.Latitude;
double diffLongitude = pointA.Longitude - pointB.Longitude;
double latitudePerPixel = Math.Abs(diffLatitude / diffX);
double longitudePerPixel = Math.Abs(diffLongitude / diffY);
int diffXforC = point.X - pointA.X;
int diffYforC = point.Y - pointA.Y;
point.Latitude = pointA.Latitude + (diffXforC * latitudePerPixel);
point.Longitude = pointA.Longitude + (diffYforC * longitudePerPixel);
}
Here's my full code. I've got three tests cases there. The first is where pointC is somewhere random, in the second, pointC matches pointA, and in the third, pointC matches pointB.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(20, 40));
ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(0, 0));
ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(100, 100));
}
public void ComputeLatitudeAndLongitude(MyPoint pointA, MyPoint pointB, MyPoint pointC)
{
int diffX = pointA.X - pointB.X;
int diffY = pointA.Y - pointB.Y;
double diffLatitude = pointA.Latitude - pointB.Latitude;
double diffLongitude = pointA.Longitude - pointB.Longitude;
double latitudePerPixel = Math.Abs(diffLatitude / diffX);
double longitudePerPixel = Math.Abs(diffLongitude / diffY);
int diffXforC = pointC.X - pointA.X;
int diffYforC = pointC.Y - pointA.Y;
pointC.Latitude = pointA.Latitude + (diffXforC * latitudePerPixel);
pointC.Longitude = pointA.Longitude + (diffYforC * longitudePerPixel);
LogResults(String.Format("pointA X:{0} Y:{1} Lat:{2} Long:{3}", pointA.X, pointA.Y, pointA.Latitude, pointA.Longitude), true);
LogResults(String.Format("pointB X:{0} Y:{1} Lat:{2} Long:{3}", pointB.X, pointB.Y, pointB.Latitude, pointB.Longitude), true);
LogResults(String.Format("pointC X:{0} Y:{1} Lat:{2} Long:{3}", pointC.X, pointC.Y, pointC.Latitude, pointC.Longitude), true);
LogResults(String.Empty, true);
}
public void LogResults(string message, bool insertNewline)
{
txtResults.Text += message + (insertNewline ? Environment.NewLine : String.Empty);
}
}
public class MyPoint
{
public int X;
public int Y;
public double Latitude = 0;
public double Longitude = 0;
public MyPoint(int x, int y)
{
X = x;
Y = y;
}
public MyPoint(int x, int y, double latitude, double longitude) : this(x, y)
{
Latitude = latitude;
Longitude = longitude;
}
}
Results:
pointA X:0 Y:0 Lat:10 Long:10
pointB X:100 Y:100 Lat:40 Long:40
pointC X:20 Y:40 Lat:16 Long:22 // C.X is 20% of the way from A.X to B.X, so C.Lat is 20% of the way from A.Lat to B.Lat, Y/Long are 40%
pointA X:0 Y:0 Lat:10 Long:10
pointB X:100 Y:100 Lat:40 Long:40
pointC X:0 Y:0 Lat:10 Long:10 // C.X = A.X and C.Y = A.Y, therefore C.Lat and C.Long = A.Lat and A.Long
pointA X:0 Y:0 Lat:10 Long:10
pointB X:100 Y:100 Lat:40 Long:40
pointC X:100 Y:100 Lat:40 Long:40 // C.X = B.X and C.Y = B.Y, therefore C.Lat and C.Long = B.Lat and B.Long
It cant be done with code above i wrote. Constant EARTH_RADIUS MUST me implemented in function for calculation, if we want to get high precision (6 digits at least: n,mmmmmm). Next code will scale proper lat/lon per pixel, so calculated point C will match referent points A and B when we put that (X,Y) cords which points A and B have.
public void ComputeLatitudeAndLogitude(Wpf_Maps.Point point){
double diffLatAB = pointB.Latitude - pointA.Latitude;
double diffLonAB = pointB.Longitude - pointA.Longitude;
int diffXAB = pointB.X - pointA.X;
int diffYAB = pointB.Y - pointA.Y;
int diffXAC = point.X - pointA.X;
int diffYAC = point.Y - pointA.Y;
point.Latitude = diffLatAB / diffXAB * diffXAC + pointA.Latitude;
point.Longitude = diffLonAB / diffYAB * diffYAC + pointA.Longitude;
}

Algorithm for finding a point in an irregular polygon

Imagagine I have a polygon like the following:
I am looking for a C# algorithm with whom I can find a point (could be the middlepoint or also a random point) inside any polygon.
For finding the center of mass I used the following algorithm:
private Point3d GetPolyLineCentroid(DBObject pObject, double pImageWidth, double pImageHeight)
{
Point2d[] pointArray = GetPointArrayOfRoomPolygon(pObject);
double centroidX = 0.0;
double centroidY = 0.0;
double signedArea = 0.0;
double x0 = 0.0; // Current vertex X
double y0 = 0.0; // Current vertex Y
double x1 = 0.0; // Next vertex X
double y1 = 0.0; // Next vertex Y
double a = 0.0; // Partial signed area
int i = 0;
for (i = 0; i < pointArray.Length - 1; ++i)
{
x0 = pointArray[i].X;
y0 = pointArray[i].Y;
x1 = pointArray[i + 1].X;
y1 = pointArray[i + 1].Y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
}
x0 = pointArray[i].X;
y0 = pointArray[i].Y;
x1 = pointArray[0].X;
y1 = pointArray[0].Y;
a = x0 * y1 - x1 * y0;
signedArea += a;
centroidX += (x0 + x1) * a;
centroidY += (y0 + y1) * a;
signedArea *= 0.5;
centroidX /= (6.0 * signedArea);
centroidY /= (6.0 * signedArea);
Point3d centroid = new Point3d(centroidX, centroidY, 0);
return centroid;
}
This works good with polygones like this:
But if my polygon has the form of a C or something like that this algorithmn does not work because the center off mass is outside the polygon.
Does anyone has an idea how to get always points inside any polygon?
You can use polygon triangulation to break your polygon apart into triangles.
One such algorithm is demonstrated using c# in this CodeProject article.
Once you have triangles, finding arbitrary points that lie within the triangle is easy. Any barycentric coordinate with a sum of 1.0 multiplied by the vertices of the triangle will give you a point inside the triangle.
The center can be derived using the barycentric coordinate [0.333333, 0.333333, 0.333333] :
float centerX = A.x * 0.333333 + B.x * 0.333333 + C.x * 0.3333333;
float centerY = A.y * 0.333333 + B.y * 0.333333 + C.y * 0.3333333;
or more simply:
float centerX = (A.x + B.x + C.x) / 3f;
float centerY = (A.y + B.y + C.y) / 3f;
Use This:
private Point getCentroid(pointArray)
{
double centroidX = 0.0;
double centroidY = 0.0;
for (int i = 0; i < pointArray.Length; i++)
{
centroidX += pointArray[i].X;
centroidY += pointArray[i].Y;`
}
centroidX /= pointArray.Length;
centroidY /= pointArray.Length;
return(new Point(centroidX ,centroidY));
}
this code is just to find Center of Mass of Polygon. To check whether a point is inside or outside polygon check this link http://bbs.dartmouth.edu/~fangq/MATH/download/source/Determining%20if%20a%20point%20lies%20on%20the%20interior%20of%20a%20polygon.htm

Categories

Resources