I know how to use the javascript to calculate the radius by using the below code
var center = new google.maps.LatLng(3.2987599, 102.6872022);
var latLng = new google.maps.LatLng(3.0987599, 101.6872022);
var distanceInMetres = google.maps.geometry.spherical.computeDistanceBetween(center, latLng);
But how to convert the google.maps.geometry.spherical.computeDistanceBetween into C# function?
Distance between 2 points: (lat1,lon1) to (lat2,lon2)
distance = acos(
cos(lat1 * (PI()/180)) *
cos(lon1 * (PI()/180)) *
cos(lat2 * (PI()/180)) *
cos(lon2 * (PI()/180))
+
cos(lat1 * (PI()/180)) *
sin(lon1 * (PI()/180)) *
cos(lat2 * (PI()/180)) *
sin(lon2 * (PI()/180))
+
sin(lat1 * (PI()/180)) *
sin(lat2 * (PI()/180))
) * 3959
3959 is the Earth radius in Miles. Replace this value with
radius in KM, (or any other unit), to get results on the same unit.
You can verify your implementation by comparing to this worked example:
i have write the C# solution to calculate the distance to convert
var distanceInMetres = google.maps.geometry.spherical.computeDistanceBetween(center, latLng);
into C#. Below is the code i have using. 6371 is the radius of the Earth.
//Calculate distance earth between 2 coordinate point
double e = lat * (Math.PI / 180);
double f = lng * (Math.PI / 180);
double g = lat2 * (Math.PI / 180);
double h = lng2 * (Math.PI / 180);
double i =
(Math.Cos(e) * Math.Cos(g) * Math.Cos(f) * Math.Cos(h)
+ Math.Cos(e) * Math.Sin(f) * Math.Cos(g) * Math.Sin(h)
+ Math.Sin(e) * Math.Sin(g));
double j = Math.Acos(i);
double k = (6371 * j); //Distance in KM
The distance between 2 lat/long points can be calculated with the haversine formula, which is described here http://en.wikipedia.org/wiki/Haversine_formula
There also is another question here at stackoverflow about more or less the same issue: Calculate distance between two latitude-longitude points? (Haversine formula)
Related
I am currently using powerpivot and I added a column to create a calculated field for all rows. The purpose of the function is to find the distance between two zip codes by takin their Latitude and Longitude; this function always works in excel worksheets but when I attempt to use the same function in power query, it does not work. The reason why I'm using power query for this function is because the data set is over 4,000,000 rows...
I'm using the function below and it returns as "#ERROR"
=ACOS(COS(RADIANS(90-'Origin vs Destination w PKG'[Latitude]))*COS(RADIANS(90-'Origin vs Destination w PKG'[DLatitude]))+SIN(RADIANS(90-'Origin vs Destination w PKG'[Latitude]))*SIN(RADIANS(90-'Origin vs Destination w PKG'[DLatitude]))*COS(RADIANS('Origin vs Destination w PKG'[Longitude]-'Origin vs Destination w PKG'[DLongitude])))*3958.8
Above is the function. Does anyone know how to get the distance function between two coordinates to work in PowerPivot?
Thanks a lot
Assuming Table1 has 4 columns [Latitude_1], [Longitude_1], [Latitude_2], [Longitude_2] and the coordinates are in decimal [38.892456, -74.0247852] then code below generates the distance between the locations in miles (change 3959 to 6371 for kilometers) using the formula:
=ACOS(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*3959
which in powerquery code is:
= Number.Acos(Number.Sin(([Latitude_1] / 180) * Number.PI) * Number.Sin(([Latitude_2] / 180) * Number.PI) + Number.Cos(([Latitude_1] / 180) * Number.PI) * Number.Cos(([Latitude_2] / 180) * Number.PI) * Number.Cos( ([Longitude_2] / 180) * Number.PI-([Longitude_1] / 180) * Number.PI)) * 3959)
full code sample:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "DistanceMiles", each Number.Acos(Number.Sin(([Latitude_1] / 180) * Number.PI) * Number.Sin(([Latitude_2] / 180) * Number.PI) + Number.Cos(([Latitude_1] / 180) * Number.PI) * Number.Cos(([Latitude_2] / 180) * Number.PI) * Number.Cos( ([Longitude_2] / 180) * Number.PI-([Longitude_1] / 180) * Number.PI)) * 3959),
in #"Added Custom"
I'm trying to draw an SVG path in a PDF using itextsharp v5.
The approach I am following is roughly this:
Reading the SVG path from the SVG file (Svg.SvgPath)
Getting the list of segments from the path ({Svg.Pathing.SvgPathSegmentList})
Creating an iTextSharp PdfAnnotation and associate a PdfAppearance to it
Drawing each segment in the SvgPathSegmentList using the corresponding PdfContentByte method ( for SvgLineSegment I use PdfContentByte.LineTo, for SvgCubicCurveSegment I use PdfContentByte.CurveTo )
For most of the SvgPathSegments types, there is a clear mapping between values in the SvgPathSegments and the arguments in the PdfContentByte method. A few examples:
SvgMoveToSegment has the attribute End which is the target point (X, Y) and the PdfContentByte.MoveTo takes two parameters: X, Y
SvgLineSegment, very similar to the Move. It has the Target End and the PdfContentByte.LineTo takes two parameters X and Y and draws a line from the current position to the target point.
app.MoveTo(segment.Start.X, segment.Start.Y);
SvgCubicCurveSegment has all you need to create a Bezier curve (The Start point, the End point, and the first and second control point). With this I use PdfContentByte.CurveTo and get a curve in the PDF that looks exactly as it looks in the SVG editor.
var cubicCurve = (Svg.Pathing.SvgCubicCurveSegment)segment;
app.CurveTo(
cubicCurve.FirstControlPoint.X, cubicCurve.FirstControlPoint.Y,
cubicCurve.SecondControlPoint.X, cubicCurve.SecondControlPoint.Y,
cubicCurve.End.X, cubicCurve.End.Y);
The problem I have is with the ARC ("A" command in the SVG, SvgArcSegment)
The SvgArcSegment has the following values:
Angle
Start (X, Y)
End (X, Y)
RadiusX
RadiusY
Start
Sweep
On the other hand, PdfContentByte.Arc method expect:
X1, X2, Y1, Y2
StartAngle,
Extent
As per the itextsharp documentation, Arc draws a partial ellipse inscribed within the rectangle x1,y1,x2,y2 starting (counter-clockwise) at StartAngle degrees and covering extent degrees. I.e. startAng=0 and extent=180 yield an openside-down semi-circle inscribed in the rectangle.
My question is: How to "map" the values in the SvgArcSegment created from the SVG A command into the arguments that PdfContentByte.Arc method expects.
I know that the Start and End values are indeed the origin and target of the curve I want, but no clue what RadiusX and RadiusY mean.
As #RobertLongson pointed in his comment, what I needed was to convert from Center to Endpoint Parametrization.
I'm posting my own C# implementation of the algorithm documented in the SVG documentation, just in case someone else needs it.
public static SvgCenterParameters EndPointToCenterParametrization(Svg.Pathing.SvgArcSegment arc)
{
//// Conversion from endpoint to center parameterization as in SVG Implementation Notes:
//// https://www.w3.org/TR/SVG11/implnote.html#ArcConversionEndpointToCenter
var sinA = Math.Sin(arc.Angle);
var cosA = Math.Cos(arc.Angle);
//// Large arc flag
var fA = arc.Size == Svg.Pathing.SvgArcSize.Large ? 1 : 0;
//// Sweep flag
var fS = arc.Sweep == Svg.Pathing.SvgArcSweep.Positive ? 1 : 0;
var radiusX = arc.RadiusX;
var radiusY = arc.RadiusY;
var x1 = arc.Start.X;
var y1 = arc.Start.Y;
var x2 = arc.End.X;
var y2 = arc.End.Y;
/*
*
* Step 1: Compute (x1′, y1′)
*
*/
//// Median between Start and End
var midPointX = (x1 - x2) / 2;
var midPointY = (y1 - y2) / 2;
var x1p = (cosA * midPointX) + (sinA * midPointY);
var y1p = (cosA * midPointY) - (sinA * midPointX);
/*
*
* Step 2: Compute (cx′, cy′)
*
*/
var rxry_2 = Math.Pow(radiusX, 2) * Math.Pow(radiusY, 2);
var rxy1p_2 = Math.Pow(radiusX, 2) * Math.Pow(y1p, 2);
var ryx1p_2 = Math.Pow(radiusY, 2) * Math.Pow(x1p, 2);
var sqrt = Math.Sqrt(Math.Abs(rxry_2 - rxy1p_2 - ryx1p_2) / (rxy1p_2 + ryx1p_2));
if (fA == fS)
{
sqrt = -sqrt;
}
var cXP = sqrt * (radiusX * y1p / radiusY);
var cYP = sqrt * -(radiusY * x1p / radiusX);
/*
*
* Step 3: Compute (cx, cy) from (cx′, cy′)
*
*/
var cX = (cosA * cXP) - (sinA * cYP) + ((x1 + x2) / 2);
var cY = (sinA * cXP) + (cosA * cYP) + ((y1 + y2) / 2);
/*
*
* Step 4: Compute θ1 and Δθ
*
*/
var x1pcxp_rx = (float)(x1p - cXP) / radiusX;
var y1pcyp_ry = (float)(y1p - cYP) / radiusY;
Vector2 vector1 = new Vector2(1f, 0f);
Vector2 vector2 = new Vector2(x1pcxp_rx, y1pcyp_ry);
var angle = Math.Acos(((vector1.x * vector2.x) + (vector1.y * vector2.y)) / (Math.Sqrt((vector1.x * vector1.x) + (vector1.y * vector1.y)) * Math.Sqrt((vector2.x * vector2.x) + (vector2.y * vector2.y)))) * (180 / Math.PI);
if (((vector1.x * vector2.y) - (vector1.y * vector2.x)) < 0)
{
angle = angle * -1;
}
var vector3 = new Vector2(x1pcxp_rx, y1pcyp_ry);
var vector4 = new Vector2((float)(-x1p - cXP) / radiusX, (float)(-y1p - cYP) / radiusY);
var extent = (Math.Acos(((vector3.x * vector4.x) + (vector3.y * vector4.y)) / Math.Sqrt((vector3.x * vector3.x) + (vector3.y * vector3.y)) * Math.Sqrt((vector4.x * vector4.x) + (vector4.y * vector4.y))) * (180 / Math.PI)) % 360;
if (((vector3.x * vector4.y) - (vector3.y * vector4.x)) < 0)
{
extent = extent * -1;
}
if (fS == 1 && extent < 0)
{
extent = extent + 360;
}
if (fS == 0 && extent > 0)
{
extent = extent - 360;
}
var rectLL_X = cX - radiusX;
var rectLL_Y = cY - radiusY;
var rectUR_X = cX + radiusX;
var rectUR_Y = cY + radiusY;
return new SvgCenterParameters
{
LlX = (float)rectLL_X,
LlY = (float)rectLL_Y,
UrX = (float)rectUR_X,
UrY = (float)rectUR_Y,
Angle = (float)angle,
Extent = (float)extent
};
}
I was going through some collision detection tutorials on youtube, In one of the tutorial, the guy used the following code to resolve a collision between two balls:
/**
* Rotates coordinate system for velocities
*
* Takes velocities and alters them as if the coordinate system they're on was rotated
*
* #param Object | velocity | The velocity of an individual particle
* #param Float | angle | The angle of collision between two objects in radians
* #return Object | The altered x and y velocities after the coordinate system has been rotated
*/
function rotate(velocity, angle) {
const rotatedVelocities = {
x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
};
return rotatedVelocities;
}
/**
* Swaps out two colliding particles' x and y velocities after running through
* an elastic collision reaction equation
*
* #param Object | particle | A particle object with x and y coordinates, plus velocity
* #param Object | otherParticle | A particle object with x and y coordinates, plus velocity
* #return Null | Does not return a value
*/
function resolveCollision(particle, otherParticle) {
const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;
const xDist = otherParticle.x - particle.x;
const yDist = otherParticle.y - particle.y;
// Prevent accidental overlap of particles
if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
// Grab angle between the two colliding particles
const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);
// Store mass in var for better readability in collision equation
const m1 = particle.mass;
const m2 = otherParticle.mass;
// Velocity before equation
const u1 = rotate(particle.velocity, angle);
const u2 = rotate(otherParticle.velocity, angle);
// Velocity after 1d collision equation
const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };
// Final velocity after rotating axis back to original location
const vFinal1 = rotate(v1, -angle);
const vFinal2 = rotate(v2, -angle);
// Swap particle velocities for realistic bounce effect
particle.velocity.x = vFinal1.x;
particle.velocity.y = vFinal1.y;
otherParticle.velocity.x = vFinal2.x;
otherParticle.velocity.y = vFinal2.y;
}
}
I've mostly understood this code. However, I'm unable to understand how this if condition is working to find out whether the balls have overlapped or not.
if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0)
Can somebody please explain?
By taking the differences of positions and velocities, you view everything in the frame of otherParticle. In that frame, otherParticle is standing still at the origin and particle is moving with velocityDiff. Here is how it looks like:
The term xVelocityDiff * xDist + yVelocityDiff * yDist is the dot product of the two vectors. This dot product is negative if velocityDiff points somewhat in the opposite direction of dist, i.e. if the particle is getting closer like in the above image. If the dot product is positive, the particle is moving away from otherParticle and you don't need to do anything.
Hope I'm posting this in the right section, apologys if not.
I have a expression that I use on an objects position in After Effects:
radius = 35;
startAngle = degreesToRadians(180);
T = 22;
angularSpeed = 2 * 3.1415926 / T;
xt =1082 + radius * Math.cos(angularSpeed * time + startAngle);
yt = 536 + radius * Math.sin(angularSpeed * time + startAngle);
[xt, yt]
My questions, is how do I make it go counter clockwise as oppsoed to cloackwise?
Any help appreciated,
Ian
I have to implement simple ray tracing algorithm, but I can not figure out How can I get Normal Vector of the sphere If I have the origin and radius of the sphere and the direction of the ray.
thanks
Wiki aboute sphere but i can not figure it out of this
I have find the solution: here is the code in C#:
Double alpha = Math.Asin(sphere.Radius / (Math.Sqrt(Math.Pow(sphere.Origin.X-ray.Origin.X,2)+Math.Pow(sphere.Origin.Y-ray.Origin.Y,2)+Math.Pow(sphere.Origin.Z-ray.Origin.Z,2))));
Double beta = Math.Acos((ray.Direction * (sphere.Origin - ray.Origin)) / (ray.Direction.Length * (sphere.Origin - ray.Origin).Length));
ray.HitParam = VypA(sphere.Origin - ray.Origin, beta, sphere.Radius) / ray.Direction.Length;
Vector4 g = ray.Origin + ray.Direction * ray.HitParam;
ray.HitNormal = (g - sphere.Origin).Normalized;
////the VypA function
public static Double VypA(Vector4 b, Double beta, Double radius)
{
return b.Length * (Math.Cos(beta) - Math.Sqrt(((radius * radius) / (b.Length2) - (Math.Sin(beta) * (Math.Sin(beta))))));
}