コード例 #1
0
ファイル: LineSegment2D.cs プロジェクト: 741645596/graph
        /// <summary>
        /// 与线段的关系
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public LineRelation CheckLineRelation(LineSegment2D line)
        {
            // 快速排斥实验,后续优化实现
            // 进行跨立实验
            double r1     = Double2.Cross(this.normalizedDir, line.startPoint - this.startPoint);
            double r2     = Double2.Cross(this.normalizedDir, line.endPoint - this.startPoint);
            double cross1 = r1 * r2;
            double t1     = Double2.Cross(line.normalizedDir, this.startPoint - line.startPoint);
            double t2     = Double2.Cross(line.normalizedDir, this.endPoint - line.startPoint);
            double cross2 = t1 * t2;

            if (cross1 > 0 || cross2 > 0)
            {
                return(LineRelation.Detach);
            }
            else if (cross1 == 0 || cross2 == 0)
            {
                if (cross1 == 0)
                {
                    if (r1 == 0)
                    {
                        if (Double2.Dot(line.startPoint - this.startPoint, line.startPoint - this.endPoint) <= 0)
                        {
                            return(LineRelation.Intersect);
                        }
                    }
                    if (r2 == 0)
                    {
                        if (Double2.Dot(line.endPoint - this.startPoint, line.endPoint - this.endPoint) <= 0)
                        {
                            return(LineRelation.Intersect);
                        }
                    }
                }
                if (cross2 == 0)
                {
                    if (t1 == 0)
                    {
                        if (Double2.Dot(this.startPoint - line.startPoint, this.startPoint - line.endPoint) <= 0)
                        {
                            return(LineRelation.Intersect);
                        }
                    }
                    if (t2 == 0)
                    {
                        if (Double2.Dot(this.endPoint - line.startPoint, this.endPoint - line.endPoint) <= 0)
                        {
                            return(LineRelation.Intersect);
                        }
                    }
                }
                return(LineRelation.Detach);
            }
            return(LineRelation.Intersect);
        }
コード例 #2
0
 /// <summary>
 /// 修正near far 点
 /// </summary>
 /// <param name="line"></param>
 /// <param name="nearPoint"></param>
 /// <param name="farPoint"></param>
 protected void ReviseNearFar(LineSegment2D line)
 {
     if (Double2.Dot(nearPoint - line.startPoint, line.normalizedDir) <= 0)
     {
         nearPoint = line.startPoint;
     }
     if (Double2.Dot(line.endPoint - farPoint, line.normalizedDir) <= 0)
     {
         farPoint = line.endPoint;
     }
 }
コード例 #3
0
        /// <summary>
        /// 获取挡格附近出生点
        /// </summary>
        /// <param name="line"></param>
        /// <param name="offset"></param>
        /// <param name="bornPoint"></param>
        /// <returns></returns>
        public override bool GetBornPoint(LineSegment2D line, double offset, ref Double2 bornPoint)
        {
            Double2 pos1 = Double2.zero;

            for (int i = 0; i < GetEdgeNum(); i++)
            {
                if (line.GetIntersectPoint(GetEdge(i), ref bornPoint, ref pos1) == true)
                {
                    bornPoint = line.normalizedDir * ((bornPoint - line.startPoint).magnitude + offset) + line.startPoint;
                    return(true);
                }
            }
            return(false);
        }
コード例 #4
0
        /// <summary>
        /// 与线段的关系
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public override LineRelation CheckLineRelation(LineSegment2D line)
        {
            Double2 pos  = Double2.zero;
            Double2 pos1 = Double2.zero;

            for (int i = 0; i < GetEdgeNum(); i++)
            {
                if (line.GetIntersectPoint(GetEdge(i), ref pos, ref pos1) == true)
                {
                    return(LineRelation.Intersect);
                }
            }
            return(LineRelation.Detach);
        }
