- Home /
Fit line through cluster of points
I have a certain number of points/vectors that approximately lie on a line in 3D space. Are there any existing functions in unity that can fit a line through a cluster of 3D points/vectors?
The problem can be solved mathematically with a orthogonal linear regression (amongst others), that minimizes the squared error. However, it's been ages since I've worked with stuff like principal component analysis, eigenvectors, eigenvalues and so on, so implementing it myself in C# would be an enourmous hustle. Unfortunately I haven't found any C# implementation either.
A solution I'm looking for doesn't have to be as mathematically optimal as the mentioned regression, I simply want to get a rough mean direction vector from my points.
I thought about fitting a cylinder or a quad around the point cluster and using the line that goes through the centers of the capping circles/squares. Does anyone have an idea how to go about doing that script wise?
Thanks in advance!
If anyone wants to give it a try and implement the regression in C# ;) http://en.wikipedia.org/wiki/User:Vossman/3D_Line_Regression
Answer by Jamora · Jan 11, 2014 at 05:32 PM
A very simple way to get an extremely rough plot is to take the average of all points and plot a line from the average of a few points form the beginning to the average of all points. This of course requires you to have sorted your points somehow, e.g. first by x, then y and finally z. Radix sort is good for this purpose. If you believe in outliers, be warned that this method is very sensitive to them in your data set, as they will strongly skew the regression.
public Vector3 GetRoughDirection(Vector3[] dataSet){
Vector3[] sortedSet = SortXYZ(dataSet);
Vector3 averagePoint = Average(dataSet);
Vector3 beginning = Average(new Vector3[]{sortedSet[0],sortedSet[1],sortedSet[2]});
return averagePoint-beginning;
}
private Vector3 Average(Vector3[] dataSet){
float sumX = 0f;
float sumY = 0f;
float sumZ = 0f;
foreach(Vector3 v in dataSet){
sumX += v.x;
sumY += v.y;
sumZ += v.z;
}
return new Vector3(sumX/dataSet.Length, sumY/dataSet.Length, sumZ/dataSet.Length);
}
Answer by HappyMoo · Jan 11, 2014 at 04:01 PM
Hi, no, fitting a cylinder requires the same kind of math as fitting the line in the first place...
It's been ages for me too since I've done this kind of stuff, but it doesn't look hard at all...
Check this for the 2D version: http://faculty.cs.niu.edu/~hutchins/csci230/best-fit.htm
now for 3D you can basically just do the 2D Algorithm two times... first by only using x/y and then by looking from above and using x/z instead, so you get all components to build your 3D line
Let me know if you need more help, but you'll probably be able to figure this out
Thanks, good idea, I'll try that. However, this definitely results in a different line than the 3D version would. I'll post my solution as soon as I have one :)
Your answer
Follow this Question
Related Questions
Transform angle to grid position 2 Answers
Make a moving object continue it's movement from the same direction , even it reaches target 1 Answer
How do I turn 1 objects rotation into another objects movement direction? 1 Answer
Finding difference between gameObject's x coordinate according to one object's transform 1 Answer