判断矢量图形中的“L”型建筑物的方法,并用.net语言实现

判断方法:

  1. 遍历矢量图形中所有的线段,找出长度大于等于L型建筑物的一条直线段。

  2. 以该线段的两个端点为起点,分别向左、右、上、下四个方向延伸,找出相邻的线段,并判断其是否与原线段成直角。

  3. 若找到了符合要求的相邻线段,则继续以该线段的端点为起点,向另一个方向延伸,直到延伸的线段不再与原线段成直角为止。

  4. 若延伸的线段数量达到了L型建筑物的要求,则判断为L型建筑物。

    public bool IsLBuilding(List<Vector2> vertices)
    {
        bool isLBuilding = false;
        foreach (Vector2 vertex in vertices)
        {
            foreach (Vector2 neighbor in GetNeighbors(vertex, vertices))
            {
                if (neighbor != vertex)
                {
                    Vector2 direction = neighbor - vertex;
                    if (direction.magnitude >= LBuildingLength)
                    {
                        Vector2 perpendicular = new Vector2(-direction.y, direction.x);
                        if (IsPerpendicular(vertex, neighbor, perpendicular, vertices))
                        {
                            if (IsLBuilding(vertex, neighbor, perpendicular, vertices))
                            {
                                isLBuilding = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (isLBuilding)
            {
                break;
            }
        }
        return isLBuilding;
    }
    
    private bool IsLBuilding(Vector2 start, Vector2 end, Vector2 perpendicular, List<Vector2> vertices)
    {
        int count = 0;
        Vector2 current = end;
        while (count < LBuildingCount)
        {
            Vector2 next = GetNextVertex(current, perpendicular, vertices);
            if (next != Vector2.zero && next != start)
            {
                perpendicular = new Vector2(-perpendicular.y, perpendicular.x);
                count++;
                current = next;
            }
            else
            {
                break;
            }
        }
        return count == LBuildingCount;
    }
    
    private bool IsPerpendicular(Vector2 start, Vector2 end, Vector2 perpendicular, List<Vector2> vertices)
    {
        bool isPerpendicular = false;
        foreach (Vector2 vertex in vertices)
        {
            if (vertex != start && vertex != end)
            {
                Vector2 direction = vertex - start;
                if (Vector2.Dot(direction, perpendicular) == 0)
                {
                    float distance = Mathf.Abs(Vector2.Dot(direction, perpendicular.normalized));
                    if (distance <= LineTolerance)
                    {
                        isPerpendicular = true;
                        break;
                    }
                }
            }
        }
        return isPerpendicular;
    }
    
    private Vector2 GetNextVertex(Vector2 current, Vector2 direction, List<Vector2> vertices)
    {
        Vector2 next = Vector2.zero;
        foreach (Vector2 vertex in vertices)
        {
            if (vertex != current)
            {
                Vector2 delta = vertex - current;
                if (delta.magnitude <= LineTolerance)
                {
                    Vector2 perpendicular = new Vector2(-delta.y, delta.x);
                    if (Vector2.Dot(perpendicular, direction) == 0)
                    {
                        next = vertex;
                        break;
                    }
                }
            }
        }
        return next;
    }
    
    private List<Vector2> GetNeighbors(Vector2 vertex, List<Vector2> vertices)
    {
        List<Vector2> neighbors = new List<Vector2>();
        foreach (Vector2 other in vertices)
        {
            if (other != vertex)
            {
                Vector2 delta = other - vertex;
                if (delta.magnitude <= LineTolerance)
                {
                    neighbors.Add(other);
                }
            }
        }
        return neighbors;
    }

    其中,vertices为矢量图形中所有顶点的列表,LBuildingLength为L型建筑物的直线段长度,LBuildingCount为L型建筑物的直线段数量,LineTolerance为判断两条直线是否垂直或平行的容差值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值