【问题标题】:c# getting a sporadic resultsc#得到一个零星的结果
【发布时间】:2012-01-30 20:02:43
【问题描述】:

所以我真的被困在这个问题上好几个小时了,这非常令人沮丧。我得到零星的结果。该程序有时会运行,但在其他时候,它无法找到我正在寻找的“切线”之一,即使在数学上保证有一个。

我真的是 c# 新手,所以如果有人有时间帮助菜鸟,将不胜感激。

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;
    }

所以我有点确信这是一个编程错误,因为我已经经历了一遍又一遍,尽管我可能弄错了。

对不起,如果这是一个不恰当的帖子,我真的只是卡住了,我不想打扰任何人,如果我滥用论坛,请告诉我。

我发现穿过两个顶点的线,每个子组中的一个,所有其他线要么低于(顶部切线)要么高于(底部切线)。错误在于,使用该算法,它应该始终迭代循环永远不会达到返回 null。但偶尔会。我猜这是一个精度错误。

【问题讨论】:

  • 错误是什么?或者是你的问题所在 - 你没有看到错误,因此它可能是一个逻辑错误
  • 你说你得到了零星的结果,但你似乎没有指出预期/期望的结果是什么。我们可以看到你得到了切线,但是 what 的切线? 为什么你认为代码错了?
  • 你不希望这里有人为你调试它吗……
  • 你说你是n00b。我们都在某个时候。您知道如何在代码中设置断点并单步执行并检查变量中的值吗?我在想 Combine 方法的第一行。
  • 你们都是一个恶毒的群体.. 让这家伙休息一下,他很沮丧。

标签: c# graphing


【解决方案1】:

这可能只是 double 的精度问题吗?也许你应该让你的测试功能“模糊”。

像这样:

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

  if ((result > -0.0001) && (result < 0.0001))
     return 0.0;
  else
     return result;

【讨论】:

  • 就是这样!但我不确定我是否理解这个概念。你介意解释为什么这是必要的吗?我的印象是 double 值足够精确,这不会成为真正的问题。
  • @CynicalOptimist - 当然,当然,但是当有其他人做得更好时,为什么要尝试解释。例如en.wikipedia.org/wiki/Floating_point#Accuracy_problems
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 2016-02-21
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多