コード例 #5
0
        /// <summary>
        /// 计算其他辅助数据
        /// </summary>
        /// <param name="line"></param>
        public void CalcHelpData(LineSegment2D line, double offset, Double2 near, Double2 far)
        {
            isCross = true;
            if (this.listpath != null && this.listpath.Count > 0)
            {
                this.nearPoint  = near;
                this.nearPoint -= offset * line.normalizedDir;

                this.farPoint  = far;
                this.farPoint += offset * line.normalizedDir;
                this.ReviseNearFar(line);
                // 计算时针方向
                this.isCounterclockwiseDir = CaclCounterclockwiseDir(line, this.listpath);

                this.distance = (line.startPoint - nearPoint).sqrMagnitude;
            }
        }
コード例 #6
0
        /// <summary>
        /// 获取交点
        /// </summary>
        /// <param name="line"></param>
        /// <param name="intersectStart"></param>
        /// <param name="intersectEnd"></param>
        /// <returns></returns>
        public override bool GetIntersectPoint(LineSegment2D line, ref Double2 intersectStart, ref Double2 intersectEnd)
        {
            List <Double2> listPt = new List <Double2>();
            Double2        pos    = Double2.zero;
            Double2        pos1   = Double2.zero;

            for (int i = 0; i < GetEdgeNum(); i++)
            {
                if (GetEdge(i).GetIntersectPoint(line, ref pos, ref pos1) == true)
                {
                    if (pos == pos1)
                    {
                        if (listPt.Contains(pos) == false)
                        {
                            listPt.Add(pos);
                        }
                    }
                    else
                    {
                        if (listPt.Contains(pos) == false)
                        {
                            listPt.Add(pos);
                        }
                        if (listPt.Contains(pos1) == false)
                        {
                            listPt.Add(pos1);
                        }
                    }
                }
            }
            // 排序从近到远
            listPt.Sort((a, b) => MathUtil.GetCompareDis(a, line.startPoint).CompareTo(MathUtil.GetCompareDis(b, line.startPoint)));
            //
            if (listPt.Count > 0)
            {
                intersectStart = listPt[0];
                intersectEnd   = listPt[listPt.Count - 1];
                return(true);
            }
            return(false);
        }
