public void Equals() { var c1 = new Coordinate<int>(13, 14); var c2 = new Coordinate<int>(c1); var c3 = new Coordinate<int>(23, 24); Assert.IsTrue(c1.Equals(c2)); Assert.IsFalse(c1.Equals(c3)); }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="p1"></param> /// <param name="p2"></param> public override void ComputeIntersection(Coordinate p, Coordinate p1, Coordinate p2) { double a1; double b1; double c1; /* * Coefficients of line eqns. */ double r; /* * 'Sign' values */ IsProper = false; /* * Compute a1, b1, c1, where line joining points 1 and 2 * is "a1 x + b1 y + c1 = 0". */ a1 = p2.Y - p1.Y; b1 = p1.X - p2.X; c1 = p2.X * p1.Y - p1.X * p2.Y; /* * Compute r3 and r4. */ r = a1 * p.X + b1 * p.Y + c1; // if r != 0 the point does not lie on the line if (r != 0) { Result = NoIntersection; return; } // Point lies on line - check to see whether it lies in line segment. double dist = RParameter(p1, p2, p); if (dist < 0.0 || dist > 1.0) { Result = NoIntersection; return; } IsProper = true; if (p.Equals(p1) || p.Equals(p2)) IsProper = false; Result = PointIntersection; }
public void DifferentTypes() { var c1 = new Coordinate<int>(13, 14); var c2 = new Coordinate<double>(13, 14); Assert.IsFalse(c1.Equals(c2)); }
/// <summary> /// Computes the "edge distance" of an intersection point p along a segment. /// The edge distance is a metric of the point along the edge. /// The metric used is a robust and easy to compute metric function. /// It is not equivalent to the usual Euclidean metric. /// It relies on the fact that either the x or the y ordinates of the /// points in the edge are unique, depending on whether the edge is longer in /// the horizontal or vertical direction. /// NOTE: This function may produce incorrect distances /// for inputs where p is not precisely on p1-p2 /// (E.g. p = (139,9) p1 = (139,10), p2 = (280,1) produces distanct 0.0, which is incorrect. /// My hypothesis is that the function is safe to use for points which are the /// result of rounding points which lie on the line, but not safe to use for truncated points. /// </summary> public static double ComputeEdgeDistance(Coordinate p, Coordinate p0, Coordinate p1) { var dx = Math.Abs(p1.X - p0.X); var dy = Math.Abs(p1.Y - p0.Y); var dist = -1.0; // sentinel value if (p.Equals(p0)) dist = 0.0; else if (p.Equals(p1)) { dist = dx > dy ? dx : dy; } else { double pdx = Math.Abs(p.X - p0.X); double pdy = Math.Abs(p.Y - p0.Y); dist = dx > dy ? pdx : pdy; // <FIX>: hack to ensure that non-endpoints always have a non-zero distance if (dist == 0.0 && ! p.Equals2D(p0)) dist = Math.Max(pdx, pdy); } Assert.IsTrue(!(dist == 0.0 && ! p.Equals(p0)), "Bad distance calculation"); return dist; }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="p1"></param> /// <param name="p2"></param> public override void ComputeIntersection(Coordinate p, Coordinate p1, Coordinate p2) { IsProper = false; // do between check first, since it is faster than the orientation test if(Envelope.Intersects(p1, p2, p)) { if((CGAlgorithms.OrientationIndex(p1, p2, p) == 0) && (CGAlgorithms.OrientationIndex(p2, p1, p) == 0)) { IsProper = true; if (p.Equals(p1) || p.Equals(p2)) IsProper = false; Result = IntersectionTypes.PointIntersection; return; } } Result = IntersectionTypes.NoIntersection; }
/// <summary> /// Automatically closes the ring (if it not alread is). /// </summary> public void CloseRing() { if (_ptList.Count < 1) return; var startPt = new Coordinate(_ptList[0]); var lastPt = _ptList[_ptList.Count - 1]; /*Coordinate last2Pt = null; if (ptList.Count >= 2) last2Pt = (Coordinate)ptList[ptList.Count - 2];*/ if (startPt.Equals(lastPt)) return; _ptList.Add(startPt); }
public void TestEquals() { Coordinate c1 = new Coordinate(1, 2, 3); const string s = "Not a coordinate"; Assert.IsFalse(c1.Equals(s)); Coordinate c2 = new Coordinate(1, 2, 3); Assert.IsTrue(c1.Equals2D(c2)); Coordinate c3 = new Coordinate(1, 22, 3); Assert.IsFalse(c1.Equals2D(c3)); }
public void DiffCoordinateNotEquals() { //arrange Coordinate first = new Coordinate(1, 1); Coordinate second = new Coordinate(2, 2); bool expected = false; //act bool actual = first.Equals(second); //assert Assert.AreEqual(expected, actual); }
/// <summary> /// This function is non-robust, since it may compute the square of large numbers. /// Currently not sure how to improve this. /// </summary> public static double NonRobustComputeEdgeDistance(Coordinate p, Coordinate p1, Coordinate p2) { double dx = p.X - p1.X; double dy = p.Y - p1.Y; double dist = Math.Sqrt(dx * dx + dy * dy); // dummy value Assert.IsTrue(! (dist == 0.0 && ! p.Equals(p1)), "Invalid distance calculation"); return dist; }
/// <summary> /// Tests whether the segment p0-p1 intersects the hot pixel tolerance square. /// Because the tolerance square point set is partially open (along the /// top and right) the test needs to be more sophisticated than /// simply checking for any intersection. However, it /// can take advantage of the fact that because the hot pixel edges /// do not lie on the coordinate grid. It is sufficient to check /// if there is at least one of: /// - a proper intersection with the segment and any hot pixel edge. /// - an intersection between the segment and both the left and bottom edges. /// - an intersection between a segment endpoint and the hot pixel coordinate. /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <returns></returns> private bool IntersectsToleranceSquare(Coordinate p0, Coordinate p1) { bool intersectsLeft = false; bool intersectsBottom = false; _li.ComputeIntersection(p0, p1, _corner[0], _corner[1]); if (_li.IsProper) return true; _li.ComputeIntersection(p0, p1, _corner[1], _corner[2]); if (_li.IsProper) return true; if (_li.HasIntersection) intersectsLeft = true; _li.ComputeIntersection(p0, p1, _corner[2], _corner[3]); if (_li.IsProper) return true; if (_li.HasIntersection) intersectsBottom = true; _li.ComputeIntersection(p0, p1, _corner[3], _corner[0]); if (_li.IsProper) return true; if (intersectsLeft && intersectsBottom) return true; if (p0.Equals(_pt)) return true; if (p1.Equals(_pt)) return true; return false; }
private void doTestCoordinateHash(bool equal, Coordinate a, Coordinate b) { Assert.AreEqual(equal, a.Equals(b)); Assert.AreEqual(equal, a.GetHashCode() == b.GetHashCode()); }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> /// <param name="p4"></param> /// <returns></returns> public override IntersectionTypes ComputeIntersect(Coordinate p1, Coordinate p2, Coordinate p3, Coordinate p4) { /* * Coefficients of line eqns. */ /* * 'Sign' values */ IsProper = false; /* * Compute a1, b1, c1, where line joining points 1 and 2 * is "a1 x + b1 y + c1 = 0". */ double a1 = p2.Y - p1.Y; double b1 = p1.X - p2.X; double c1 = p2.X * p1.Y - p1.X * p2.Y; /* * Compute r3 and r4. */ double r3 = a1 * p3.X + b1 * p3.Y + c1; double r4 = a1 * p4.X + b1 * p4.Y + c1; /* * Check signs of r3 and r4. If both point 3 and point 4 lie on * same side of line 1, the line segments do not intersect. */ if (r3 != 0 && r4 != 0 && IsSameSignAndNonZero(r3, r4)) { return IntersectionTypes.NoIntersection; } /* * Compute a2, b2, c2 */ double a2 = p4.Y - p3.Y; double b2 = p3.X - p4.X; double c2 = p4.X * p3.Y - p3.X * p4.Y; /* * Compute r1 and r2 */ double r1 = a2 * p1.X + b2 * p1.Y + c2; double r2 = a2 * p2.X + b2 * p2.Y + c2; /* * Check signs of r1 and r2. If both point 1 and point 2 lie * on same side of second line segment, the line segments do * not intersect. */ if (r1 != 0 && r2 != 0 && IsSameSignAndNonZero(r1, r2)) { return IntersectionTypes.NoIntersection; } /* * Line segments intersect: compute intersection point. */ double denom = a1 * b2 - a2 * b1; if (denom == 0) return ComputeCollinearIntersection(p1, p2, p3, p4); double numX = b1 * c2 - b2 * c1; double x = numX / denom; double numY = a2 * c1 - a1 * c2; double y = numY / denom; PointA = new Coordinate(x, y); // check if this is a proper intersection BEFORE truncating values, // to avoid spurious equality comparisons with endpoints IsProper = true; if (PointA.Equals(p1) || PointA.Equals(p2) || PointA.Equals(p3) || PointA.Equals(p4)) IsProper = false; // truncate computed point to precision grid if (PrecisionModel != null) PrecisionModel.MakePrecise(PointA); return IntersectionTypes.PointIntersection; }
/// <summary>Computes the Projection Factor for the projection of the point p /// onto this LineSegment. The Projection Factor is the constant r /// by which the vector for this segment must be multiplied to /// equal the vector for the projection of <tt>p</tt> on the line /// defined by this segment. /// <para/> /// The projection factor will lie in the range <tt>(-inf, +inf)</tt>, /// or be <c>NaN</c> if the line segment has zero length. /// </summary> /// <param name="p">The point to compute the factor for</param> /// <returns>The projection factor for the point</returns> public double ProjectionFactor(Coordinate p) { if (p.Equals(_p0)) return 0.0; if (p.Equals(_p1)) return 1.0; // Otherwise, use comp.graphics.algorithms Frequently Asked Questions method /* AC dot AB r = ------------ ||AB||^2 r has the following meaning: r=0 Point = A r=1 Point = B r<0 Point is on the backward extension of AB r>1 Point is on the forward extension of AB 0<r<1 Point is interior to AB */ var dx = _p1.X - _p0.X; var dy = _p1.Y - _p0.Y; var len = dx * dx + dy * dy; // handle zero-length segments if (len <= 0.0) return Double.NaN; double r = ((p.X - _p0.X) * dx + (p.Y - _p0.Y) * dy) / len; return r; }
/// <summary> /// Compute the projection factor for the projection of the point p /// onto this <c>LineSegment</c>. The projection factor is the constant k /// by which the vector for this segment must be multiplied to /// equal the vector for the projection of p. /// </summary> /// <param name="p"></param> /// <returns></returns> public virtual double ProjectionFactor(Coordinate p) { if (p.Equals(P0)) return 0.0; if (p.Equals(P1)) return 1.0; // Otherwise, use comp.graphics.algorithms Frequently Asked Questions method /* AC dot AB r = ------------ ||AB||^2 r has the following meaning: r=0 Point = A r=1 Point = B r<0 Point is on the backward extension of AB r>1 Point is on the forward extension of AB 0<r<1 Point is interior to AB */ double dx = P1.X - P0.X; double dy = P1.Y - P0.Y; double len2 = dx * dx + dy * dy; double r = ((p.X - P0.X) * dx + (p.Y - P0.Y) * dy) / len2; return r; }
public static bool IsInList(Coordinate pt, Coordinate[] pts) { foreach (Coordinate p in pts) if (pt.Equals(p)) return true; return true; }
private static void CheckCollapse(Coordinate p0, Coordinate p1, Coordinate p2) { if (p0.Equals(p2)) throw new ApplicationException(String.Format( "found non-noded collapse at: {0}, {1} {2}", p0, p1, p2)); }
/// <summary> /// /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="p2"></param> private static void CheckCollapse(Coordinate p0, Coordinate p1, Coordinate p2) { if (p0.Equals(p2)) throw new Exception("found non-noded collapse at: " + p0 + ", " + p1 + " " + p2); }
/// <summary> /// Computes the distance from a line segment AB to a line segment CD. /// Note: NON-ROBUST! /// </summary> /// <param name="A">A point of one line.</param> /// <param name="B">The second point of the line (must be different to A).</param> /// <param name="C">One point of the line.</param> /// <param name="D">Another point of the line (must be different to A).</param> /// <returns>The distance from line segment AB to line segment CD.</returns> public static double DistanceLineLine(Coordinate A, Coordinate B, Coordinate C, Coordinate D) { // check for zero-length segments if (A.Equals(B)) return DistancePointLine(A,C,D); if (C.Equals(D)) return DistancePointLine(D,A,B); // AB and CD are line segments /* from comp.graphics.algo Solving the above for r and s yields (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) r = ----------------------------- (eqn 1) (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) s = ----------------------------- (eqn 2) (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) Let Point be the position vector of the intersection point, then Point=A+r(B-A) or Px=Ax+r(Bx-Ax) Py=Ay+r(By-Ay) By examining the values of r & s, you can also determine some other limiting conditions: If 0<=r<=1 & 0<=s<=1, intersection exists r<0 or r>1 or s<0 or s>1 line segments do not intersect If the denominator in eqn 1 is zero, AB & CD are parallel If the numerator in eqn 1 is also zero, AB & CD are collinear. */ double r_top = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y); double r_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); double s_top = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y); double s_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); if ((r_bot==0) || (s_bot == 0)) return Math.Min(DistancePointLine(A,C,D), Math.Min(DistancePointLine(B,C,D), Math.Min(DistancePointLine(C,A,B), DistancePointLine(D,A,B) ) ) ); double s = s_top/s_bot; double r = r_top/r_bot; if ((r < 0) || ( r > 1) || (s < 0) || (s > 1)) //no intersection return Math.Min(DistancePointLine(A,C,D), Math.Min(DistancePointLine(B,C,D), Math.Min(DistancePointLine(C,A,B), DistancePointLine(D,A,B) ) ) ); return 0.0; //intersection exists }
/// <summary> /// Computes the distance from a point p to a line segment AB. /// Note: NON-ROBUST! /// </summary> /// <param name="p">The point to compute the distance for.</param> /// <param name="A">One point of the line.</param> /// <param name="B">Another point of the line (must be different to A).</param> /// <returns> The distance from p to line segment AB.</returns> public static double DistancePointLine(Coordinate p, Coordinate A, Coordinate B) { // if start == end, then use pt distance if (A.Equals(B)) return p.Distance(A); // otherwise use comp.graphics.algorithms Frequently Asked Questions method /*(1) AC dot AB r = --------- ||AB||^2 r has the following meaning: r=0 Point = A r=1 Point = B r<0 Point is on the backward extension of AB r>1 Point is on the forward extension of AB 0<r<1 Point is interior to AB */ double r = ( (p.X - A.X) * (B.X - A.X) + (p.Y - A.Y) * (B.Y - A.Y) ) / ( (B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y) ); if (r <= 0.0) return p.Distance(A); if (r >= 1.0) return p.Distance(B); /*(2) (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) s = ----------------------------- Curve^2 Then the distance from C to Point = |s|*Curve. */ double s = ( (A.Y - p.Y) * (B.X - A.X) - (A.X - p.X) * (B.Y - A.Y) ) / ( (B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y) ); return Math.Abs(s) * Math.Sqrt(((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y))); }
/// <summary> /// /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="q1"></param> /// <param name="q2"></param> /// <returns></returns> private IntersectionTypes ComputeCollinearIntersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { bool p1q1p2 = Envelope.Intersects(p1, p2, q1); bool p1q2p2 = Envelope.Intersects(p1, p2, q2); bool q1p1q2 = Envelope.Intersects(q1, q2, p1); bool q1p2q2 = Envelope.Intersects(q1, q2, p2); if(p1q1p2 && p1q2p2) { IntersectionPoints[0] = q1; IntersectionPoints[1] = q2; return IntersectionTypes.Collinear; } if(q1p1q2 && q1p2q2) { IntersectionPoints[0] = p1; IntersectionPoints[1] = p2; return IntersectionTypes.Collinear; } if(p1q1p2 && q1p1q2) { IntersectionPoints[0] = q1; IntersectionPoints[1] = p1; return q1.Equals(p1) && !p1q2p2 && !q1p2q2 ? IntersectionTypes.PointIntersection : IntersectionTypes.Collinear; } if(p1q1p2 && q1p2q2) { IntersectionPoints[0] = q1; IntersectionPoints[1] = p2; return q1.Equals(p2) && !p1q2p2 && !q1p1q2 ? IntersectionTypes.PointIntersection : IntersectionTypes.Collinear; } if(p1q2p2 && q1p1q2) { IntersectionPoints[0] = q2; IntersectionPoints[1] = p1; return q2.Equals(p1) && !p1q1p2 && !q1p2q2 ? IntersectionTypes.PointIntersection : IntersectionTypes.Collinear; } if(p1q2p2 && q1p2q2) { IntersectionPoints[0] = q2; IntersectionPoints[1] = p2; return q2.Equals(p2) && !p1q1p2 && !q1p1q2 ? IntersectionTypes.PointIntersection : IntersectionTypes.Collinear; } return IntersectionTypes.NoIntersection; }
/// <summary> /// /// </summary> /// <param name="pt"></param> private void AddPt(Coordinate pt) { Coordinate bufPt = new Coordinate(pt); _precisionModel.MakePrecise(bufPt); // don't add duplicate points Coordinate lastPt = null; if (_ptList.Count >= 1) lastPt = _ptList.Last(); if (lastPt != null && bufPt.Equals(lastPt)) return; _ptList.Add(bufPt); }
/// <summary> /// /// </summary> private void ClosePts() { if (_ptList.Count < 1) return; Coordinate startPt = new Coordinate(_ptList[0]); Coordinate lastPt = _ptList[_ptList.Count - 1]; if (startPt.Equals(lastPt)) return; _ptList.Add(startPt); }
/// <summary> /// /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="tolerance"></param> /// <returns></returns> protected virtual bool Equal(Coordinate a, Coordinate b, double tolerance) { if (tolerance == 0) return a.Equals(b); return a.Distance(b) <= tolerance; }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="l"></param> /// <returns></returns> private static Location Locate(Coordinate p, ILineString l) { // bounding-box check if (!l.EnvelopeInternal.Intersects(p)) return Location.Exterior; Coordinate[] pt = l.Coordinates; if(!l.IsClosed) if(p.Equals(pt[0]) || p.Equals(pt[pt.Length - 1])) return Location.Boundary; if (CGAlgorithms.IsOnLine(p, pt)) return Location.Interior; return Location.Exterior; }
/// <summary> /// Computes the distance from a line segment AB to a line segment CD. /// Note: NON-ROBUST! /// </summary> /// <param name="A">A point of one line.</param> /// <param name="B">The second point of the line (must be different to A).</param> /// <param name="C">One point of the line.</param> /// <param name="D">Another point of the line (must be different to A).</param> /// <returns>The distance from line segment AB to line segment CD.</returns> public static double DistanceLineLine(Coordinate A, Coordinate B, Coordinate C, Coordinate D) { // check for zero-length segments if (A.Equals(B)) return DistancePointLine(A,C,D); if (C.Equals(D)) return DistancePointLine(D,A,B); // AB and CD are line segments /* from comp.graphics.algo * * Solving the above for r and s yields * * (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) * r = ----------------------------- (eqn 1) * (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) * * (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) * s = ----------------------------- (eqn 2) * (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) * * Let P be the position vector of the * intersection point, then * P=A+r(B-A) or * Px=Ax+r(Bx-Ax) * Py=Ay+r(By-Ay) * By examining the values of r & s, you can also determine some other limiting * conditions: * If 0<=r<=1 & 0<=s<=1, intersection exists * r<0 or r>1 or s<0 or s>1 line segments do not intersect * If the denominator in eqn 1 is zero, AB & CD are parallel * If the numerator in eqn 1 is also zero, AB & CD are collinear. */ var noIntersection = false; if (!Envelope.Intersects(A, B, C, D)) { noIntersection = true; } else { var denom = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); if (denom == 0) { noIntersection = true; } else { var r_num = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y); var s_num = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y); var s = s_num / denom; var r = r_num / denom; if ((r < 0) || (r > 1) || (s < 0) || (s > 1)) { noIntersection = true; } } } if (noIntersection) { return MathUtil.Min( DistancePointLine(A, C, D), DistancePointLine(B, C, D), DistancePointLine(C, A, B), DistancePointLine(D, A, B)); } // segments intersect return 0.0; }
/// <summary> /// Tests whether the segment p0-p1 intersects the hot pixel tolerance square. /// Because the tolerance square point set is partially open (along the /// top and right) the test needs to be more sophisticated than /// simply checking for any intersection. /// However, it can take advantage of the fact that the hot pixel edges /// do not lie on the coordinate grid. /// It is sufficient to check if any of the following occur: /// - a proper intersection between the segment and any hot pixel edge. /// - an intersection between the segment and BOTH the left and bottom hot pixel edges /// (which detects the case where the segment intersects the bottom left hot pixel corner). /// - an intersection between a segment endpoint and the hot pixel coordinate. /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <returns></returns> private bool IntersectsToleranceSquare(Coordinate p0, Coordinate p1) { var intersectsLeft = false; var intersectsBottom = false; //Console.WriteLine("Hot Pixel: " + WKTWriter.ToLineString(corner)); //Console.WriteLine("Line: " + WKTWriter.ToLineString(p0, p1)); _li.ComputeIntersection(p0, p1, _corner[0], _corner[1]); if (_li.IsProper) return true; _li.ComputeIntersection(p0, p1, _corner[1], _corner[2]); if (_li.IsProper) return true; if (_li.HasIntersection) intersectsLeft = true; _li.ComputeIntersection(p0, p1, _corner[2], _corner[3]); if (_li.IsProper) return true; if (_li.HasIntersection) intersectsBottom = true; _li.ComputeIntersection(p0, p1, _corner[3], _corner[0]); if (_li.IsProper) return true; if (intersectsLeft && intersectsBottom) return true; if (p0.Equals(_pt)) return true; if (p1.Equals(_pt)) return true; return false; }
/// <summary> /// Compute the projection of a point onto the line determined /// by this line segment. /// Notice that the projected point /// may lie outside the line segment. If this is the case, /// the projection factor will lie outside the range [0.0, 1.0]. /// </summary> /// <param name="p"></param> /// <returns></returns> public virtual Coordinate Project(Coordinate p) { if (p.Equals(P0) || p.Equals(P1)) return new Coordinate(p); double r = ProjectionFactor(p); Coordinate coord = new Coordinate(); coord.X = P0.X + r * (P1.X - P0.X); coord.Y = P0.Y + r * (P1.Y - P0.Y); return coord; }
private void Move(Coordinate currentCoordinate, Coordinate target, int step) { //reached target if (currentCoordinate.Equals(target)) { //_pathFound = true; return; } //try up if(IsCellInsideLabyrinth(currentCoordinate.X, currentCoordinate.Y - 1) && CanMoveTo(currentCoordinate, MoveDirection.Up) && !HasBeenThere(new Coordinate(currentCoordinate.X, currentCoordinate.Y - 1))) { _tempLabirynth[currentCoordinate.X, currentCoordinate.Y - 1] = step; //Move(new Coordinate(currentCoordinate.X, currentCoordinate.Y - 1), target, step + 1); } //try down if (IsCellInsideLabyrinth(currentCoordinate.X, currentCoordinate.Y + 1) && CanMoveTo(currentCoordinate, MoveDirection.Down) && !HasBeenThere(new Coordinate(currentCoordinate.X, currentCoordinate.Y + 1))) { _tempLabirynth[currentCoordinate.X, currentCoordinate.Y + 1] = step; //Move(new Coordinate(currentCoordinate.X, currentCoordinate.Y + 1), target, step + 1); } //try left if(IsCellInsideLabyrinth(currentCoordinate.X - 1, currentCoordinate.Y) && CanMoveTo(currentCoordinate, MoveDirection.Left) && !HasBeenThere(new Coordinate(currentCoordinate.X - 1, currentCoordinate.Y))) { _tempLabirynth[currentCoordinate.X - 1, currentCoordinate.Y] = step; //Move(new Coordinate(currentCoordinate.X - 1, currentCoordinate.Y), target, step + 1); } //try right if (IsCellInsideLabyrinth(currentCoordinate.X + 1, currentCoordinate.Y) && CanMoveTo(currentCoordinate, MoveDirection.Right) && !HasBeenThere(new Coordinate(currentCoordinate.X + 1, currentCoordinate.Y))) { _tempLabirynth[currentCoordinate.X + 1, currentCoordinate.Y] = step; //Move(new Coordinate(currentCoordinate.X + 1, currentCoordinate.Y), target, step + 1); } }
/// <summary> /// Compute the projection of a point onto the line determined /// by this line segment. /// Note that the projected point may lie outside the line segment. /// If this is the case, the projection factor will lie outside the range [0.0, 1.0]. /// </summary> /// <param name="p"></param> /// <returns></returns> public Coordinate Project(Coordinate p) { if (p.Equals(_p0) || p.Equals(_p1)) return new Coordinate(p); var r = ProjectionFactor(p); var coord = new Coordinate { X = _p0.X + r * (_p1.X - _p0.X), Y = _p0.Y + r * (_p1.Y - _p0.Y) }; return coord; }
public void SameCoordinateEquals() { //arrange Coordinate first = new Coordinate(1, 1); Coordinate second = new Coordinate(1, 1); bool expected = true; //act bool actual = first.Equals(second); //assert Assert.AreEqual(expected, actual); }