zoukankan      html  css  js  c++  java
  • 线性规划解决图片内不规则多边形的碰撞体问题

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

    当鼠标点击图片里正六边形内某个点时,我们需要取到该点的颜色值并进行一些操作。而点击正六边形外的透明区域时,我们不需要对该区域进行取值,但是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;
        }
  • 相关阅读:
    Nodejs下载和第一个Nodejs示例
    永久关闭Win10工具栏的TaskbarSearch控件
    对称加密,非对称加密,散列算法,签名算法
    【转】TTL和RS232之间的详细对比
    zlg核心板linux系统中查看系统内存等使用信息
    Power BI后台自动刷新数据报错 The operation was throttled by Power BI Premium because there were too many datasets being processed concurrently.
    剪切板和上传文件内容获取
    CSS, LESS, SCSS, SASS总结
    文字程序
    electron 打包“ERR_ELECTRON_BUILDER_CANNOT_EXECUTE”
  • 原文地址:https://www.cnblogs.com/greyhh/p/5682243.html
Copyright © 2011-2022 走看看