1

So I've literally been stuck on this for hours and it's quite frustrating. I am getting sporadic results. the program is working sometime, but at other times, it can't find one of the "tangents" I'm looking for, even though mathematically there is guaranteed to be one.

I'm really new to c# so, if anyone had some time to help a noob, it would be much appreciated.

private List<PointF> SplitAndSolve(Graphics g, List<PointF> pointList)
    {
        if (pointList.Count < 4)
            return pointList;
        List<List<PointF>> leftAndRight = SplitByX(pointList);
        List<PointF> left = leftAndRight[0];
        List<PointF> right = leftAndRight[1];
        drawPolygon(g, left);// just a way to visually assess the correctness
        drawPolygon(g, right);// same
        left = SplitAndSolve(g, left);
        right = SplitAndSolve(g, right);
        Combine(g, left, right);
        return pointList;
    }
    private List<PointF> Combine(Graphics g, List<PointF> left, List<PointF> right)
    {
        //find tangents
        List<PointF> topTangents = GetTangents(g, left, right, TOP);
        drawPoint(g, topTangents[0]);//visual debug
        drawPoint(g, topTangents[1]);//visual debug
        List<PointF> botTangents = GetTangents(g, left, right, BOT);
        drawPoint(g, botTangents[0]);//visual debug
        drawPoint(g, botTangents[1]);//""
        // get a new polygon

        return left;// just a place holder so I don't get errors for the time being
    }
    private List<PointF> GetTangents(Graphics g, List<PointF> left, List<PointF> right, float topOrBot)
    {
        List<PointF> tangents = new List<PointF>();
        foreach (PointF leftAnchor in left)
        {
            foreach (PointF rightAnchor in right)
            {
                double lax = leftAnchor.X;
                double lay = leftAnchor.Y;
                double rax = rightAnchor.X;
                double ray = rightAnchor.Y;
                double m = (lay - ray) / (lax - rax);
                double b = (-1 * m * lax) + lay;
                bool isTangent = true;
                foreach (PointF lpoi in left)
                {
                    if ((topOrBot == TOP) && (Test(m, b, lpoi) > 0))
                    {
                        isTangent = false;

                    }
                    if ((topOrBot == BOT) && (Test(m, b, lpoi) < 0))
                    {
                        isTangent = false;

                    }
                }

                foreach (PointF rpoi in right)
                {
                    if ((topOrBot == TOP) && (Test(m, b, rpoi) > 0))
                    {
                        isTangent = false;

                    }
                    if ((topOrBot == BOT) && (Test(m, b, rpoi) < 0))
                    {
                        isTangent = false;

                    }
                }
                if (isTangent)
                {
                    tangents.Add(leftAnchor);
                    tangents.Add(rightAnchor);
                    return tangents;
                }

            }

        }
        return null;
    }

    /*  Test, test to see the location of a point in relation to a line
     *  @float m slope of the line
     *  @float b the constast of the y intercept form
     *  @Pointf r is the point to be tested against the line
     * 
     *  returns some k > 0 if point is below the line
     *  returns some k < 0 if point is above the line
     *  returns 0 if point is found along the line
     */
    private double Test(double m, double b, PointF r)
    {
        return (m*(double)r.X) + b - (double)r.Y;
    }

so I'm somewhat convinced it's a programming error, because I've been over it and over it, though I may be mistaken.

I'm sorry if this is an inappropriate post, I really am just stuck, I don't mean to be bothersome to anyone, if I am misusing the forum please let me know.

I am finding the line that crosses two vertices, one from each subgroup, that all other lines are either below(top tangent) or above(bottom tangent). The error is that with the algorithm, it should always iterative loops should never reach the return null. Yet occasionally it does. I guessing it is a precision error.

MrBrightside
  • 593
  • 2
  • 10
  • 22
  • 1
    You say you are getting sporadic results but you don't seem to indicate what the expected/desired results are. We can see you are getting tangents, but tangents of *what*? *Why* do you think the code is wrong? – vcsjones Jan 30 '12 at 20:05
  • 1
    What is the error? Or is that where your problem lies - you dont see an error therefore it might be a logical mistake – JonH Jan 30 '12 at 20:05
  • Don't you expect anyone here to debug it for you… – Ondrej Tucny Jan 30 '12 at 20:05
  • 1
    You say you are a n00b. We all were at some point. Do you know how to set a breakpoint in the code and step through it and examine the values in the variables? I'm thinking the first line of the Combine method. – DOK Jan 30 '12 at 20:12
  • 1
    You are all a vicious group.. give the guy a break, he is frustrated. – Hogan Jan 30 '12 at 20:14

1 Answers1

3

Could this just be precision issues with double? Maybe you should make your Test function "fuzzy".

Like this:

  double result = (m*(double)r.X) + b - (double)r.Y;

  if ((result > -0.0001) && (result < 0.0001))
     return 0.0;
  else
     return result;
Hogan
  • 69,564
  • 10
  • 76
  • 117
  • That was it!, yet I'm not sure I understand the concept. Do you mind explaining why this is necessary? I was under the impression that double values were precise enough that this wouldn't really be an issue. – MrBrightside Jan 30 '12 at 20:20
  • @CynicalOptimist - Sure, sure, but why try to explain when there are others who have done a better job. e.g. http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems – Hogan Jan 30 '12 at 20:40