How to make requests for radial collections in C #?

I have many points (with coordinates .Xand .Y) in 2d-space. For example, KDTree or some other collections IEnumerable<AnyXYPointImpl>. I want to make a query that is not square, but Circle \ Radius is based:

enter image description here

I want it simply: having a point P, a direction Dand a half angle a, we want to get all the points in the collection area covered by the sector they formed.

So how to make such radial collection queries in C # with LINQ?

+4
source share
2 answers

Here is the solution :

Usage example:

var field = new List<Vector2>() {
            new Vector2(-1,1),  new Vector2(1,1), 
            new Vector2(-1,-1), new Vector2(1,-1)
        };

        Console.WriteLine(string.Join("; ", field.IsInSector(new Vector2(0,0), new Vector2(2,2), 45.0)));
        Console.WriteLine(string.Join("; ", field.IsInSector(new Vector2(0,0), new Vector2(2,-2), 45.0)));
        Console.WriteLine(string.Join("; ", field.IsInSector(new Vector2(0,0), new Vector2(2,0), 90.0)));

- IEnumerable:

public static class Extenctions {
    public static IEnumerable<IXYPoint> IsInSector(this IEnumerable<IXYPoint> source, Vector2 pointToCheck, Vector2 direction, double halfAngle)
    {
        if(!source.Any() || pointToCheck == null || halfAngle <= 0)
            return new IXYPoint[0];

        var dirVector = new Vector2() {
            X = direction.X - pointToCheck.X,
            Y = direction.Y - pointToCheck.Y
        };

        var radius = Distance(direction, pointToCheck);
        var result = new List<IXYPoint>();

        foreach(var p in source)
        {
            if(Distance(p, pointToCheck) > radius){ // check is point in circle
                continue;
            }


            if(IsPointInSector(dirVector, p, halfAngle)) // main check 
                result.Add(p);
        }

        return result;
    }

    private static double Distance(IXYPoint from, IXYPoint to)
    {
        return Math.Sqrt(Math.Pow(to.X - from.X,2) + Math.Pow(from.Y-to.Y,2));
    }

    private static bool IsPointInSector(IXYPoint directionVector, IXYPoint pointToCheck, double halfAngle)
    {
        var rq0 = Math.Pow(directionVector.X,2) + Math.Pow(directionVector.Y,2);
        var rq = Math.Pow(pointToCheck.X,2) + Math.Pow(pointToCheck.Y,2);
        return rq0 >= rq && (directionVector.X*pointToCheck.X + directionVector.Y*pointToCheck.Y)/Math.Sqrt(rq0*rq) >= Math.Cos(halfAngle/180.0*Math.PI);
    }

}
+2

-LINQ-.

    var filteredPoints = new List<Point2D>();

    foreach (var point in points)
        if (point.IsInSector(origin, d, a))
            filteredPoints.Add(point);
-1

Source: https://habr.com/ru/post/1695620/


All Articles