コード例 #7
0
        /// <summary>
        /// 与多边形的关系
        /// </summary>
        /// <param name="ab"></param>
        /// <returns>true 相交: false 不相交</returns>
        public override bool CheckIntersect(Polygon2D ab)
        {
            if (ab == null)
            {
                return(false);
            }
            if (ab.CheckIn(this.circleCenter) == true)
            {
                return(true);
            }

            for (int i = 0; i < ab.GetEdgeNum(); i++)
            {
                LineSegment2D ls = ab.GetEdge(i);
                if (this.CheckLineRelation(ls) != LineRelation.Detach)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #8
0
        /// <summary>
        /// 计算超出线段范围
        /// </summary>
        /// <param name="lineStart"></param>
        /// <param name="lineEnd"></param>
        /// <param name="listMidPoint"></param>
        /// <param name="nearestIndex"></param>
        /// <param name="farestIndex"></param>
        private static void CalcNearFarest(Double2 lineStart, Double2 lineEnd, List <Double2> listMidPoint, ref int nearestIndex, ref int farestIndex)
        {
            if (listMidPoint == null || listMidPoint.Count == 0)
            {
                return;
            }
            nearestIndex = -1;
            farestIndex  = -1;
            double        outStartdis = 0;
            double        outEnddis   = 0;
            LineSegment2D line        = new LineSegment2D(lineStart, lineEnd);

            for (int i = 0; i < listMidPoint.Count; i++)
            {
                ProjectPointInLine pp = line.CheckProjectInLine(listMidPoint[i]);
                if (pp == ProjectPointInLine.In)
                {
                    continue;
                }
                Double2 projectPoint = line.ProjectPoint(listMidPoint[i]);
                if (pp == ProjectPointInLine.OutStart)
                {
                    double dis = (projectPoint - lineStart).sqrMagnitude;
                    if (dis > outStartdis)
                    {
                        outStartdis  = dis;
                        nearestIndex = i;
                    }
                }
                else if (pp == ProjectPointInLine.OutStart)
                {
                    double dis = (projectPoint - lineEnd).sqrMagnitude;
                    if (dis > outEnddis)
                    {
                        outEnddis   = dis;
                        farestIndex = i;
                    }
                }
            }
        }
コード例 #9
0
ファイル: LineSegment2D.cs プロジェクト: 741645596/graph
        public override bool Equals(System.Object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            LineSegment2D p = (LineSegment2D)obj;

            if ((System.Object)p == null)
            {
                return(false);
            }
            if ((startPoint == p.startPoint && endPoint == p.endPoint) || (startPoint == p.endPoint && endPoint == p.startPoint))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #10
0
        /// <summary>
        /// 与线段的关系
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public override LineRelation CheckLineRelation(LineSegment2D line)
        {
            double dis = line.CalcDistance(this.circleCenter);

            if (dis > this.radius)
            {
                return(LineRelation.Detach);
            }
            else
            {
                double sqrRadius = this.radius * this.radius;
                if ((this.circleCenter - line.startPoint).sqrMagnitude > sqrRadius)
                {
                    return(LineRelation.Intersect);
                }
                if ((this.circleCenter - line.endPoint).sqrMagnitude > sqrRadius)
                {
                    return(LineRelation.Intersect);
                }
                return(LineRelation.Coincide);
            }
        }
コード例 #11
0
        /// <summary>
        /// 计算时钟方向
        /// </summary>
        /// <param name="line"></param>
        /// <param name="paths"></param>
        /// <returns></returns>
        protected bool CaclCounterclockwiseDir(LineSegment2D line, List <Double2> paths)
        {
            if (paths == null || paths.Count == 0)
            {
                return(true);
            }
            Double2 f = Double2.zero;

            for (int i = 0; i < paths.Count; i++)
            {
                f += paths[i];
            }
            f /= paths.Count;
            double sinAngle = Double2.SinAngle(line.normalizedDir, f - line.startPoint);

            if (sinAngle < 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
コード例 #12
0
 /// <summary>
 /// 与线段的关系
 /// </summary>
 /// <param name="line"></param>
 /// <returns></returns>
 public virtual LineRelation CheckLineRelation(LineSegment2D line)
 {
     return(LineRelation.Intersect);
 }
コード例 #13
0
 /// <summary>
 /// 获取挡格附近出生点
 /// </summary>
 /// <param name="line"></param>
 /// <param name="offset"></param>
 /// <param name="bornPoint"></param>
 /// <returns></returns>
 public virtual bool GetBornPoint(LineSegment2D line, float offset, ref Float2 bornPoint)
 {
     return(false);
 }
コード例 #14
0
ファイル: LineSegment2D.cs プロジェクト: 741645596/graph
 /// <summary>
 /// 获取交点
 /// </summary>
 /// <param name="line"></param>
 /// <param name="intersectPoint"></param>
 /// <returns></returns>
 public bool GetIntersectPoint(LineSegment2D line, ref Double2 intersectStartPoint, ref Double2 intersectEndPoint)
 {
     if (CheckLineRelation(line) == LineRelation.Intersect)
     {
         Double2 aixsVector = AixsVector(line.startPoint);
         double  distance   = aixsVector.magnitude;
         if (distance == 0)
         {
             if (Double2.Cross(line.normalizedDir, this.normalizedDir) == 0)
             {
                 if (Double2.Dot(line.normalizedDir, this.normalizedDir) > 0)
                 {
                     if (Double2.Dot(line.normalizedDir, this.startPoint - line.startPoint) > 0)
                     {
                         intersectStartPoint = this.startPoint;
                     }
                     else
                     {
                         intersectStartPoint = line.startPoint;
                     }
                     //
                     if (Double2.Dot(line.normalizedDir, this.endPoint - line.endPoint) > 0)
                     {
                         intersectEndPoint = line.endPoint;
                     }
                     else
                     {
                         intersectEndPoint = this.endPoint;
                     }
                 }
                 else
                 {
                     if (Double2.Dot(line.normalizedDir, this.startPoint - line.endPoint) > 0)
                     {
                         intersectEndPoint = line.endPoint;
                     }
                     else
                     {
                         intersectEndPoint = line.startPoint;
                     }
                     //
                     if (Double2.Dot(line.normalizedDir, this.endPoint - line.startPoint) > 0)
                     {
                         intersectStartPoint = this.endPoint;
                     }
                     else
                     {
                         intersectStartPoint = line.startPoint;
                     }
                 }
             }
             else
             {
                 intersectStartPoint = line.startPoint;
                 intersectEndPoint   = line.startPoint;
             }
             return(true);
         }
         else
         {
             if (CalcDistance(line.endPoint) == 0)
             {
                 intersectStartPoint = line.endPoint;
                 intersectEndPoint   = intersectStartPoint;
                 return(true);
             }
             //
             double dot = Double2.Dot(aixsVector.normalized, line.normalizedDir);
             if (dot == 0)
             {
                 return(false);
             }
             else
             {
                 intersectStartPoint = line.startPoint - distance / dot * line.normalizedDir;
                 intersectEndPoint   = intersectStartPoint;
                 return(true);
             }
         }
     }
     return(false);
 }
コード例 #15
0
 /// <summary>
 /// 获取交点
 /// </summary>
 /// <param name="line"></param>
 /// <param name="intersectStart"></param>
 /// <param name="intersectEnd"></param>
 /// <returns></returns>
 public virtual bool GetIntersectPoint(LineSegment2D line, ref Float2 intersectStart, ref Float2 intersectEnd)
 {
     return(false);
 }
コード例 #16
0
ファイル: Rays2D.cs プロジェクト: 741645596/graph
 /// <summary>
 /// 获取交点
 /// </summary>
 /// <param name="line"></param>
 /// <param name="intersectPoint"></param>
 /// <returns></returns>
 public bool GetIntersectPoint(LineSegment2D line, ref Double2 intersectStartPoint, ref Double2 intersectEndPoint)
 {
     return(line.GetIntersectPoint(this, ref intersectStartPoint));
 }
コード例 #17
0
ファイル: Rays2D.cs プロジェクト: 741645596/graph
 /// <summary>
 /// 与线段的关系
 /// </summary>
 /// <param name="line"></param>
 /// <returns></returns>
 public LineRelation CheckLineRelation(LineSegment2D line)
 {
     return(line.CheckLineRelation(this));
 }
コード例 #18
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();
            }
            int index = 0;

            Double3[] lineArray         = new Double3[2];
            Double2   intersectionPoint = Double2.zero;
            Double2   pos1 = Double2.zero;

            if (line.GetIntersectPoint(GetEdge(0), ref intersectionPoint, ref pos1) == true)
            {
                lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 1);
                index++;
            }
            if (line.GetIntersectPoint(GetEdge(2), ref intersectionPoint, ref pos1) == true)
            {
                lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 3);
                index++;
            }
            if (index < 2)
            {
                if (line.GetIntersectPoint(GetEdge(3), ref intersectionPoint, ref pos1) == true)
                {
                    lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 4);
                    index++;
                }
            }
            if (index < 2)
            {
                if (line.GetIntersectPoint(GetEdge(1), ref intersectionPoint, ref pos1) == true)
                {
                    lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 2);
                    index++;
                }
            }

            if (index == 2)
            {
                double  v1 = (new Double2(lineArray[0].x, lineArray[0].y) - line.startPoint).sqrMagnitude;
                double  v2 = (new Double2(lineArray[1].x, lineArray[1].y) - line.startPoint).sqrMagnitude;
                Double2 s;
                Double2 e;
                if (v1 < v2)
                {
                    s = new Double2(lineArray[0].x, lineArray[0].y);
                    e = new Double2(lineArray[1].x, lineArray[1].y);
                    RayboundingNearestPath(new Double3(s.x, s.y, lineArray[0].z), new Double3(e.x, e.y, lineArray[1].z), offset, ref rbi.listpath);
                }
                else
                {
                    e = new Double2(lineArray[0].x, lineArray[0].y);
                    s = new Double2(lineArray[1].x, lineArray[1].y);
                    RayboundingNearestPath(new Double3(s.x, s.y, lineArray[1].z), new Double3(e.x, e.y, lineArray[0].z), offset, ref rbi.listpath);
                }
                if (rbi.listpath != null && rbi.listpath.Count > 0)
                {
                    rbi.CalcHelpData(line, offset, s, e);
                    return(RBIResultType.Succ);
                }
                return(RBIResultType.Fail);
            }
            else
            {
                return(RBIResultType.Fail);
            }
        }
