Rotating a Signature: Part 1

For the next step of my signature analysis, I need to rotate the signatures so that both the compared and the comparee signatures are on the same horizontal plain.  To rotate the signatures, I need to find the center line (which I did in this blog post)  and then rotate that line to horizontal with all of the signature’s points keeping the exact same relationship to the center line.

image

To that end, I need to find the center point of the signature.  I created my first unit test like this:

[TestMethod()]
[DeploymentItem("Tff.Signature.Comparison.dll")]
public void GetCenterPoint_OddNumberOfPoints_ReturnsCenterPoint()
{
    ScatterplotComparisonFactory_Accessor target = new ScatterplotComparisonFactory_Accessor();
    List<Point> points = new List<Point>();
    points.Add(new Point(0, 0));
    points.Add(new Point(1, 1));
    points.Add(new Point(2, 2));

    Point expected = new Point(1,1);
    Point actual = target.GetCenterPoint(points);
    Assert.AreEqual(expected, actual);
}

I then wrote enough production to pass this test:

private Point GetCenterPoint(List<Point> comparePoints)
{
    Int32 totalX = 0;
    Int32 totalY = 0;
    Int32 totalCount = 0;

    foreach (Point point in comparePoints)
    {
        totalX += point.X;
        totalY += point.Y;
        totalCount += 1;
    }

    Int32 averageX = (Int32)(totalX / totalCount);
    Int32 averageY = (Int32)(totalY / totalCount);

    return new Point(averageX, averageY);
}

Sure enough: GreenToGo:

image

I then wrote a test for a list of 4 points and quickly realize that I can’t calculate the center point for a list that contains an even-number of points:

image

Sounds like an exception to me.  I altered the test like so

[TestMethod()]
[DeploymentItem("Tff.Signature.Comparison.dll")]
[ExpectedException(typeof(ArgumentException))]
public void GetCenterPoint_EvenNumberOfPoints_ThrowsArgumentException()
{
    ScatterplotComparisonFactory_Accessor target = new ScatterplotComparisonFactory_Accessor();
    List<Point> points = new List<Point>();
    points.Add(new Point(0, 0));
    points.Add(new Point(1, 1));
    points.Add(new Point(2, 2));
    points.Add(new Point(3, 3));

    Point actual = target.GetCenterPoint(points);
    Assert.Fail("Should not get here.");
}

and then the production code:

private Point GetCenterPoint(List<Point> comparePoints)
{
    if (comparePoints.Count % 2 == 0)
    {
        throw new ArgumentException("comparePoints must have an even number.");
    }

    Int32 totalX = 0;
    Int32 totalY = 0;
    Int32 totalCount = 0;

    foreach (Point point in comparePoints)
    {
        totalX += point.X;
        totalY += point.Y;
        totalCount += 1;
    }

    Int32 averageX = (Int32)(totalX / totalCount);
    Int32 averageY = (Int32)(totalY / totalCount);

    return new Point(averageX, averageY);
}

And I was greentogo.

So then I thought – what about a line where the center point is not included in the list?

[TestMethod()]
[DeploymentItem("Tff.Signature.Comparison.dll")]
[ExpectedException(typeof(ArgumentException))]
public void GetCenterPoint_OddNumberOfNonConsecutivePoints_ReturnsCenterPoint()
{
    ScatterplotComparisonFactory_Accessor target = new ScatterplotComparisonFactory_Accessor();
    List<Point> points = new List<Point>();
    points.Add(new Point(0, 0));
    points.Add(new Point(1, 1));
    points.Add(new Point(2, 2));
    points.Add(new Point(5, 5));
    points.Add(new Point(6, 6));

    Point expected = new Point(3, 3);
    Point actual = target.GetCenterPoint(points);
    Assert.AreEqual(expected, actual);
}

I got Red

image

The problem is that list of points that I am using to represent the line may or may not include the true center point.  But that is not the center points problem – its only job is to tell me the center point for an odd number of points.  The problem is that there is a rounding assumption in the code – 1/2 way between 0 and 6 is three – the values of the other numbers are irrelevant.  I then refactored the GetCenterPoint like so:

private Point GetCenterPoint(List<Point> comparePoints)
{
    if (comparePoints.Count % 2 == 0)
    {
        throw new ArgumentException("comparePoints must have an odd number.");
    }

    Point lowestPoint = comparePoints.Min();
    Point highestPoint = comparePoints.Max();

    Double MidX = (highestPoint.X + lowestPoint.X)/2;
    Double MidY = (highestPoint.Y + lowestPoint.Y)/2;

    Int32 MidXRounded = (Int32)MidX;
    Int32 MidYRounded = (Int32)MidY;
    return new Point(MidXRounded, MidYRounded);
}

And I was GreenToGo.

I then realized that GetCenterPoint implicitly violates the SRP – it doesn’t matter if there is a even or odd number in the compare points – just as long as there is at least 1 point.  The even/odd is only if I want to see if the center point of the line is in the list of points that I am using to represent the line.  That is another function – and another set of tests.  I refactored the GetCenterPoint like this:

if (comparePoints.Count == 0)
 {
     throw new ArgumentException("comparePoints has no points.");
 }

And changed my ArguementExceptionTest:

[TestMethod()]
[DeploymentItem("Tff.Signature.Comparison.dll")]
[ExpectedException(typeof(ArgumentException))]
public void GetCenterPoint_NoPointsInArgument_ThrowsArgumentException()
{
    ScatterplotComparisonFactory_Accessor target = new ScatterplotComparisonFactory_Accessor();
    List<Point> points = new List<Point>();
    Point actual = target.GetCenterPoint(points);
    Assert.Fail("Should not get here.");
}

And I was still green everywhere.  With the center point established, I was ready to tackle the rotation of the points around that center point.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: