-1

Help me, because I'm rly tired of this...

I need to count angles between current point and the closest 3 points (look at an image below) - I need to sort the angles in descending order (to get the point with the largest angle - if it doesn't fit expectations, I have to get another one).

Angles

I tried to do something, but it doesn't work...

private static Vertex[] SortByAngle(IEnumerable<Vertex> vs, Vertex current, Vertex previous)
{
    if (current.CompareTo(previous) == 0)
    {
        previous.X = previous.X - 1.0; // this is a trick to handle the first point
    }

    var vertices = new Dictionary<Vertex, double>();
    foreach (var v in vs)
    {
        double priorAngle = Angle(previous, current);
        double nextAngle = Angle(current, v);
        double angleInBetween = 180.0 - (priorAngle + nextAngle);

        vertices.Add((Vertex) v.Clone(), angleInBetween);
    }

    // here the angles are incorrect, because I want to sort them in desc order, but it's a real mess when I do OrderByDescending - something is wrong with my code:S
    vertices = vertices.OrderBy(v => v.Value).ToDictionary(k => k.Key, v => v.Value);

    return vertices.Select(v => new Vertex(v.Key.X, v.Key.Y)).ToArray();
}

private static double Angle(Vertex v1, Vertex v2, double offsetInDegrees = 0.0)
{
    return (RadianToDegree(Math.Atan2(-v2.Y + v1.Y, -v2.X + v1.X)) + offsetInDegrees);
}

public static double RadianToDegree(double radian)
{
    var degree = radian * (180.0 / Math.PI);
    if (degree < 0)
        degree = 360 + degree;

    return degree;
}
  • vs is my set of 3 nearest points
  • current and previous are obvious:)
4

1 回答 1

1

我没有测试它,但我重新设计了一点,避免使用字典。我认为您的错误在于:double angleInBetween = 180.0 - (priorAngle + nextAngle); 应该是:double angleInBetween = (180.0 - priorAngle) + nextAngle;

    public struct Vertex
    {
        public double X { get; set; }
        public double Y { get; set; }
    }

    private static double CalcDistance(Vertex v1, Vertex v2)
    {
        double dX = (v2.X - v1.X);
        double dY = (v2.Y - v1.Y);

        return Math.Sqrt((dX * dX) + (dY * dY));
    }

    private static Vertex[] SortByAngle(IEnumerable<Vertex> vs, Vertex current, Vertex previous)
    {
        var verticesOnDistance = from vertex in vs
                                 where !vertex.Equals(current)
                                 let distance = CalcDistance(current, vertex)
                                 orderby distance
                                 select vertex;

        double priorAngle = Angle(previous, current);

        var verticeAngles = from vertex in verticesOnDistance.Take(3)
                            let nextAngle = Angle(current, vertex)
                            let angleInBetween = (180.0 - priorAngle) + nextAngle
                            orderby angleInBetween descending
                            select vertex;

        return verticeAngles.ToArray();
    }

    private static double Angle(Vertex v1, Vertex v2, double offsetInDegrees = 0.0)
    {
        return (RadianToDegree(Math.Atan2(-v2.Y + v1.Y, -v2.X + v1.X)) + offsetInDegrees);
    }

    public static double RadianToDegree(double radian)
    {
        var degree = radian * (180.0 / Math.PI);
        if (degree < 0)
            degree = 360 + degree;

        return degree;
    }

我在这里有点没时间了。我稍后再讲...我不确定这是否正确,但也许可以再亮一下...

祝你好运

于 2013-08-09T14:38:47.017 回答