• 线性规划解决图片内不规则多边形的碰撞体问题


    首先,我们先来看一个问题,如下图演示

    当鼠标点击图片里正六边形内某个点时,我们需要取到该点的颜色值并进行一些操作。而点击正六边形外的透明区域时,我们不需要对该区域进行取值,但是Unity没有正六边形碰撞体,用其他碰撞体代替总会有一些问题。

    于是,我首先想到了用多个小碰撞体来拼接一下,好了,问题完美解决了。

    不过。。。如果是这样的呢?

       

    要想完美拼接起来,那得需要多少boxcollider啊!

    于是我又想到了另外一种方法:线性规划。

    通过线性规划将所需区域围起来,点击时判断鼠标位置是否在规划区域里,从而解决不规则多边形的事件检测。

    简单的做了一个Demo,部分代码如下:

    直线类(相应的可以扩展各种曲线)

    public class Line
    {
        public Vector2 StartPos { get; set; }
        public Vector2 EndPos { get; set; }
        public Line(Vector2 start, Vector2 end)
        {
            StartPos = start;
            EndPos = end;
        }
         /// <summary>
         ///计算点是否在该直线上
         /// </summary>
         /// <param name="point"></param>
         /// <returns>0:点在直线上;1:点在直线上方;-1:点在直线下方</returns>
        public int IsOnLine(Vector2 point)
        {
            float yOnLine = CalcYByX(point.x);
            if (Math.Abs(yOnLine - point.y) <= 0.001f) return 0;
            else
            {
                if ((yOnLine - point.y) > 0) return -1;
                else return 1;
            }
        }
        public float CalcYByX(float x)
        {
            if (StartPos.x == EndPos.x) throw new Exception("X1=X2");
            if (StartPos.y == EndPos.y) return StartPos.y;
            return (EndPos.y - StartPos.y) / (EndPos.x - StartPos.x) * (x - StartPos.x) + StartPos.y;
        }
    }

    正六边形线性规划代码:

     //线性规划解决点是否在正六边形内部
        bool IsInRegularHexagon(Vector2 center,float edge,Vector2 point)
        {
            Vector2 pUp=new Vector2(center.x,center.y+edge);
            Vector2 pDown = new Vector2(center.x, center.y - edge);
            Vector2 pLeft1 = new Vector2(center.x-1.732f/2*edge, center.y + edge/2); 
            Vector2 pLeft2=new Vector2(center.x-1.732f/2*edge, center.y - edge/2); 
            Vector2 pRight1=new Vector2(center.x+1.732f/2*edge, center.y + edge/2); 
            Vector2 pRight2=new Vector2(center.x+1.732f/2*edge, center.y - edge/2);
            Line line1 = new Line(pUp,pLeft1);
            Line line2 = new Line(pUp,pRight1);
            Line line3 = new Line(pDown,pLeft2);
            Line line4 = new Line(pDown,pRight2);
          
            if (point.x > (center.x - 1.732f / 2 * edge) && point.x < center.x + 1.732f / 2 * edge)
            {
                if (line1.IsOnLine(point)==-1&&
                    line2.IsOnLine(point)==-1&&
                    line3.IsOnLine(point)==1&&
                    line4.IsOnLine(point)==1)
                {
                    return true;
                }
            }
            return false;
        }
  • 相关阅读:
    Spring的两种代理JDK和CGLIB的区别浅谈
    抽象 工厂模式
    Mybatis总结面试题
    java抽象工厂模式
    java工厂设计模式
    java单例设计模式
    lombok基本使用
    HTML
    select查询操作(重要)五
    mysql的DML语言(需要背下来)(四)
  • 原文地址:https://www.cnblogs.com/greyhh/p/5682243.html
Copyright © 2020-2023  润新知