コード例 #19
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);
        }
コード例 #20
0
 /// <summary>
 /// 最短射线包围盒路径
 /// </summary>
 /// <param name="line">线段</param>
 /// <param name="offset">偏移值</param>
 /// <param name="paths">返回路径</param>
 /// <returns>true,表示线段与aabb有相交,并返回最短包围路径</returns>
 public virtual bool RayboundingNearestPath(LineSegment2D line, float offset, ref List <Float2> paths)
 {
     return(false);
 }
コード例 #21
0
ファイル: Polygon2D.cs プロジェクト: 741645596/graph
        /// <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();
            }
            List <Double3> lineArray         = new List <Double3>();
            Double2        intersectionPoint = Double2.zero;
            Double2        pos1 = Double2.zero;

            for (int i = 0; i < this.pointArr.Length; i++)
            {
                if (line.GetIntersectPoint(GetEdge(i), ref intersectionPoint, ref pos1) == true)
                {
                    lineArray.Add(new Double3(intersectionPoint.x, intersectionPoint.y, i));
                }
            }
            int count = lineArray.Count;

            if (count == 0)
            {
                return(RBIResultType.Fail);
            }
            else if (count % 2 == 1)
            {
                lineArray.Sort((x, y) => MathUtil.GetCompareDis(new Double2(x.x, x.y), line.startPoint).CompareTo(MathUtil.GetCompareDis(new Double2(y.x, y.y), line.startPoint)));
                if (CheckIn(line.startPoint) == true)
                {
                    rbi.SetNear(line, offset, new Double2(lineArray[0].x, lineArray[0].y));
                    return(RBIResultType.UnCrossstartPointIn);
                }
                else
                {
                    rbi.SetNear(line, offset, new Double2(lineArray[count - 1].x, lineArray[count - 1].y));
                    return(RBIResultType.UnCrossendPointIn);
                }
            }
            else
            {
                // 先按距离进行排序。
                lineArray.Sort((x, y) => MathUtil.GetCompareDis(new Double2(x.x, x.y), line.startPoint).CompareTo(MathUtil.GetCompareDis(new Double2(y.x, y.y), line.startPoint)));
                //
                bool isCross   = true;
                bool isPathDir = CheckPathDir(lineArray[0], lineArray[lineArray.Count - 1], ref isCross);
                if (isCross == false)
                {
                    rbi.SetNear(line, offset, new Double2(lineArray[0].x, lineArray[0].y));
                    return(RBIResultType.UnCross);
                }
                List <Double2> temppaths = new List <Double2>();
                RayboundingNearestPath(lineArray[0], lineArray[lineArray.Count - 1], offset, isPathDir, ref temppaths);
                if (rbi.listpath == null)
                {
                    rbi.listpath = temppaths;
                }
                else
                {
                    rbi.listpath.AddRange(temppaths);
                }
                // 排斥需要扣除的点。
                for (int i = 1; i < lineArray.Count - 1; i += 2)
                {
                    if (CheckisSubChild((int)lineArray[0].z, (int)lineArray[lineArray.Count - 1].z, isPathDir, (int)lineArray[i].z, (int)lineArray[i + 1].z) == false)
                    {
                        continue;
                    }
                    List <Double2> listTemp = new List <Double2>();
                    RayboundingNearestPath(lineArray[i], lineArray[i + 1], offset, isPathDir, ref listTemp);
                    if (listTemp.Count > 0)
                    {
                        foreach (Double2 pos in listTemp)
                        {
                            rbi.listpath.Remove(pos);
                        }
                    }
                }
                //
                if (rbi.listpath != null && rbi.listpath.Count > 0)
                {
                    rbi.CalcHelpData(line, offset, new Double2(lineArray[0].x, lineArray[0].y), new Double2(lineArray[lineArray.Count - 1].x, lineArray[lineArray.Count - 1].y));
                    return(RBIResultType.Succ);
                }
                return(RBIResultType.Fail);
            }
        }