I'm trying to find the 4 steepest local maxima (corners of a piece) in a polar coordinate plot generated from a Jigsaw Piece, example plot:
My current implementation, which uses the same idea as this answer and works perfectly, but when combined with a "steepest peaks" function, does not work well, the issue most certainly lies in how a peak is measured for its "steepness".
Here is the "steepest peak" determining function, it returns a single number, smaller is better.
public double GetMagnitude(List<Point> pointList, int centerIndex)
{
Point crrt = pointList[centerIndex];
Point prev = pointList[centerIndex - 1];
Point next = pointList[centerIndex + 1];
Point rhs = new Point((next - crrt).x, (next - crrt).y);
Point lhs = new Point((prev - crrt).x, (prev - crrt).y);
// Calculate the gradient of the lhs against the rhs
return Math.Abs((lhs.y - rhs.y) / (lhs.x - rhs.x));
}
It's called like so (where averageRange is 20, and the number of sample points to take across the curve from the centerIndex)
public double GetAverageMagnitude(List<Point> pointList, int centerIndex)
{
double mag = 0;
int halfAverageRange = averageRange / 2;
for (int j = -halfAverageRange; j < halfAverageRange; j++)
{
mag += GetMagnitude(pointList, centerIndex + j);
}
return mag / averageRange;
}
The math at the end of the GetMagnitude()
function could be entirely wrong, I have also tried:
- Cross product of lhs against rhs
- Separately calculating gradient of lhs and rhs and averaging them (absolute) No luck on any of those methods, the current one is the best so far, yet it's not good enough.
See example below for incorrect vs correct identification:
Note: Each consecutive points X value follows X=i, as in, X0 = 0, X1 = 1
How can I improve these results?