Ejemplo n.º 1
0
    /// <summary>
    /// 创建圆形mesh
    /// </summary>
    /// <param name="center"></param>
    /// <param name="radius"></param>
    /// <returns></returns>
    private static Mesh CreateCircleMesh(Vector3 center, float radius)
    {
        Mesh    mesh  = new Mesh();
        float   angle = Mathf.Deg2Rad * 1.0f;
        Double2 dir   = Double2.right * radius;

        Vector3[] vertices = new Vector3[361];
        vertices[360] = center;
        for (int i = 0; i < 360; i++)
        {
            Double2 newPos = Double2.Rotate(dir, i * angle);
            vertices[i] = center + new Vector3((float)newPos.x, 0, (float)newPos.y);
        }

        int[] triangles = new int[360 * 3];
        for (int i = 0; i < 360; i++)
        {
            int index = i * 3;
            triangles[index]     = 360;
            triangles[index + 1] = i;
            triangles[index + 2] = (i + 1) > 359 ? 0: (i + 1);
        }

        Vector2[] uvs = new Vector2[361];
        for (int i = 0; i < 361; i++)
        {
            Vector3 diff = (vertices[i] - center) / radius * 0.5f;
            uvs[i] = new Vector2(diff.x + 0.5f, diff.z + 0.5f);
        }
        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.uv        = uvs;
        return(mesh);
    }
