I am in need of a C# solution to some code i have in Javascript, which takes a array of latitude and longitude positions which forms an area or zone. and also an object X and Y position and returns the X and Y of the closest point from the object. This code works perfect in Javascript, however as i am now re-writing my work in C#, i am unable to find a workable solution which works, and does what this function does.
The Javascript function is below, which takes 2 arguments pXy, which is the X and Y position of your location and aXys, which is an array of X and Y positions forming the polylines of an area.
var getClosestPointOnLines = function(pXy, aXys) {
var minDist;
var fTo;
var fFrom;
var x;
var y;
var i;
var dist;
if (aXys.length > 1) {
for (var n = 1 ; n < aXys.length ; n++) {
if (aXys[n].x != aXys[n - 1].x) {
var a = (aXys[n].y - aXys[n - 1].y) / (aXys[n].x - aXys[n - 1].x);
var b = aXys[n].y - a * aXys[n].x;
dist = Math.abs(a * pXy.x + b - pXy.y) / Math.sqrt(a * a + 1);
}
else
dist = Math.abs(pXy.x - aXys[n].x)
// length^2 of line segment
var rl2 = Math.pow(aXys[n].y - aXys[n - 1].y, 2) + Math.pow(aXys[n].x - aXys[n - 1].x, 2);
// distance^2 of pt to end line segment
var ln2 = Math.pow(aXys[n].y - pXy.y, 2) + Math.pow(aXys[n].x - pXy.x, 2);
// distance^2 of pt to begin line segment
var lnm12 = Math.pow(aXys[n - 1].y - pXy.y, 2) + Math.pow(aXys[n - 1].x - pXy.x, 2);
// minimum distance^2 of pt to infinite line
var dist2 = Math.pow(dist, 2);
// calculated length^2 of line segment
var calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.sqrt(Math.min(ln2, lnm12));
if ((minDist == null) || (minDist > dist)) {
if (calcrl2 > rl2) {
if (lnm12 < ln2) {
fTo = 0;//nearer to previous point
fFrom = 1;
}
else {
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else {
// perpendicular from point intersects line segment
fTo = ((Math.sqrt(lnm12 - dist2)) / Math.sqrt(rl2));
fFrom = ((Math.sqrt(ln2 - dist2)) / Math.sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].x - aXys[i].x;
var dy = aXys[i - 1].y - aXys[i].y;
x = aXys[i - 1].x - (dx * fTo);
y = aXys[i - 1].y - (dy * fTo);
}
return { 'x': x, 'y': y, 'i': i, 'fTo': fTo, 'fFrom': fFrom };
}
How can i replicate the above in C#?
Thanks xdtTransform. I was not using Visual Studio so did not realize the Ctrl+Space. After installing it, i have managed to convert the code myself. I have included it here for anyone who will benefit from it in the future.
I started with a class to hold the Latitude and Longitude details of the points.
namespace Classes
{
public class AppGeoPoint
{
public double X { get; set; }
public double Y { get; set; }
}
}
And the function converted
public static Classes.AppGeoPoint getClosestPointOnLines(Classes.AppGeoPoint pXy, Classes.AppGeoPoint[] aXys)
{
double? minDist = null;
double fTo = 0.0;
double fFrom;
double x = 0.0;
double y = 0.0;
int i = 0;
double dist;
if (aXys.Length > 1)
{
for (var n = 1; n < aXys.Length; n++)
{
if (aXys[n].X != aXys[n - 1].X)
{
var a = (aXys[n].Y - aXys[n - 1].Y) / (aXys[n].X - aXys[n - 1].X);
var b = aXys[n].Y - a * aXys[n].X;
dist = Math.Abs(a * pXy.X + b - pXy.Y) / Math.Sqrt(a * a + 1);
}
else
dist = Math.Abs(pXy.X - aXys[n].X);
// length^2 of line segment
double rl2 = Math.Pow(aXys[n].Y - aXys[n - 1].Y, 2) + Math.Pow(aXys[n].X - aXys[n - 1].X, 2);
// distance^2 of pt to end line segment
double ln2 = Math.Pow(aXys[n].Y - pXy.Y, 2) + Math.Pow(aXys[n].X - pXy.X, 2);
// distance^2 of pt to begin line segment
double lnm12 = Math.Pow(aXys[n - 1].Y - pXy.Y, 2) + Math.Pow(aXys[n - 1].X - pXy.X, 2);
// minimum distance^2 of pt to infinite line
double dist2 = Math.Pow(dist, 2);
// calculated length^2 of line segment
double calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.Sqrt(Math.Min(ln2, lnm12));
if ((minDist == null) || (minDist > dist))
{
if (calcrl2 > rl2)
{
if (lnm12 < ln2)
{
fTo = 0;//nearer to previous point
fFrom = 1;
}
else
{
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else
{
// perpendicular from point intersects line segment
fTo = ((Math.Sqrt(lnm12 - dist2)) / Math.Sqrt(rl2));
fFrom = ((Math.Sqrt(ln2 - dist2)) / Math.Sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].X - aXys[i].X;
var dy = aXys[i - 1].Y - aXys[i].Y;
x = aXys[i - 1].X - (dx * fTo);
y = aXys[i - 1].Y - (dy * fTo);
}
return new Classes.AppGeoPoint { X = x, Y = y };
}
Then finally, to build an array list and check for the closest point
Classes.AppGeoPoint YourLocation= new Classes.AppGeoPoint { X = 50.83737, Y = -1.07428 };
Classes.AppGeoPoint[] AreaCheck = new[] {
new Classes.AppGeoPoint { X = 50.847550000000005, Y = -1.0863200000000002 },
new Classes.AppGeoPoint { X = 50.83975, Y = -1.0859800000000002 },
new Classes.AppGeoPoint { X = 50.83845, Y = -1.06487 },
new Classes.AppGeoPoint { X = 50.84723, Y = -1.0645200000000001 }
};
Classes.AppGeoPoint ReturnVal = getClosestPointOnLines(YourLocation, AreaCheck);
Console.WriteLine("X " + ReturnVal.X);
Console.WriteLine("Y " + ReturnVal.Y);
ReturnVal.X and ReturnVal.Y will return the closest points latitude and longitude.
Hopefully, this may come in helpful to others.
Related
So I'm running iterations with this formula:
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2)); With this process: Xn+1 = f(Xn).
And if you start from negative X you will eventually end up with (-/+) infinity, so after 6 iterations I'm supposed to get infinity, but what I got surprised me and I couldn't find anywhere what that is, I got "-?", I've tried comparing it to +/- infinity and tried to compare it to int numbers just to clarify what it is, but I cant get anything out of it, for example, I've tried if ("-?" > 1000) break;, and it doesn't outcome as "true". Neither am I getting any errors by comparing it to int/double, I need to stop iterations when I start going into infinity, how can I do that?
code:
public static double CalculateX1(double x1, double x2)
{
double x = 10 / 0.25 * ((0.0002 * x1 * (10 - 0.25 * x1)) + 0.00217 * x2 * (20 - 0.25 * x2));
return x;
}
public static double CalculateX2(double x2, double x1)
{
double y = 20 / 0.25 * ((0.00052 * x2 * (20 - 0.25 * x2)) + 0.0075 * x1 * (10 - 0.25 * x1));
return y;
}
static void Main(string[] args)
{
string writePath = #"C:\Users\evluc\Desktop\cord.txt";
double X = -5;
double Y = -5;
int pointer = 1;
double[,] coordinates = new double[10001, 2];
coordinates[0, 0] = X;
coordinates[0, 1] = Y;
for (int i = 0; i < 5000; i++)
{
//double XTemp = CalculateX1(X, Y);
//double YTemp = CalculateX2(Y, X);
//X = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
//Y = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
coordinates[pointer, 0] = CalculateX1(coordinates[pointer - 1, 0], coordinates[pointer - 1, 1]);
coordinates[pointer, 1] = CalculateX2(coordinates[pointer - 1, 1], coordinates[pointer - 1, 0]);
pointer++;
if (Math.Abs(coordinates[pointer, 0]) > 1000 || Math.Abs(coordinates[pointer, 1]) > 1000)
{
Console.WriteLine("infinity");
Console.ReadKey();
}
}
for (int i = 0; i < 5000; i++)
{
Console.WriteLine("X = " + coordinates[i, 0] + "," + "Y = " + coordinates[i, 1] + "; ");
}
}
I think whatever you use to display/inspect the value cannot print ∞.
double d = double.MinValue;
d *= 2;
Console.WriteLine($"{d}: IsInfinity: {double.IsNegativeInfinity(d)}");
-∞: IsInfinity: True
Stopping at infinity
Here's a loop that stops at infinity:
double d = 2;
var i = 1;
while(!double.IsInfinity(d))
{
d = i*d*d;
i = -i;
}
Console.WriteLine(d);
-∞
I need to interpolate whole 2d array in with c#.
I managed to write an interpolation class. It should work as intpl2 function of matlab.
slice: is the 2d array that going to be interpolated
xaxis: interpolated x axis
yaxis: interpolated y axis
It maps as
v0 v1 | v3 v2
EDIT: Solve the issue, but I am open to more elegant solution :)
public static float[,] ArrayBilinear(float[,] slice, float[] xaxis, float[] yaxis)
{
float[,] scaledSlice = new float[xaxis.Length, yaxis.Length];
double xscale = ((xaxis.Length - 1) / (slice.GetLength(0) - 1));
double yscale = ((yaxis.Length - 1) / (slice.GetLength(1) - 1));
for (int x = 0; x < scaledSlice.GetLength(0) ; x++)
{
for (int y = 0; y < scaledSlice.GetLength(1) ; y++)
{
float gx = ((float)x) / xaxis.Length * (slice.GetLength(0) - 1);
float gy = ((float)y) / yaxis.Length * (slice.GetLength(1) - 1);
int xInOriginal = (int)gx;
int yInOriginal = (int)gy;
double v0 = slice[xInOriginal, yInOriginal];
double v1 = slice[xInOriginal + 1, yInOriginal];
double v2 = slice[xInOriginal + 1, yInOriginal + 1];
double v3 = slice[xInOriginal, yInOriginal + 1];
double newValue = (1 - GetScale(xscale, x)) * (1 - GetScale(yscale, y)) * v0 + GetScale(xscale, x) * (1 - GetScale(yscale, y)) * v1 + GetScale(xscale, x) * GetScale(yscale, y) * v2 + (1 - GetScale(xscale, x)) * GetScale(yscale, y) * v3;
scaledSlice[x, y] = (float)newValue;
}
}
return scaledSlice;
}
private static double GetScale(double scale, int i)
{
if (i == 0)
return 0;
if (i % scale > 0)
return (i % scale) / scale;
return 1.0;
}
public static float[] LinSpace(float start, float stop, int length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
if (length == 0) return new float[0];
if (length == 1) return new[] { stop };
float step = (stop - start) / (length - 1);
var data = new float[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = start + i * step;
}
data[data.Length - 1] = stop;
return data;
}
Test with random 2d array
[Test]
public void testBilinearInterpolation()
{
float[,] array2D = new float[4, 4] { { 0, 0, 0, 5 }, { 1, 1, 4, 0 }, { 0, 1, 3, 1 }, { 0, 4, 0, 1 } };
var xaxes = LinSpace(0, 3, 10);
var yaxes = LinSpace(0, 3, 10);
var intepolatedarr = ArrayBilinear(array2D, xaxes , yaxes);
}
The interpolation result is wrong (Different from interp2 from matlab) I couldn't found why.
I have 2 lines. Both lines containing their 2 points of X and Y. This means they both have length.
I see 2 formulas, one using determinants and one using normal algebra. Which would be the most efficient to calculate and what does the formula looks like?
I'm having a hard time using matrices in code.
This is what I have so far, can it be more efficient?
public static Vector3 Intersect(Vector3 line1V1, Vector3 line1V2, Vector3 line2V1, Vector3 line2V2)
{
//Line1
float A1 = line1V2.Y - line1V1.Y;
float B1 = line1V1.X - line1V2.X;
float C1 = A1*line1V1.X + B1*line1V1.Y;
//Line2
float A2 = line2V2.Y - line2V1.Y;
float B2 = line2V1.X - line2V2.X;
float C2 = A2 * line2V1.X + B2 * line2V1.Y;
float det = A1*B2 - A2*B1;
if (det == 0)
{
return null;//parallel lines
}
else
{
float x = (B2*C1 - B1*C2)/det;
float y = (A1 * C2 - A2 * C1) / det;
return new Vector3(x,y,0);
}
}
Assuming you have two lines of the form Ax + By = C, you can find it pretty easily:
float delta = A1 * B2 - A2 * B1;
if (delta == 0)
throw new ArgumentException("Lines are parallel");
float x = (B2 * C1 - B1 * C2) / delta;
float y = (A1 * C2 - A2 * C1) / delta;
Pulled from here
I recently went back on paper to find a solution to this problem using basic algebra. We just need to solve the equations formed by the two lines and if a valid solution exist then there is an intersection.
You can check my Github repository for extended implementation handling potential precision issue with double and tests.
public struct Line
{
public double x1 { get; set; }
public double y1 { get; set; }
public double x2 { get; set; }
public double y2 { get; set; }
}
public struct Point
{
public double x { get; set; }
public double y { get; set; }
}
public class LineIntersection
{
// Returns Point of intersection if do intersect otherwise default Point (null)
public static Point FindIntersection(Line lineA, Line lineB, double tolerance = 0.001)
{
double x1 = lineA.x1, y1 = lineA.y1;
double x2 = lineA.x2, y2 = lineA.y2;
double x3 = lineB.x1, y3 = lineB.y1;
double x4 = lineB.x2, y4 = lineB.y2;
// equations of the form x=c (two vertical lines) with overlapping
if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance && Math.Abs(x1 - x3) < tolerance)
{
throw new Exception("Both lines overlap vertically, ambiguous intersection points.");
}
//equations of the form y=c (two horizontal lines) with overlapping
if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance && Math.Abs(y1 - y3) < tolerance)
{
throw new Exception("Both lines overlap horizontally, ambiguous intersection points.");
}
//equations of the form x=c (two vertical parallel lines)
if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance)
{
//return default (no intersection)
return default(Point);
}
//equations of the form y=c (two horizontal parallel lines)
if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance)
{
//return default (no intersection)
return default(Point);
}
//general equation of line is y = mx + c where m is the slope
//assume equation of line 1 as y1 = m1x1 + c1
//=> -m1x1 + y1 = c1 ----(1)
//assume equation of line 2 as y2 = m2x2 + c2
//=> -m2x2 + y2 = c2 -----(2)
//if line 1 and 2 intersect then x1=x2=x & y1=y2=y where (x,y) is the intersection point
//so we will get below two equations
//-m1x + y = c1 --------(3)
//-m2x + y = c2 --------(4)
double x, y;
//lineA is vertical x1 = x2
//slope will be infinity
//so lets derive another solution
if (Math.Abs(x1 - x2) < tolerance)
{
//compute slope of line 2 (m2) and c2
double m2 = (y4 - y3) / (x4 - x3);
double c2 = -m2 * x3 + y3;
//equation of vertical line is x = c
//if line 1 and 2 intersect then x1=c1=x
//subsitute x=x1 in (4) => -m2x1 + y = c2
// => y = c2 + m2x1
x = x1;
y = c2 + m2 * x1;
}
//lineB is vertical x3 = x4
//slope will be infinity
//so lets derive another solution
else if (Math.Abs(x3 - x4) < tolerance)
{
//compute slope of line 1 (m1) and c2
double m1 = (y2 - y1) / (x2 - x1);
double c1 = -m1 * x1 + y1;
//equation of vertical line is x = c
//if line 1 and 2 intersect then x3=c3=x
//subsitute x=x3 in (3) => -m1x3 + y = c1
// => y = c1 + m1x3
x = x3;
y = c1 + m1 * x3;
}
//lineA & lineB are not vertical
//(could be horizontal we can handle it with slope = 0)
else
{
//compute slope of line 1 (m1) and c2
double m1 = (y2 - y1) / (x2 - x1);
double c1 = -m1 * x1 + y1;
//compute slope of line 2 (m2) and c2
double m2 = (y4 - y3) / (x4 - x3);
double c2 = -m2 * x3 + y3;
//solving equations (3) & (4) => x = (c1-c2)/(m2-m1)
//plugging x value in equation (4) => y = c2 + m2 * x
x = (c1 - c2) / (m2 - m1);
y = c2 + m2 * x;
//verify by plugging intersection point (x, y)
//in orginal equations (1) & (2) to see if they intersect
//otherwise x,y values will not be finite and will fail this check
if (!(Math.Abs(-m1 * x + y - c1) < tolerance
&& Math.Abs(-m2 * x + y - c2) < tolerance))
{
//return default (no intersection)
return default(Point);
}
}
//x,y can intersect outside the line segment since line is infinitely long
//so finally check if x, y is within both the line segments
if (IsInsideLine(lineA, x, y) &&
IsInsideLine(lineB, x, y))
{
return new Point { x = x, y = y };
}
//return default (no intersection)
return default(Point);
}
// Returns true if given point(x,y) is inside the given line segment
private static bool IsInsideLine(Line line, double x, double y)
{
return (x >= line.x1 && x <= line.x2
|| x >= line.x2 && x <= line.x1)
&& (y >= line.y1 && y <= line.y2
|| y >= line.y2 && y <= line.y1);
}
}
How to find intersection of two lines/segments/ray with rectangle
public class LineEquation{
public LineEquation(Point start, Point end){
Start = start;
End = end;
IsVertical = Math.Abs(End.X - start.X) < 0.00001f;
M = (End.Y - Start.Y)/(End.X - Start.X);
A = -M;
B = 1;
C = Start.Y - M*Start.X;
}
public bool IsVertical { get; private set; }
public double M { get; private set; }
public Point Start { get; private set; }
public Point End { get; private set; }
public double A { get; private set; }
public double B { get; private set; }
public double C { get; private set; }
public bool IntersectsWithLine(LineEquation otherLine, out Point intersectionPoint){
intersectionPoint = new Point(0, 0);
if (IsVertical && otherLine.IsVertical)
return false;
if (IsVertical || otherLine.IsVertical){
intersectionPoint = GetIntersectionPointIfOneIsVertical(otherLine, this);
return true;
}
double delta = A*otherLine.B - otherLine.A*B;
bool hasIntersection = Math.Abs(delta - 0) > 0.0001f;
if (hasIntersection){
double x = (otherLine.B*C - B*otherLine.C)/delta;
double y = (A*otherLine.C - otherLine.A*C)/delta;
intersectionPoint = new Point(x, y);
}
return hasIntersection;
}
private static Point GetIntersectionPointIfOneIsVertical(LineEquation line1, LineEquation line2){
LineEquation verticalLine = line2.IsVertical ? line2 : line1;
LineEquation nonVerticalLine = line2.IsVertical ? line1 : line2;
double y = (verticalLine.Start.X - nonVerticalLine.Start.X)*
(nonVerticalLine.End.Y - nonVerticalLine.Start.Y)/
((nonVerticalLine.End.X - nonVerticalLine.Start.X)) +
nonVerticalLine.Start.Y;
double x = line1.IsVertical ? line1.Start.X : line2.Start.X;
return new Point(x, y);
}
public bool IntersectWithSegementOfLine(LineEquation otherLine, out Point intersectionPoint){
bool hasIntersection = IntersectsWithLine(otherLine, out intersectionPoint);
if (hasIntersection)
return intersectionPoint.IsBetweenTwoPoints(otherLine.Start, otherLine.End);
return false;
}
public bool GetIntersectionLineForRay(Rect rectangle, out LineEquation intersectionLine){
if (Start == End){
intersectionLine = null;
return false;
}
IEnumerable<LineEquation> lines = rectangle.GetLinesForRectangle();
intersectionLine = new LineEquation(new Point(0, 0), new Point(0, 0));
var intersections = new Dictionary<LineEquation, Point>();
foreach (LineEquation equation in lines){
Point point;
if (IntersectWithSegementOfLine(equation, out point))
intersections[equation] = point;
}
if (!intersections.Any())
return false;
var intersectionPoints = new SortedDictionary<double, Point>();
foreach (var intersection in intersections){
if (End.IsBetweenTwoPoints(Start, intersection.Value) ||
intersection.Value.IsBetweenTwoPoints(Start, End)){
double distanceToPoint = Start.DistanceToPoint(intersection.Value);
intersectionPoints[distanceToPoint] = intersection.Value;
}
}
if (intersectionPoints.Count == 1){
Point endPoint = intersectionPoints.First().Value;
intersectionLine = new LineEquation(Start, endPoint);
return true;
}
if (intersectionPoints.Count == 2){
Point start = intersectionPoints.First().Value;
Point end = intersectionPoints.Last().Value;
intersectionLine = new LineEquation(start, end);
return true;
}
return false;
}
public override string ToString(){
return "[" + Start + "], [" + End + "]";
}
}
full sample is described [here][1]
I got an array of data voltages and I want to get the RMS value from the FFT that has been applied before to that data. I've seen that RMS in time domain should be equal to RMS(fft) / sqrt(nFFT) from Parseval's Theorem, but gives me different results. I'm using these functions:
1)FFT
public static VectorDPoint FFT(double[] trama, double samplingFreq)
{
double fs = samplingFreq; // Sampling frequency
double t1 = 1 / fs; // Sample time
int l = trama.Length; // Length of signal
// Time vector
//Vector t = Normal(0, l, 1) * t1;
//// Values vector
//Vector y = new Vector(trama);
// We just use half of the data as the other half is simetric. The middle is found in NFFT/2 + 1
int nFFT = (int)Math.Pow(2, NextPow2(l));
if (nFFT > 655600)
{ }
// Create complex array for FFT transformation. Use 0s for imaginary part
Complex[] samples = new Complex[nFFT];
for (int i = 0; i < nFFT; i++)
{
if (i >= trama.Length)
{
samples[i] = new MathNet.Numerics.Complex(0, 0);
}
else
{
samples[i] = new MathNet.Numerics.Complex(trama[i], 0);
}
}
ComplexFourierTransformation fft = new ComplexFourierTransformation(TransformationConvention.Matlab);
fft.TransformForward(samples);
ComplexVector s = new ComplexVector(samples);
s = s / l;
Vector f = (fs / 2.0) * Linspace(0, 1, (nFFT / 2) + 1);
VectorDPoint result = new VectorDPoint();
for (int i = 0; i < (nFFT / 2) + 1; i++)
{
result.Add(new DPoint(f[i], 2 * s[i].Modulus));
}
s = null;
f = null;
samples = null;
return result;
2) RMS
public static double RMSCalculate(double[] channelValues, int samplesNumber, double sampleRate, DateTime currentDate)
{
double[] times = new double[channelValues.Length];
double sampleTime = 0.0;
double period = 0;
times[0] = currentDate.Second + currentDate.Millisecond / 1000.0;
sampleTime = 1 / sampleRate; //s
// Limited samples
for (int i = 1; i < channelValues.Length; i++)
{
times[i] = times[i - 1] + sampleTime;
}
DPoint RMSValues = new DPoint();
RMSValues.Y = 0;
if (channelValues.Length == 1)
{
double x = channelValues[0];
double y = channelValues[0];
RMSValues = new DPoint(x, Math.Abs(y));
}
else
{
for (int i = 0; i < times.Length - 1; i++)
{
period = 0;
if (i + 1 < times.Length)
{
RMSValues.Y += channelValues[i + 1] * channelValues[i + 1] * (times[i + 1] - times[i]);
}
}
period = times[times.Length - 1] - times[0];
RMSValues.Y = RMSValues.Y / period;
RMSValues.Y = Math.Sqrt(RMSValues.Y);
}
return RMSValues.Y;
}
I am trying to draw curves a specified distance away from a curve. Kind of like the sides of roads are always a set distance away from the yellow lines in the center. I have code to do this, however, when done using my code it ends up with overlap in one of the curves.
Here is my code:
for (int i = 0; i < curves.Count; i++)
{
for (float j = 0; j < 1; j += .001f)
{
Vector2 temp = Vector2.CatmullRom(curves[i].Points[0], curves[i].Points[1], curves[i].Points[2], curves[i].Points[3], j);
if (mid.Count != 0)
{
if (temp != mid[mid.Count - 1])
{
mid.Add(temp);
}
else Console.WriteLine(temp == mid[mid.Count - 1]);
}
else mid.Add(temp);
}
}
for (int i = 0; i < mid.Count; i++)
{
if (i == 0)
{
Vector2 slope = mid[i] - mid[i + 1];
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
else if (i < mid.Count - 1)
{
Vector2 slope1 = mid[i] - mid[i - 1],
slope2 = mid[i + 1] - mid[i];
Vector2 slope = (slope1 + slope2) / 2;
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
else
{
Vector2 slope = mid[i] - mid[i - 1];
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
}
And here is a photo of the result:
Curves with overlap
Any and all help would be appreciated.