I have two points on a map and I know the distance between them. Now, I need to get a new point between them X meters away from start point. However, i cannot figure out, how to find the new coords.
var nextTrazadoPoint = new Coord {Lat = ...., Lng=...., Alt=...};
var previousTrazadoPoint = new Coord {Lat = ...., Lng=...., Alt...};
var fromCoords = new GeoCoordinate(nextTrazadoPoint.Lat, nextTrazadoPoint.Lng, nextTrazadoPoint.Alt);
var toCoords = new GeoCoordinate(previousTrazadoPoint .Lat, previousTrazadoPoint .Lng, previousTrazadoPoint .Alt);
var distance = fromCoords.GetDistanceTo(toCoords); //Let's say 1000 ¿meters?
Now I want to walk 200 meters from previousTrazadoPoint to nextTrazadoPoint
//Vector from previousTrazadoPoint to nextTrazadoPoint
var vectorDireccion = new Vector(
(double)(nextTrazadoPoint.Latitud - previousTrazadoPoint.Latitud),
(double)(nextTrazadoPoint.Longitud - previousTrazadoPoint.Longitud)
);
//Normalize
vectorDireccion.Normalize();
//meters from previousTrazadoPoint
var distanciaARecorrer = 200;
//New coords
var vectorDestino = distanciaARecorrer * vectorDireccion;
point.Latitud = (decimal)vectorDestino.X + previousTrazadoPoint.Latitud;
point.Longitud = (decimal)vectorDestino.Y + previousTrazadoPoint.Longitud;
However, when i draw the new point on Gmaps, it is not placed between both.
Any ideas?
Thanks to #HansKilian and #cletus (Calculate distance between 2 GPS coordinates), I could find the solution
private const double EARTH_RADIUS = 6378.1;
private static double ConvertToRadians(double angle)
{
return (Math.PI / 180) * angle;
}
private static double ConvertToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
private static double CalculateBearing(CoordsDto from, CoordsDto to)
{
var from_lat_rad = ConvertToRadians(from.Latitud);
var to_lat_rad = ConvertToRadians(to.Latitud);
var dif_lng_rad = ConvertToRadians(to.Longitud - from.Longitud);
double x = Math.Cos(from_lat_rad) * Math.Sin(to_lat_rad) - Math.Sin(from_lat_rad) * Math.Cos(to_lat_rad) * Math.Cos(dif_lng_rad);
double y = Math.Sin(dif_lng_rad) * Math.Cos(to_lat_rad);
// Math.Atan2 can return negative value, 0 <= output value < 2*PI expected
return (Math.Atan2(y, x) + Math.PI * 2) % (Math.PI * 2);
}
public static CoordsDto GetPointFarAway(CoordsDto from, CoordsDto to, double meterAwayFromStart)
{
var resp = new CoordsDto();
var bearing_rad = CalculateBearing(from, to);
var d = meterAwayFromStart * 0.001; //KM
var input_lat1_rad = ConvertToRadians(from.Latitud);
var input_lon1_rad = ConvertToRadians(from.Longitud);
var newPoint_lat_rad = Math.Asin(
Math.Sin(input_lat1_rad) * Math.Cos(d / EARTH_RADIUS) + Math.Cos(input_lat1_rad) * Math.Sin(d / EARTH_RADIUS) * Math.Cos(bearing_rad)
);
var newPoint_lon_rad = input_lon1_rad + Math.Atan2(
Math.Sin(bearing_rad) * Math.Sin(d / EARTH_RADIUS) * Math.Cos(input_lat1_rad),
Math.Cos(d / EARTH_RADIUS) - Math.Sin(input_lat1_rad) * Math.Sin(newPoint_lat_rad)
);
resp.Latitud = ConvertToDegree(newPoint_lat_rad);
resp.Longitud = ConvertToDegree(newPoint_lon_rad);
return resp;
}
I can't see anything wrong with your code. You haven't really provided enough information that I can take your code and compile it and see what's wrong, so I tried coding it up from scratch using the Vector2 class. I couldn't use Vector since that isn't available in .NET core and my sandbox project is a .NET core project.
This is what I got
var origin = new Vector2(100.0f, 100.0f);
var destination = new Vector2(0.0f, 400.0f);
var direction = destination - origin;
var movement = Vector2.Normalize(direction) * 200.0f;
var movementdestination = origin + movement;
Console.WriteLine($"X: {movementdestination.X}, Y: {movementdestination.Y}");
It prints
X: 36.75444, Y: 289.7367
which - as far as I can tell - is correct. I hope that helps.
Related
So, I'm working on Pie Control with Orbit View from Windows Community toolkit.
I tried to change the behavior of Orbit View to arrange item started at the top instead of at the left center.
Here is when Orbit View has only one item.
I tried tracking it down and found the code that Orbit View used to arrange item. But the problem is that I know nothing about math and didn't know where to change the value :/ So, here is the code.
protected override Size ArrangeOverride(Size finalSize)
{
var angle = 2 * Math.PI / Children.Count;
var minDistance = 80;
var maxDistance = Math.Max(minDistance, (Math.Min(finalSize.Width, finalSize.Height) - OrbitView.MaxItemSize) / 2);
var elementsProperties = new List<OrbitViewElementProperties>();
for (var i = 0; i < Children.Count; i++)
{
var element = Children.ElementAt(i);
OrbitViewDataItem orbitViewDataItem = null;
if (element is FrameworkElement)
{
orbitViewDataItem = ((FrameworkElement)element).DataContext as OrbitViewDataItem;
}
var d = orbitViewDataItem != null && orbitViewDataItem.Distance >= 0 ? orbitViewDataItem.Distance : 0.5;
d = Math.Min(d, 1d);
var distance = (d * (maxDistance - minDistance)) + minDistance;
var x = distance * Math.Cos((angle * i) + (angle / 2));
var y = distance * Math.Sin((angle * i) + (angle / 2));
var x_normalized = (finalSize.Width / 2) + x - (element.DesiredSize.Width / 2);
var y_normalized = (finalSize.Height / 2) - y - (element.DesiredSize.Height / 2);
var point = new Point(x_normalized, y_normalized);
element.Arrange(new Rect(point, element.DesiredSize));
var elementProperties = new OrbitViewElementProperties()
{
XYFromCenter = new Point(x, y),
DistanceFromCenter = distance,
Element = element
};
elementsProperties.Add(elementProperties);
if (ItemArranged != null)
{
var args = new OrbitViewPanelItemArrangedArgs()
{
ElementProperties = elementProperties,
ItemIndex = i
};
ItemArranged.Invoke(this, args);
}
}
ItemsArranged?.Invoke(this, new OrbitViewPanelItemsArrangedArgs() { Elements = elementsProperties });
return finalSize;
}
So, where do I change it to make it start putting the item at the top center (0 degree) instead of left center (270 degree)
Edit: I fork the project and remove all item to just a few control here: https://github.com/ray1997/WindowsCommunityToolkit/tree/ForJustR
The code I mention above is in here: https://github.com/ray1997/WindowsCommunityToolkit/blob/ForJustR/Microsoft.Toolkit.Uwp.UI.Controls/OrbitView/OrbitViewPanel.cs line 90
var angle = 2 * Math.PI / Children.Count;
This looks like the angle is expressed in radians.
var distance = (d * (maxDistance - minDistance)) + minDistance;
var x = distance * Math.Cos((angle * i) + (angle / 2));
var y = distance * Math.Sin((angle * i) + (angle / 2));
and here it is used to calculate the x and y values for the elements.
Now adding 90° or 2 * Math.PI / 4 Radians will move it by 90°.
So that gets you
// offset the first element by 90°
var customOffset = 2 * Math.PI / 4;
var distance = (d * (maxDistance - minDistance)) + minDistance;
var x = distance * Math.Cos((angle * i) + (angle / 2) - customOffset);
var y = distance * Math.Sin((angle * i) + (angle / 2) - customOffset);
Is there a function in C# which can give me all the points on a straight line between two points in 3D?
To calculate the distance between those two points, I use this:
public class Position {
public float x;
public float y;
public float z;
}
public void CalculateDistance(Position position1, Position position2, int mapId){
float deltaX = position1.x - position2.x;
float deltaY = position1.y - position2.y;
float deltaZ = position1.z - position2.z;
float distance = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
Console.WriteLine("Distance is: " + distance);
}
Example coordinates:
Position pos1 = new Position();
pos1.x = 141.6586f;
pos1.y = 0.6852107f;
pos1.z = 153.2231f;
Position pos2 = new Position();
pos2.x = 142.336f;
pos2.y = 0.8685942f;
pos2.z = 130.8394f;
Let's say, the distance in line between those two 3d coordinates can be passed for 5 seconds. How can I print the current coordinate for every 1 second?
what you want to do is well described in this answer
And here is example of code how you can print your values:
var mx = pos2.x - pos1.x;
var my = pos2.y - pos1.y;
var mz = pos2.z - pos1.z;
for(var t=0; t < 10; t++) {
var x = pos1.x + mx * t;
var y = pos1.y + my * t;
var z = pos1.z + mz * t;
//TODO: use you 3D point
}
Hope this helps!
I am creating a 2D physics engine, and I am having trouble with a certain type of collision between movable and immovable objects. What I mean by movable is that the (x,y) values can change, not that the frame of reference can or can't change.
For example, a ball hitting a wall would be something that is movable colliding with something immovable.
I believe that I need to use something like Normal Force in this situation, but I am no sure how that would be used for finding the outcome of the collision.
Here is the code that I have so far. This code is for collision between two moving entities, but I need to add a case for when one is not moving:
private static void UpdateEntities(PhysicsEntity a, PhysicsEntity b)
{
var collisionAngle = Math.Atan2(a.Position.Y - b.Position.Y, a.Position.X - b.Position.X);
var angleA = a.Velocity.Direction - collisionAngle;
var angleB = b.Velocity.Direction - collisionAngle;
var vAx = a.Velocity.Magnitude * Math.Cos(angleA);
var vAy = a.Velocity.Magnitude * Math.Sin(angleA);
var vBx = b.Velocity.Magnitude * Math.Cos(angleB);
var vBy = b.Velocity.Magnitude * Math.Sin(angleB);
var vfAx = ((vAx * (a.Mass - b.Mass) + 2 * b.Mass * vBx) / (a.Mass + b.Mass)) * a.Material.Elasticity;
var vfBx = ((vBx * (b.Mass - a.Mass) + 2 * a.Mass * vAx) / (a.Mass + b.Mass)) * b.Material.Elasticity;
var vfAy = vAy * a.Material.Elasticity;
var vfBy = vBy * b.Material.Elasticity;
var magA = Math.Sqrt(Math.Pow(vfAx, 2) + Math.Pow(vfAy, 2));
var magB = Math.Sqrt(Math.Pow(vfBx, 2) + Math.Pow(vfBy, 2));
var dirA = Math.Atan2(vfAy, vfAx) + collisionAngle;
var dirB = Math.Atan2(vfBy, vfBx) + collisionAngle;
a.Velocity.X = magA * Math.Cos(dirA);
a.Velocity.Y = magA * Math.Sin(dirA);
b.Velocity.X = magB * Math.Cos(dirB);
b.Velocity.Y = magB * Math.Sin(dirB);
}
I tried setting the velocity of the immovable object to the opposite of the movable object's velocity, but that caused things to phase into each other.
I was able to get help from a friend and we worked out this algorithm to have objects reflect off of immovable objects during a collision.
Modified Original Function:
private static void UpdateEntities(PhysicsEntity a, PhysicsEntity b)
{
var collisionAngle = Math.Atan2(a.Position.Y - b.Position.Y, a.Position.X - b.Position.X);
if (a.IsMoveable && b.IsMoveable)
{
var angleA = a.Velocity.Direction - collisionAngle;
var angleB = b.Velocity.Direction - collisionAngle;
var vAx = a.Velocity.Magnitude * Math.Cos(angleA);
var vAy = a.Velocity.Magnitude * Math.Sin(angleA);
var vBx = b.Velocity.Magnitude * Math.Cos(angleB);
var vBy = b.Velocity.Magnitude * Math.Sin(angleB);
var vfAx = ((vAx * (a.Mass - b.Mass) + 2 * b.Mass * vBx) / (a.Mass + b.Mass)) * a.Material.Elasticity;
var vfBx = ((vBx * (b.Mass - a.Mass) + 2 * a.Mass * vAx) / (a.Mass + b.Mass)) * b.Material.Elasticity;
var vfAy = vAy * a.Material.Elasticity;
var vfBy = vBy * b.Material.Elasticity;
var magA = Math.Sqrt(Math.Pow(vfAx, 2) + Math.Pow(vfAy, 2));
var magB = Math.Sqrt(Math.Pow(vfBx, 2) + Math.Pow(vfBy, 2));
var dirA = Math.Atan2(vfAy, vfAx) + collisionAngle;
var dirB = Math.Atan2(vfBy, vfBx) + collisionAngle;
a.Velocity.X = magA * Math.Cos(dirA);
a.Velocity.Y = magA * Math.Sin(dirA);
b.Velocity.X = magB * Math.Cos(dirB);
b.Velocity.Y = magB * Math.Sin(dirB);
}
else
{
var sign = Math.Sign(collisionAngle);
collisionAngle *= sign;
while (collisionAngle > Math.PI/2)
{
collisionAngle -= Math.PI / 2;
}
collisionAngle *= sign;
if (a.IsMoveable)
{
Reflection(ref a, b, collisionAngle);
}
else
{
Reflection(ref b, a, collisionAngle);
}
}
}
Reflection Function:
private static void Reflection(ref PhysicsEntity movable, PhysicsEntity immovable, double collisionAngle)
{
if (Math.Abs(collisionAngle - Math.PI / 2) < Universe.Epsilon)
{
// take the velocity vector, rotate it 180 degrees, scale it
movable.Velocity.X *= -1;
movable.Velocity.Y *= -1;
}
else if (Math.Abs(movable.Position.Y - immovable.Position.Y) < Universe.Epsilon ||
(movable.Position.X > movable.CollisionPoint.X ^ movable.Position.Y < movable.CollisionPoint.Y))
{
//take velocity vector, rotate CCW by 2*collisionAngle, scale it
var rotateAngle = 2 * collisionAngle;
var xPrime = movable.Velocity.X * Math.Cos(rotateAngle) - movable.Velocity.Y * Math.Sin(rotateAngle);
var yPrime = movable.Velocity.Y * Math.Cos(rotateAngle) - movable.Velocity.X * Math.Sin(rotateAngle);
movable.Velocity.X = xPrime;
movable.Velocity.Y = yPrime;
}
else
{
//take the vector, rotate it CCW by 360-2*collisionAngle, scale it
var rotateAngle = 2 * (Math.PI - collisionAngle);
var xPrime = movable.Velocity.X * Math.Cos(rotateAngle) - movable.Velocity.Y * Math.Sin(rotateAngle);
var yPrime = movable.Velocity.Y * Math.Cos(rotateAngle) - movable.Velocity.X * Math.Sin(rotateAngle);
movable.Velocity.X = xPrime;
movable.Velocity.Y = yPrime;
}
movable.Velocity.X *= movable.Material.Elasticity;
movable.Velocity.Y *= movable.Material.Elasticity;
}
I am developing an application which shows driving distances to a certain points from current position of user. There are couple of thousands of coordinate points and the application needs to calculate the distance really fast. Below is the method I'm using.
public async Task<int> findRouteLength(System.Device.Location.GeoCoordinate currentPosition, System.Device.Location.GeoCoordinate businessPosition)
{
List<System.Device.Location.GeoCoordinate> routePositions = new List<System.Device.Location.GeoCoordinate>();
routePositions.Add(currentPosition);
routePositions.Add(businessPosition);
RouteQuery query = new RouteQuery();
query.TravelMode = TravelMode.Driving;
query.Waypoints = routePositions;
Route route = await query.GetRouteAsync();
return route.LengthInMeters;
}
However, this task can only calculate no more than 5-6 distances in one second. Is there any faster way of calculating driving distances in windows phone 8 c# ?
Try this, it should be much faster
public double CalculateDistance(System.Device.Location.GeoCoordinate geo, System.Device.Location.GeoCoordinate geo2)
{
//var R = 6371; // result in km
var R = 6371000; // result in m
var dLat = (geo2.Latitude - geo.Latitude).ToRad();
var dLon = (geo2.Longitude - geo.Longitude).ToRad();
var lat1 = geo.Latitude.ToRad();
var lat2 = geo2.Latitude.ToRad();
var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2);
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return R * c;
}
ToRad extension
static class Ext
{
public static double ToRad(this double val)
{
return (Math.PI / 180) * val;
}
}
I am trying to sort out a method to calculate the distance between 2 points in c#.
This is the code I have been trying though I fear the answer I get is not correct.
static void Main()
{
//postcode australia 2600 -> 3000
float latA = -31.997976f;
float longA = 115.762877f;
float latB = -31.99212f;
float longB = 115.763228f;
decimal distance = (DistanceBetween(latA, latB, longA, longB));
Console.WriteLine("Distance is" + distance);
Console.ReadLine();
}
static decimal DistanceBetween(float latA, float longA, float latB, float longB)
{
var RadianLatA = Math.PI * latA / 180;
var RadianLatb = Math.PI * latB / 180;
var RadianLongA = Math.PI * longA / 180;
var RadianLongB = Math.PI * longB / 180;
double theDistance = (Math.Sin(RadianLatA)) *
Math.Sin(RadianLatb) +
Math.Cos(RadianLatA) *
Math.Cos(RadianLatb) *
Math.Cos(RadianLongA - RadianLongB);
return Convert.ToDecimal(((Math.Acos(theDistance) * (180.0 / Math.PI)))) * 69.09M * 1.6093M;
}
this was adapted from a response found on this site here
Distance between addresses
Any thoughts on what is going wrong/
Thanks
Ryan
The class I usually use is GeoCoordinate
double latA = -31.997976f;
double longA = 115.762877f;
double latB = -31.99212f;
double longB = 115.763228f;
var locA = new GeoCoordinate(latA, longA);
var locB = new GeoCoordinate(latB, longB);
double distance = locA.GetDistanceTo(locB ); // metres
double lat1 = {};
double lat2 = {};
double lon1 = {};
double lon2 = {};
var R = 6376.5000; //Km
lat1 = lat1.ToRad();
lat2 = lat2.ToRad();
lon1 = lon1.ToRad();
lon2 = lon2.ToRad();
var dLat = lat2 - lat1;
var dLon = lon2 - lon1;
var a = Math.Pow(Math.Sin(dLat / 2), 2) + (Math.Pow(Math.Sin(dLon / 2), 2) * Math.Cos(lat1) * Math.Cos(lat2));
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var distance = R * c;
public double ToRad(this double degs) {
return degs * (Math.PI/180.0);
}
Input expects doubles.
This is the haversine formula, it's used to calculate the distances on our globe between two points. This is the distance in a straight line, if you need the distance on a path you will have to find all points on that path and then calculate the distances between each two points and then take the sum of that.
You can use DbGeography for spatial calculation. It has DbGeography.Distance method which is used to calculate the distance between two gps points.
Otherwise, try Ref: Harversine Formula to calculate the distance between two points.
Distance Formula: Given the two points (x1, y1) and (x2, y2), the distance between these points is given by the formula:
use it accordingly