示例#1
0
        public void TestDistanceOfPointAndLine()
        {
            Vector2 lpo = new Vector2()
            {
                X = 0, Y = 10
            };                                                              //直线上的点点
            Vector2 lv = new Vector2()
            {
                X = 1, Y = 1
            };                                                              //直线方向向量(非0)
            Vector2 outerPoint = new Vector2()
            {
                X = 10, Y = 10
            };                                                              //直线上或者直线外的一点
            Vector2 result = new Vector2()
            {
                X = 1, Y = 1
            };                                                                                         //过outerPoint作l的垂线,result为垂足
            float distance = OutputCoordinate.DistanceOfPointAndLine(lpo, lv, outerPoint, ref result); //点到直线距离

            Assert.AreEqual(distance, 5 * Math.Sqrt(2), delta);
            Assert.IsFalse(result.X == 1);
            Assert.IsFalse(result.Y == 1);
            float dotMulti = Vector2.Dot(outerPoint - result, lv);          //垂线

            Assert.AreEqual(dotMulti, 0f, delta);
            Vector2 result2   = new Vector2();
            float   distance2 = OutputCoordinate.DistanceOfPointAndLine(lpo, lv, result, ref result2);     //垂足在l上

            Assert.AreEqual(distance2, 0f, delta);
        }
示例#2
0
        /// <summary>
        /// 直线可能与另一条直线相交,交点有0,、1个,也可能与一个圆相交,交点有0、1、2个
        /// </summary>
        /// <param name="another">another可能是一个Circle或者Line</param>
        /// <returns>交点是一个Point2的数组(List)</returns>
        List <Point2> IPointSet.Intersection(IPointSet another)
        {
            List <Point2> pcl = new List <Point2>();          //point cross list

            if (another is Line)
            {
                Line             l2     = another as Line;      //转换
                Vector2          v1     = this.GetVector();
                Vector2          v2     = l2.GetVector();
                Point2           p1     = this.GetCenterPoint();
                Point2           p2     = l2.GetCenterPoint();
                FMatrix <double> matrix = new FMatrix <double>(2, 3, 0);
                //if(Vector2.Zero)                              //理论上来说两个直线方向向量都不会为0
                Vector3 v31 = new Vector3()
                {
                    X = v1.X, Y = v1.Y, Z = 0
                };
                Vector3 v32 = new Vector3()
                {
                    X = v2.X, Y = v2.Y, Z = 0
                };
                Vector3 multiVector = Vector3.Cross(v31, v32);       //向量积、叉积
                if (multiVector.Length() > 1e-7)                     //几乎平行
                {
                    matrix[0][0] = v1.X;
                    matrix[0][1] = -v2.X;
                    matrix[0][2] = p2.X - p1.X;

                    matrix[1][0] = v1.Y;
                    matrix[1][1] = -v2.Y;
                    matrix[1][2] = p2.Y - p1.Y;

                    FMatrix <double> simpleMatrix = FMatrix <double> .RowSimplestFormOf(matrix);

                    Point2 onePoint = new Point2()
                    {
                        X = p1.X + (float)simpleMatrix[0][2] * v1.X, Y = p1.Y + (float)simpleMatrix[0][2] * v1.Y
                    };
                    onePoint.rely.Add(this);
                    onePoint.rely.Add((Geometry)another);
                    onePoint.markOfTwoIntersectPointOnCircle = true;
                    pcl.Add(onePoint);     //存在一个交点
                }
            }
            else if (another is Circle)
            {
                Circle  c2     = another as Circle;
                float   radius = c2.GetRadius();
                Vector2 lv     = this.GetVector();
                Vector2 result = new Vector2();

                float distance = OutputCoordinate.DistanceOfPointAndLine(this.GetCenterPoint().ToVector2(), this.GetVector(), c2.center.ToVector2(), ref result);

                float halfChord = (float)Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow(distance, 2.0)); //弦长的一半
                if (radius >= distance)                                                              //直线过圆
                {
                    Vector2 lve = Vector2.Normalize(lv);
                    Vector2 vd1 = lve * halfChord;
                    Vector2 vd2 = Vector2.Negate(lve) * halfChord;
                    Point2  p1  = new Point2()
                    {
                        X = result.X + vd1.X, Y = result.Y + vd1.Y
                    };
                    Point2 p2 = new Point2()
                    {
                        X = result.X + vd2.X, Y = result.Y + vd2.Y
                    };
                    bool counterclockwise = true;                                                                      //逆时针
                    if ((p1.X - c2.center.X) * (p2.Y - c2.center.Y) - (p1.Y - c2.center.Y) * (p2.X - c2.center.X) < 0) //顺时针
                    {
                        counterclockwise = false;
                    }
                    p1.rely.Add(this);
                    p1.rely.Add((Geometry)another);
                    p1.markOfTwoIntersectPointOnCircle = counterclockwise;
                    p2.rely.Add(this);
                    p2.rely.Add((Geometry)another);
                    p2.markOfTwoIntersectPointOnCircle = !counterclockwise;
                    pcl.Add(p1);
                    pcl.Add(p2);
                }
            }
            return(pcl);
        }