I am trying to make a determinat calculator using mathematical Cramer's theorem, as you can see I translated the theorem into code convertedString = Convert.ToString (x * y1 * 1 + x1 * y2 * 1 + x2 * x * y - (1 * y1 * x2 + 1 * y2 * y + 1 * y * x1));All good until I am at the point where I need to compute 2 unknown numbers, I don't know how to "tell" in code to the computer that x + x = 2x or 3y-y = 2y, so I tought that if I convert the Crammer's equation into a string I can find all the matches like x + x or y + 2y or y * y and begin from that a solution that can solve my initial problem, like if I find an x * x pattern I will tell the pc through an if statement or something that the pattern x * x is x^2.
So that being said, I want to find out the number of specific sequences like X * y or y + x that are present in a string, I did try some foreach loops and for loops but I can't get it to work and I don't know how should I approach the problem next, plase help.
Here is my code:
using System;
using InputMath;
namespace MathWizard
{
class Determinants
{
//Determinant of a first point and a second graphical point on the xoy axis.
public static void BasicDeterminant()
{
float x;
float y;
float x1 = Input.x1;
float y1 = Input.y1;
float x2 = Input.x2;
float y2 = Input.y2;
float result;
string convertedString;
string pointsValue;
string[] point;
Console.WriteLine("Please introduce the 2 graphical points ( A and B) \n in the order x1 y1 x2 y2, separated by a space ");
pointsValue = Console.ReadLine();
point = pointsValue.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
x1 = Convert.ToInt32(point[0]);
y1 = Convert.ToInt32(point[1]);
x2 = Convert.ToInt32(point[2]);
y2 = Convert.ToInt32(point[3]);
//The Cramer's Rule for solving a 2 points determinant ( P1(x1,y1) and P2(x2,y2)
convertedString = Convert.ToString (x * y1 * 1 + x1 * y2 * 1 + x2 * x * y - (1 * y1 * x2 + 1 * y2 * y + 1 * y * x1));
}
}
}
You could also use the following regex which will find x*y with case insensitivity for each operator:
string pattern = /(x(\*|\+|\-|\/|\^)y)/gi;
then you could do some string.Contains(pattern); to check. Let me know if this helps.
Edit: Updated Pattern
Updated the pattern so that it will also allow variables such as y9 or X10. Any single character (x or y) followed by any amount of numbers.
string pattern =/(x\d*(\*|\+|\-|\/|\^)y\d*)/gi; // could match X1*y9
This doesn't account for whitespaces so you could use some .replace() to get rid of whitespace or use .split(/\s/) and get a string array without whitespace before using this pattern.
bool found = false;
int xyCount = 0;
if(convertedString.Contains("X*Y")){
found = true;
xyCount++;
//makes a substring without the first case of the "X*Y"
string s = convertedString.SubString(convertedString.IndexOf("X*Y"))
if(s.Contains("X*Y")){
xyCount++;
}
Its probably not the best way to do it, but you can probably make a better method doing something like this
Suppose I have two points, int x1, x2, where x1 can be larger, smaller or equal to x2. I want to generate all integer numbers between those two points inclusive (starting with x1 and ending with x2), or just value of x1 if both two points are equal. Is there any elegant way to generate IEnumerable<int> with those values?
You can use this iterator block:
IEnumerable<int> CreateRange(int x1, int x2) {
var increment = x2 > x1 ? 1 : -1;
for (var i = x1; i != x2; i += increment)
yield return i;
yield return x2;
}
It's efficient and creating a range is just as clean as using Enumerable.Range:
CreateRange(10, 5).Select( ... )
If you want to stick with single LINQ statement -
Enumerable.Range(0, Math.Abs(x2 - x1) + 1).Select(i => x1 + i * Math.Sign(x2 - x1))
You can do something like this:
//normal order works
int x1 = 5;
int x2 = 10;
int len = Math.Abs(x2 - x1) + 1;
var range = x1 < x2 ? Enumerable.Range(x1, len) : Enumerable.Range(x2, len).Reverse();
//reverse order works (the same code for range)
x1 = 10;
x2 = 5;
len = Math.Abs(x2 - x1) + 1;
range = x1 < x2 ? Enumerable.Range(x1, len) : Enumerable.Range(x2, len).Reverse();
I have a c# function that contains formula to calculate euclidean distance of some points. I got the point's position defined by R(rx,ry) and L(lx,ly).
at first, I tried to write the code like this:
double dRightLeft = Math.Sqrt((Math.Pow(rx - lx, 2) + Math.Pow(ry - ly, 2)));
it returns 0.0.
then I tried to split the variable to check where did I do wrong, like this:
double rl = (Math.Pow(rx - lx, 2) + Math.Pow(ry - ly, 2));
double dRightLeft = Math.Sqrt(rl);
the rl variable returns a valid value of its operation. but then when I tried to get the square root out of it, the dRighLeft variable still returns 0.0.
I tried both assigned and unassigned dRightLeft like this:
//assigned
dRightLeft = 0;
//unassigned
dRightLeft;
they both still returns 0.0 value.
here's my short but complete program where I get the rx, ry, lx, and ly value:
public Bitmap getDetectedImage()
{
int rx, rx, lx, ly, ...;
double dRightLeft = 0;
...
//righteyeloop
for (int x = fo.rightEye.X; x < (fo.rightEye.X + fo.rightEye.Width); x++)
{
for (int y = fo.rightEye.Y; y < (fo.rightEye.Y + fo.rightEye.Height); y++)
{ //segmentation...//
rPixel++;
result.byteImage[x, y].R = 0;
result.byteImage[x, y].G = 255;
result.byteImage[x, y].B = 0;
//to get the the first pixel detected//
if (rPixel == 1)
{
result.byteImage[x, y].R = 255;
result.byteImage[x, y].G = 0;
result.byteImage[x, y].B = 0;
rx = x + (fo.rightEye.Width / setting.featureWidth * setting.eyeHeight / setting.eyeWidth);
ry = y + (fo.rightEye.Height / setting.featureWidth * setting.eyeHeight / setting.eyeWidth);
}
}
}
//lefteyeloop basically the same type as righteyeloop//
.....
//this to count the distance of righteye and lefteye
double rl = ((rx - lx) * (rx - lx) + (ry - ly) * (ry - ly));
double dRightLeft = Math.Pow(rl, 0.5);
}
I suspect the problem is that Math.Pow deals with doubles, which have low precision (see this SO question for more discussion). The immediate instinct is to just replace Math.Pow by writing out the multiplication:
double rl = ((rx - lx) * (rx - lx) + (ry - ly) * (ry - ly));
double dRightLeft = Math.Sqrt(rl);
From the Math.Pow reference, it seems that, with an exponent of two, the only way to return 0 is if your base (i.e. rx - lx or ry - ly) is also 0.
I need a way to programmatically find the point of intersection between a line f(x), which originates from the origin, and a cubic spline defined by 4 points. The line is guaranteed to intersect the center segment of the spline, between X1 and X2.
I have tried a number of approaches but cannot seem to get the expected result. I suspect my problem lies somewhere in my handling of complex numbers.
Can anyone find the problem with my code, or else suggest a different approach?
private Vector2 CubicInterpolatedIntersection(float y0, float y1,
float y2, float y3, float lineSlope, lineYOffset)
{
// f(x) = lineSlope * x + lineYOffset
// g(x) = (a0 * x^3) + (a1 * x^2) + (a2 * x) + a3
// Calculate Catmull-Rom coefficients for g(x) equation as found
// in reference (1). These
double a0, a1, a2, a3;
a0 = -0.5 * y0 + 1.5 * y1 - 1.5 * y2 + 0.5 * y3;
a1 = y0 - 2.5 * y1 + 2 * y2 - 0.5 * y3;
a2 = -0.5 * y0 + 0.5 * y2;
a3 = y1;
// To find POI, let 'g(x) - f(x) = 0'. Simplified equation is:
// (a0 * x^3) + (a1 * x^2) + ((a2 - lineSlope) * x)
// + (a3 - lineYOffset) = 0
// Put in standard form 'ax^3 + bx^2 + cx + d = 0'
double a, b, c, d;
a = a0;
b = a1;
c = a2 - lineSlope;
d = a3 - lineYOffset;
// Solve for roots using cubic equation as found in reference (2).
// x = {q + [q^2 + (r-p^2)^3]^(1/2)}^(1/3)
// + {q - [q^2 + (r-p^2)^3]^(1/2)}^(1/3) + p
// Where...
double p, q, r;
p = -b / (3 * a);
q = p * p * p + (b * c - 3 * a * d) / (6 * a * a);
r = c / (3 * a);
//Solve the equation starting from the center.
double x, x2;
x = r - p * p;
x = x * x * x + q * q;
// Here's where I'm not sure. The cubic equation contains a square
// root. So if x is negative at this point, then we need to proceed
// with complex numbers.
if (x >= 0)
{
x = Math.Sqrt(x);
x = CubicRoot(q + x) + CubicRoot(q - x) + p;
}
else
{
x = Math.Sqrt(Math.Abs(x));
// x now represents the imaginary component of
// a complex number 'a + b*i'
// We need to take the cubic root of 'q + x' and 'q - x'
// Since x is imaginary, we have two complex numbers in
// standard form. Therefore, we take the cubic root of
// the magnitude of these complex numbers
x = CubicRoot(Math.Sqrt(q * q + x * x)) +
CubicRoot(Math.Sqrt(q * q + -x * -x)) + p;
}
// At this point, x should hold the x-value of
// the point of intersection.
// Now use it to solve g(x).
x2 = x * x;
return new Vector2((float)Math.Abs(x),
(float)Math.Abs(a0 * x * x2 + a1 * x2 + a2 * x + a3));
}
References:
http://paulbourke.net/miscellaneous/interpolation/
http://www.math.vanderbilt.edu/~schectex/courses/cubic/
The code
if (x >= 0)
{ // One real root and two imaginaries.
x = Math.Sqrt(x);
x = CubicRoot(q + x) + CubicRoot(q - x) + p;
}
else
{ // Three real roots.
x = Math.Sqrt(Math.Abs(x));
x_1 = Math.Sign(q)*2*(q*q + x*x)^(1/6)*Math.Cos(Math.Atan(x/q)/3) + p;
x_2 = Math.Sign(q)*2*(q*q + x*x)^(1/6)*Math.Cos(Math.Atan(x/q)/3 + Math.PI*2/3) + p;
x_3 = Math.Sign(q)*2*(q*q + x*x)^(1/6)*Math.Cos(Math.Atan(x/q)/3 + Math.PI*4/3) + p;
}
You can compute ( )^(1/6) with Math.Pow( , 1/6) or your Math.Sqrt(CubicRoot( )) or Math.Sqrt(Cbrt( )). See the following thread on Microsoft forum.
Be careful with q = 0. ( Atan(x/0) = pi/2 radians. Cos(Atan(x/0)/3) = Sqrt(3)/2 )
For a quadratic equation there exists atleast 1 single real root.
Use this method for finding the roots http://en.wikipedia.org/wiki/Cubic_function#General_formula_of_roots
Trying to find functions that will assist us to draw a 3D line through a series of points.
For each point we know: Date&Time, Latitude, Longitude, Altitude, Speed and Heading.
Data might be recorded every 10 seconds and we would like to be able to guestimate the points in between and increase granularity to 1 second. Thus creating a virtual flight path in 3D space.
I have found a number of curve fitting algorithms that will approximate a line through a series of points but they do not guarantee that the points are intersected. They also do not take into account speed and heading to determine the most likely path taken by the object to reach the next point.
From a physics viewpoint:
You have to assume something about the acceleration in your intermediate points to get the interpolation.
If your physical system is relatively well-behaved (as a car or a plane), as opposed to for example a bouncing ball, you may go ahead supposing an acceleration varying linearly with time between your points.
The vector equation for a constant varying accelerated movement is:
x''[t] = a t + b
where all magnitudes except t are vectors.
For each segment you already know v(t=t0) x(t=t0) tfinal and x(tfinal) v(tfinal)
By solving the differential equation you get:
Eq 1:
x[t_] := (3 b t^2 Tf + a t^3 Tf - 3 b t Tf^2 - a t Tf^3 - 6 t X0 + 6 Tf X0 + 6 t Xf)/(6 Tf)
And imposing the initial and final contraints for position and velocity you get:
Eqs 2:
a -> (6 (Tf^2 V0 - 2 T0 Tf Vf + Tf^2 Vf - 2 T0 X0 + 2 Tf X0 +
2 T0 Xf - 2 Tf Xf))/(Tf^2 (3 T0^2 - 4 T0 Tf + Tf^2))
b -> (2 (-2 Tf^3 V0 + 3 T0^2 Tf Vf - Tf^3 Vf + 3 T0^2 X0 -
3 Tf^2 X0 - 3 T0^2 Xf + 3 Tf^2 Xf))/(Tf^2 (3 T0^2 - 4 T0 Tf + Tf^2))}}
So inserting the values for eqs 2 into eq 1 you get the temporal interpolation for your points, based on the initial and final position and velocities.
HTH!
Edit
A few examples with abrupt velocity change in two dimensions (in 3D is exactly the same). If the initial and final speeds are similar, you'll get "straighter" paths.
Suppose:
X0 = {0, 0}; Xf = {1, 1};
T0 = 0; Tf = 1;
If
V0 = {0, 1}; Vf = {-1, 3};
V0 = {0, 1}; Vf = {-1, 5};
V0 = {0, 1}; Vf = {1, 3};
Here is an animation where you may see the speed changing from V0 = {0, 1} to Vf = {1, 5}:
Here you may see an accelerating body in 3D with positions taken at equal intervals:
Edit
A full problem:
For convenience, I'll work in Cartesian coordinates. If you want to convert from lat/log/alt to Cartesian just do:
x = rho sin(theta) cos(phi)
y = rho sin(theta) sin(phi)
z = rho cos(theta)
Where phi is the longitude, theta is the latitude, and rho is your altitude plus the radius of the Earth.
So suppose we start our segment at:
t=0 with coordinates (0,0,0) and velocity (1,0,0)
and end at
t=10 with coordinates (10,10,10) and velocity (0,0,1)
I clearly made a change in the origin of coordinates to set the origin at my start point. That is just for getting nice round numbers ...
So we replace those numbers in the formulas for a and b and get:
a = {-(3/50), -(3/25), -(3/50)} b = {1/5, 3/5, 2/5}
With those we go to eq 1, and the position of the object is given by:
p[t] = {1/60 (60 t + 6 t^2 - (3 t^3)/5),
1/60 (18 t^2 - (6 t^3)/5),
1/60 (12 t^2 - (3 t^3)/5)}
And that is it. You get the position from 1 to 10 secs replacing t by its valus in the equation above.
The animation runs:
Edit 2
If you don't want to mess with the vertical acceleration (perhaps because your "speedometer" doesn't read it), you could just assign a constant speed to the z axis (there is a very minor error for considering it parallel to the Rho axis), equal to (Zfinal - Zinit)/(Tf-T0), and then solve the problem in the plane forgetting the altitude.
What you're asking is a general interpolation problem. My guess is your actual problem isn't due to the curve-fitting algorithm being used, but rather your application of it to all discrete values recorded by the system instead of the relevant set of values.
Let's decompose your problem. You're currently drawing a point in spherically-mapped 3D space, adjusting for linear and curved paths. If we discretize the operations performed by an object with six degrees of freedom (roll, pitch, and yaw), the only operations you're particularly interested in are linear paths and curved paths accounting for pitch and yaw in any direction. Accounting for acceleration and deceleration also possible given understanding of basic physics.
Dealing with the spherical mapping is easy. Simply unwrap your points relative to their position on a plane, adjusting for latitude, longitude, and altitude. This should allow you to flatten data that would otherwise exist along a curved path, though this may not strictly be necessary for the solutions to your problem (see below).
Linear interpolation is easy. Given an arbitrary number of points backwards in time that fit a line within n error as determined by your system,* construct the line and compute the distance in time between each point. From here, attempt to fit the time points to one of two cases: constant velocity or constant acceleration.
Curve interpolation is a little more difficult, but still plausible. For cases of pitch, yaw, or combined pitch+yaw, construct a plane containing an arbitrary number of points backwards in time, within m error for curved readouts from your system.* From these data, construct a planar curve and once again account for constant velocity or acceleration along the curve.
You can do better than this by attempting to predict the expected operations of a plane in flight as part of a decision tree or neural network relative to the flight path. I'll leave that as an exercise for the reader.
Best of luck designing your system.
--
* Both error readouts are expected to be from GPS data, given the description of the problem. Accounting and adjusting for errors in these data is a separate interesting problem.
What you need (instead of modeling the physics) is to fit a spline through the data. I used a numerical recipies book (http://www.nrbook.com/a has free C and FORTRAN algorithms. Look into F77 section 3.3 to get the math needed). If you want to be simple then just fit lines through the points, but that will not result in a smooth flight path at all. Time will be your x value, and each parameter loged will have it's own cublic spline parameters.
Since we like long postings for this question here is the full code:
//driver program
static void Main(string[] args)
{
double[][] flight_data = new double[][] {
new double[] { 0, 10, 20, 30 }, // time in seconds
new double[] { 14500, 14750, 15000, 15125 }, //altitude in ft
new double[] { 440, 425, 415, 410 }, // speed in knots
};
CubicSpline altitude = new CubicSpline(flight_data[0], flight_data[1]);
CubicSpline speed = new CubicSpline(flight_data[0], flight_data[2]);
double t = 22; //Find values at t
double h = altitude.GetY(t);
double v = speed.GetY(t);
double ascent = altitude.GetYp(t); // ascent rate in ft/s
}
// Cubic spline definition
using System.Linq;
/// <summary>
/// Cubic spline interpolation for tabular data
/// </summary>
/// <remarks>
/// Adapted from numerical recipies for FORTRAN 77
/// (ISBN 0-521-43064-X), page 110, section 3.3.
/// Function spline(x,y,yp1,ypn,y2) converted to
/// C# by jalexiou, 27 November 2007.
/// Spline integration added also Nov 2007.
/// </remarks>
public class CubicSpline
{
double[] xi;
double[] yi;
double[] yp;
double[] ypp;
double[] yppp;
double[] iy;
#region Constructors
public CubicSpline(double x_min, double x_max, double[] y)
: this(Sequence(x_min, x_max, y.Length), y)
{ }
public CubicSpline(double x_min, double x_max, double[] y, double yp1, double ypn)
: this(Sequence(x_min, x_max, y.Length), y, yp1, ypn)
{ }
public CubicSpline(double[] x, double[] y)
: this(x, y, double.NaN, double.NaN)
{ }
public CubicSpline(double[] x, double[] y, double yp1, double ypn)
{
if( x.Length == y.Length )
{
int N = x.Length;
xi = new double[N];
yi = new double[N];
x.CopyTo(xi, 0);
y.CopyTo(yi, 0);
if( N > 0 )
{
double p, qn, sig, un;
ypp = new double[N];
double[] u = new double[N];
if( double.IsNaN(yp1) )
{
ypp[0] = 0;
u[0] = 0;
}
else
{
ypp[0] = -0.5;
u[0] = (3 / (xi[1] - xi[0])) *
((yi[1] - yi[0]) / (x[1] - x[0]) - yp1);
}
for (int i = 1; i < N-1; i++)
{
double hp = x[i] - x[i - 1];
double hn = x[i + 1] - x[i];
sig = hp / hn;
p = sig * ypp[i - 1] + 2.0;
ypp[i] = (sig - 1.0) / p;
u[i] = (6 * ((y[i + 1] - y[i]) / hn) - (y[i] - y[i - 1]) / hp)
/ (hp + hn) - sig * u[i - 1] / p;
}
if( double.IsNaN(ypn) )
{
qn = 0;
un = 0;
}
else
{
qn = 0.5;
un = (3 / (x[N - 1] - x[N - 2])) *
(ypn - (y[N - 1] - y[N - 2]) / (x[N - 1] - x[N - 2]));
}
ypp[N - 1] = (un - qn * u[N - 2]) / (qn * ypp[N - 2] + 1.0);
for (int k = N-2; k > 0; k--)
{
ypp[k] = ypp[k] * ypp[k + 1] + u[k];
}
// Calculate 1st derivatives
yp = new double[N];
double h;
for( int i = 0; i < N - 1; i++ )
{
h = xi[i + 1] - xi[i];
yp[i] = (yi[i + 1] - yi[i]) / h
- h / 6 * (ypp[i + 1] + 2 * ypp[i]);
}
h = xi[N - 1] - xi[N - 2];
yp[N - 1] = (yi[N - 1] - yi[N - 2]) / h
+ h / 6 * (2 * ypp[N - 1] + ypp[N - 2]);
// Calculate 3rd derivatives as average of dYpp/dx
yppp = new double[N];
double[] jerk_ij = new double[N - 1];
for( int i = 0; i < N - 1; i++ )
{
h = xi[i + 1] - xi[i];
jerk_ij[i] = (ypp[i + 1] - ypp[i]) / h;
}
Yppp = new double[N];
yppp[0] = jerk_ij[0];
for( int i = 1; i < N - 1; i++ )
{
yppp[i] = 0.5 * (jerk_ij[i - 1] + jerk_ij[i]);
}
yppp[N - 1] = jerk_ij[N - 2];
// Calculate Integral over areas
iy = new double[N];
yi[0] = 0; //Integration constant
for( int i = 0; i < N - 1; i++ )
{
h = xi[i + 1] - xi[i];
iy[i + 1] = h * (yi[i + 1] + yi[i]) / 2
- h * h * h / 24 * (ypp[i + 1] + ypp[i]);
}
}
else
{
yp = new double[0];
ypp = new double[0];
yppp = new double[0];
iy = new double[0];
}
}
else
throw new IndexOutOfRangeException();
}
#endregion
#region Actions/Functions
public int IndexOf(double x)
{
//Use bisection to find index
int i1 = -1;
int i2 = Xi.Length;
int im;
double x1 = Xi[0];
double xn = Xi[Xi.Length - 1];
bool ascending = (xn >= x1);
while( i2 - i1 > 1 )
{
im = (i1 + i2) / 2;
double xm = Xi[im];
if( ascending & (x >= Xi[im]) ) { i1 = im; } else { i2 = im; }
}
if( (ascending && (x <= x1)) || (!ascending & (x >= x1)) )
{
return 0;
}
else if( (ascending && (x >= xn)) || (!ascending && (x <= xn)) )
{
return Xi.Length - 1;
}
else
{
return i1;
}
}
public double GetIntY(double x)
{
int i = IndexOf(x);
double x1 = xi[i];
double x2 = xi[i + 1];
double y1 = yi[i];
double y2 = yi[i + 1];
double y1pp = ypp[i];
double y2pp = ypp[i + 1];
double h = x2 - x1;
double h2 = h * h;
double a = (x-x1)/h;
double a2 = a*a;
return h / 6 * (3 * a * (2 - a) * y1
+ 3 * a2 * y2 - a2 * h2 * (a2 - 4 * a + 4) / 4 * y1pp
+ a2 * h2 * (a2 - 2) / 4 * y2pp);
}
public double GetY(double x)
{
int i = IndexOf(x);
double x1 = xi[i];
double x2 = xi[i + 1];
double y1 = yi[i];
double y2 = yi[i + 1];
double y1pp = ypp[i];
double y2pp = ypp[i + 1];
double h = x2 - x1;
double h2 = h * h;
double A = 1 - (x - x1) / (x2 - x1);
double B = 1 - A;
return A * y1 + B * y2 + h2 / 6 * (A * (A * A - 1) * y1pp
+ B * (B * B - 1) * y2pp);
}
public double GetYp(double x)
{
int i = IndexOf(x);
double x1 = xi[i];
double x2 = xi[i + 1];
double y1 = yi[i];
double y2 = yi[i + 1];
double y1pp = ypp[i];
double y2pp = ypp[i + 1];
double h = x2 - x1;
double A = 1 - (x - x1) / (x2 - x1);
double B = 1 - A;
return (y2 - y1) / h + h / 6 * (y2pp * (3 * B * B - 1)
- y1pp * (3 * A * A - 1));
}
public double GetYpp(double x)
{
int i = IndexOf(x);
double x1 = xi[i];
double x2 = xi[i + 1];
double y1pp = ypp[i];
double y2pp = ypp[i + 1];
double h = x2 - x1;
double A = 1 - (x - x1) / (x2 - x1);
double B = 1 - A;
return A * y1pp + B * y2pp;
}
public double GetYppp(double x)
{
int i = IndexOf(x);
double x1 = xi[i];
double x2 = xi[i + 1];
double y1pp = ypp[i];
double y2pp = ypp[i + 1];
double h = x2 - x1;
return (y2pp - y1pp) / h;
}
public double Integrate(double from_x, double to_x)
{
if( to_x < from_x ) { return -Integrate(to_x, from_x); }
int i = IndexOf(from_x);
int j = IndexOf(to_x);
double x1 = xi[i];
double xn = xi[j];
double z = GetIntY(to_x) - GetIntY(from_x); // go to nearest nodes (k) (j)
for( int k = i + 1; k <= j; k++ )
{
z += iy[k]; // fill-in areas in-between
}
return z;
}
#endregion
#region Properties
public bool IsEmpty { get { return xi.Length == 0; } }
public double[] Xi { get { return xi; } set { xi = value; } }
public double[] Yi { get { return yi; } set { yi = value; } }
public double[] Yp { get { return yp; } set { yp = value; } }
public double[] Ypp { get { return ypp; } set { ypp = value; } }
public double[] Yppp { get { return yppp; } set { yppp = value; } }
public double[] IntY { get { return yp; } set { iy = value; } }
public int Count { get { return xi.Length; } }
public double X_min { get { return xi.Min(); } }
public double X_max { get { return xi.Max(); } }
public double Y_min { get { return yi.Min(); } }
public double Y_max { get { return yi.Max(); } }
#endregion
#region Helpers
static double[] Sequence(double x_min, double x_max, int double_of_points)
{
double[] res = new double[double_of_points];
for (int i = 0; i < double_of_points; i++)
{
res[i] = x_min + (double)i / (double)(double_of_points - 1) * (x_max - x_min);
}
return res;
}
#endregion
}
You can find an approximation of a line that intersects points in 3d and 2d space using a Hough Transformation algorithm. I am only familiar with it's uses in 2d however but it will still work for 3d spaces given that you know what kind of line you are looking for. There is a basic implementation description linked. You can Google for pre-mades and here is a link to a 2d C implementation CImg.
The algorithm process (roughly)... First you find equation of a line that you think will best approximate the shape of the line (in 2d parabolic, logarithmic, exponential, etc). You take that formula and solve for one of the parameters.
y = ax + b
becomes
b = y - ax
Next, for each point you are attempting to match, you plugin the points to the y and x values. With 3 points, you would have 3 separate functions of b with respect to a.
(2, 3) : b = 3 - 2a
(4, 1) : b = 1 - 4a
(10, -5): b = -5 - 10a
Next, the theory is that you find all possible lines which pass through each of the points, which is infinitely many for each individual point however when combined in an accumulator space only a few possible parameters best fit. In practice this is done by choosing a range space for the parameters (I chose -2 <= a <= 1, 1 <= b <= 6) and begin plugging in values for the variant parameter(s) and solving for the other. You tally up the number of intersections from each function in an accumulator. The points with the highest values give you your parameters.
Accumulator after processing b = 3 - 2a
a: -2 -1 0 1
b: 1
2
3 1
4
5 1
6
Accumulator after processing b = 1 - 4a
a: -2 -1 0 1
b: 1 1
2
3 1
4
4
5 2
6
Accumulator after processing b = -5 - 10a
a: -2 -1 0 1
b: 1 1
2
3 1
4
5 3
6
The parameter set with the highest accumulated value is (b a) = (5 -1) and the function best fit to the points given is y = 5 - x.
Best of luck.
My guess is that a serious application of this would use a http://en.wikipedia.org/wiki/Kalman_filter. By the way, that probably wouldn't guarantee that the reported points were intersected either, unless you fiddled with the parameters a bit. It would expect some degree of error in each data point given to it, so where it thinks the object is at time T would not necessarily be where it was at time T. Of course, you could set the error distribution to say that you were absolutely sure you knew where it was at time T.
Short of using a Kalman filter, I would try and turn it into an optimisation problem. Work at the 1s granularity and write down equations like
x_t' = x_t + (Vx_t + Vx_t')/2 + e,
Vx_t_reported = Vx_t + f,
Vx_t' = Vx_t + g
where e, f, and g represent the noise. Then create a penalty function such as e^2 + f^2 + g^2 +...
or some weighted version such as 1.5e^2 + 3f^2 + 2.6g^2 +... according to your idea of what the errors really are and how smooth you wnat the answer to be, and find the values that make the penalty function as small as possible - with least squares if the equations turn out nicely.