Ejemplo n.º 2
0
        /// <summary>
        /// Retrieve an elipse in its center-radius form using parameters from the SVG specification
        /// </summary>
        /// <param name="cur">Current point</param>
        /// <param name="radii">The ellipse radius</param>
        /// <param name="xRotation">The rotation of the ellipse in relation to the x-axis</param>
        /// <param name="largeArc">Wheter the large arc should be selected or not</param>
        /// <param name="sweep">Sweep direction (false for clockwise, true for counterclockwise)</param>
        /// <param name="target">The target point</param>
        /// <returns></returns>
        public static Curve EllipticArc(Double2 cur, Double2 radii, double xRotation, bool largeArc, bool sweep, Double2 target)
        {
            // The algorithm used here is presented on this link: https://svgwg.org/svg2-draft/implnote.html
            var xpun = (cur - target) / 2;
            var xpr  = xpun.Rotate(-xRotation);

            // Guarantee that the radii are positive
            radii.X = Math.Abs(radii.X); radii.Y = Math.Abs(radii.Y);

            // Guarantee that the radius are large enough
            var    rr = radii.X * radii.X * xpr.Y * xpr.Y + radii.Y * radii.Y * xpr.X * xpr.X;
            var    r2 = radii.X * radii.X * radii.Y * radii.Y;
            double skr;

            if (rr > r2)
            {
                radii *= Math.Sqrt(rr / r2);
                skr    = 0;
            }
            else
            {
                skr = Math.Sqrt((r2 - rr) / rr);
            }

            var cpr = new Double2(skr * radii.X * xpr.Y / radii.Y, -skr * radii.Y * xpr.X / radii.X);

            if (largeArc == sweep)
            {
                cpr = -cpr;
            }

            // Calculate the center
            var cpun = cpr.Rotate(xRotation) + (target + cur) / 2;

            // Calculate the angle
            var t1 = Math.Atan2(radii.X * (xpr.Y - cpr.Y), radii.Y * (xpr.X - cpr.X));
            var t2 = Math.Atan2(radii.X * (-xpr.Y - cpr.Y), radii.Y * (-xpr.X - cpr.X));

            var dt = t2 - t1;

            if (!sweep && dt > 0)
            {
                dt -= TwoPi;
            }
            else if (sweep && dt < 0)
            {
                dt += TwoPi;
            }

            return(EllipticArcInternal(cpun, radii, Double2.FromAngle(xRotation), t1, dt));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 优化路线
        /// </summary>
        /// <param name="lineStart">线段起点</param>
        /// <param name="lineEnd">线段终点</param>
        /// <param name="near">与动态挡格相交 near点</param>
        /// <param name="far">与动态挡格相交 far点</param>
        /// <param name="listMidPoint">2个交点之间的路线</param>
        /// <returns></returns>
        public static List <Double2> OptimizationLine(Double2 lineStart, Double2 lineEnd, Double2 near, Double2 far, bool isCounterclockwiseDir, List <Double2> listMidPoint)
        {
            if (listMidPoint == null || listMidPoint.Count == 0)
            {
                return(listMidPoint);
            }

/*
 #if UNITY_EDITOR
 *          List<Float2> l = new List<Float2>();
 *          l.Add(near);
 *          l.AddRange(listMidPoint);
 *          l.Add(far);
 *          SkillObb.instance.TargetPoly = l.ToArray();
 #endif
 */

            List <Double2> listOptimizationLine = listMidPoint;
            // 先顺序来一次优化
            Double2 outdir = (lineEnd - lineStart).normalized;

            if (isCounterclockwiseDir == false)
            {
                outdir = Double2.Rotate(outdir, MathUtil.kPI - MathUtil.kEpsilon);
            }
            else
            {
                outdir = Double2.Rotate(outdir, -MathUtil.kPI + MathUtil.kEpsilon);
            }
            listOptimizationLine = SearchOutPoint(lineStart, far, outdir.normalized, listOptimizationLine);
            // 再倒序来一次优化
            listOptimizationLine.Reverse();
            outdir = (lineStart - lineEnd).normalized;
            if (isCounterclockwiseDir == true)
            {
                outdir = Double2.Rotate(outdir, MathUtil.kPI - MathUtil.kEpsilon);
            }
            else
            {
                outdir = Double2.Rotate(outdir, -MathUtil.kPI + MathUtil.kEpsilon);
            }
            listOptimizationLine = SearchOutPoint(lineEnd, near, outdir.normalized, listOptimizationLine);
            listOptimizationLine.Reverse();
            //
            return(listOptimizationLine);
        }
Ejemplo n.º 4
0
        private static List <Double2> OptimizationStepLine(Double2 lineStart, Double2 lineEnd, Double2 near, Double2 far, bool isCounterclockwiseDir, List <Double2> listMidPoint)
        {
            if (listMidPoint == null || listMidPoint.Count == 0)
            {
                return(listMidPoint);
            }

            List <Double2> listOptimizationLine = listMidPoint;
            // 先顺序来一次优化
            Double2 outdir = (lineEnd - lineStart).normalized;

            if (isCounterclockwiseDir == false)
            {
                outdir = Double2.Rotate(outdir, MathUtil.kPI - MathUtil.kEpsilon);
            }
            else
            {
                outdir = Double2.Rotate(outdir, -MathUtil.kPI + MathUtil.kEpsilon);
            }
            listOptimizationLine = SearchOutPoint(lineStart, far, outdir.normalized, listOptimizationLine);
            // 再倒序来一次优化

            outdir = (lineStart - lineEnd).normalized;
            if (isCounterclockwiseDir == true)
            {
                outdir = Double2.Rotate(outdir, MathUtil.kPI - MathUtil.kEpsilon);
            }
            else
            {
                outdir = Double2.Rotate(outdir, -MathUtil.kPI + MathUtil.kEpsilon);
            }
            listOptimizationLine.Reverse();
            listOptimizationLine = SearchOutPoint(lineEnd, near, outdir.normalized, listOptimizationLine);
            listOptimizationLine.Reverse();
            //
            return(listOptimizationLine);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 最短射线包围盒路径
        /// </summary>
        /// <param name="line">线段</param>
        /// <param name="offset">偏移值</param>
        /// <param name="rbi">包围盒信息</param>
        /// <returns>true,表示线段与aabb有相交,并返回最短包围路径</returns>
        public override RBIResultType RayboundingNearestPath(LineSegment2D line, double offset, ref RayboundingInfo rbi)
        {
            if (rbi == null)
            {
                rbi = new RayboundingInfo();
            }
            Double2 diff = this.circleCenter - line.startPoint;

            if (diff == Double2.zero)
            {
                return(RBIResultType.Fail);
            }
            //
            Double2 projectoint = line.ProjectPoint(this.circleCenter);

            diff = this.circleCenter - projectoint;
            // 跟直线相交奥
            double dis = diff.sqrMagnitude - this.radius * this.radius;

            if (dis >= 0)
            {
                return(RBIResultType.Fail);
            }
            dis = -dis;
            // 在同侧不行。
            Double2 diff1 = line.startPoint - projectoint;
            Double2 diff2 = line.endPoint - projectoint;

            if (Double2.Dot(diff1, diff2) >= 0)
            {
                return(RBIResultType.Fail);
            }
            //
            if (diff1.sqrMagnitude < dis || diff2.sqrMagnitude < dis)
            {
                return(RBIResultType.Fail);
            }

            dis = System.Math.Sqrt(dis) + offset;

            Double2 p1 = projectoint - line.normalizedDir * dis;
            Double2 p2 = projectoint + line.normalizedDir * dis;

            double         bigRadius   = this.radius + offset;
            double         angle       = SignedAngleInCircle(p1 - this.circleCenter, p2 - this.circleCenter, bigRadius);
            int            count       = (int)(System.Math.Abs(angle / 0.25f));
            double         diffangle   = angle / count;
            List <Double2> listpath    = new List <Double2>();
            Double2        startVector = (p1 - this.circleCenter).normalized * bigRadius;

            for (int i = 1; i <= count - 1; i++)
            {
                Double2 rorateVector = Double2.Rotate(startVector, -diffangle * i);
                listpath.Add(rorateVector + this.circleCenter);
            }
            rbi.listpath = listpath;
            if (rbi.listpath != null && rbi.listpath.Count > 0)
            {
                rbi.CalcHelpData(line, offset, p1, p2);
                return(RBIResultType.Succ);
            }
            return(RBIResultType.Fail);
        }