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); }
/// <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); }