public override double Distance(PointF2D point) { VectorF2D vectorF2D = point - this._a; double num1 = VectorF2D.Cross(this.Direction, vectorF2D); double length = this.Length; double num2 = point.Distance(this._a); double num3 = point.Distance(this._b); double num4 = System.Math.Abs(num1 / length); if (this.IsSegment) { if (VectorF2D.Dot(vectorF2D, this.Direction) < 0.0 && num1 != 0.0) { num4 = this._a.Distance(point); } else if (num1 == 0.0 && (num2 >= length || num3 >= length)) { num4 = num2 <= num3?this._a.Distance(point) : this._b.Distance(point); } if (VectorF2D.Dot(point - this._b, this.Direction.Inverse) < 0.0 && num1 != 0.0) { num4 = this._b.Distance(point); } } return(num4); }
/// <summary> /// Returns the distance from the point to this line. /// </summary> /// <param name="point"></param> /// <returns></returns> public override double Distance(PointF2D point) { double distance = 0.0f; // get the second vector for the cross product. VectorF2D a_point = point - _a; // get the cross product. double cross = VectorF2D.Cross(this.Direction, a_point); // distances between a, b and point. double distance_a_b = this.Length; double distance_a = point.Distance(_a); double distance_b = point.Distance(_b); // calculate distance to line as if it were no segment. distance = System.Math.Abs(cross / distance_a_b); // if this line is a segment. if (this.IsSegment) { double dot1 = VectorF2D.Dot(a_point, this.Direction); if (dot1 < 0 && cross != 0) { distance = _a.Distance(point); } else if (cross == 0 && (distance_a >= distance_a_b || distance_b >= distance_a_b)) { // check if the point is between the points. if (distance_a > distance_b) { // if the distance to a is greater then the point is at the b-side. distance = _b.Distance(point); } else {// if the distance to b is greater then the point is at the a-side. distance = _a.Distance(point); } } VectorF2D b_point = point - _b; double dot2 = VectorF2D.Dot(b_point, this.Direction.Inverse); if (dot2 < 0 && cross != 0) { distance = _b.Distance(point); } } return(distance); }
/// <summary> /// Adds a line. /// </summary> /// <param name="maxZoom"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="width">Width.</param> /// <param name="minZoom"></param> /// <returns>The line.</returns> public override uint AddLine(int layer, float minZoom, float maxZoom, double[] x, double[] y, int color, double width, LineJoin lineJoin, int[] dashes) { // add the line but simplify it for higher zoom levels. float currentMaxZoom = float.MaxValue; for (int idx = 0; idx < _zoomLevelCutoffs.Count; idx++) { float currentMinZoom = _zoomLevelCutoffs[idx]; if (!(currentMinZoom >= maxZoom) && !(currentMaxZoom < minZoom)) { float thisMinZoom = System.Math.Max(currentMinZoom, minZoom); float thisMaxZoom = System.Math.Min(currentMaxZoom, maxZoom); // simplify the algorithm. double epsilon = this.CalculateSimplificationEpsilon(thisMaxZoom); double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y }, epsilon); double distance = epsilon; if (simplified[0].Length == 2) { // check if the simplified version is smaller than epsilon. OsmSharp.Math.Primitives.PointF2D point1 = new OsmSharp.Math.Primitives.PointF2D( simplified[0][0], simplified[0][1]); OsmSharp.Math.Primitives.PointF2D point2 = new OsmSharp.Math.Primitives.PointF2D( simplified[1][0], simplified[0][1]); distance = point1.Distance(point2); } if (distance >= epsilon && this.CalculateSimplificationSurfaceCondition(currentMaxZoom, x, y)) { // add to the scene. if (_scenes[idx] == null) { _scenes[idx] = new Scene2DSimple(); } _scenes[idx].AddLine(layer, thisMinZoom, thisMaxZoom, simplified[0], simplified[1], color, width, lineJoin, dashes); } } currentMaxZoom = currentMinZoom; // move to the next cutoff. } return(0); }
public void Point2DTest() { // create the test cases. PointF2D a = new PointF2D(0, 0); PointF2D b = new PointF2D(1, 1); // calculate the results double sqrt_2 = (double)System.Math.Sqrt(2); //double sqrt_2_div_2 = (double)System.Math.Sqrt(2) / 2.0f; // test distance. Assert.AreEqual(a.Distance(b), sqrt_2, string.Format("Distance should be {0}!", sqrt_2)); // test substraction into vector. VectorF2D ab = b - a; Assert.AreEqual(ab[0], 1, "Vector should be 1 at index 0!"); Assert.AreEqual(ab[1], 1, "Vector should be 1 at index 1!"); VectorF2D ba = a - b; Assert.AreEqual(ba[0], -1, "Vector should be -1 at index 0!"); Assert.AreEqual(ba[1], -1, "Vector should be -1 at index 1!"); }
/// <summary> /// Adds a line. /// </summary> /// <param name="maxZoom"></param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="width">Width.</param> /// <param name="minZoom"></param> /// <returns>The line.</returns> public override uint AddLine(int layer, float minZoom, float maxZoom, double[] x, double[] y, int color, double width, LineJoin lineJoin, int[] dashes) { // add the line but simplify it for higher zoom levels. float currentMaxZoom = float.MaxValue; for (int idx = 0; idx < _zoomLevelCutoffs.Count; idx++) { float currentMinZoom = _zoomLevelCutoffs[idx]; if (!(currentMinZoom >= maxZoom) && !(currentMaxZoom < minZoom)) { float thisMinZoom = System.Math.Max(currentMinZoom, minZoom); float thisMaxZoom = System.Math.Min(currentMaxZoom, maxZoom); // simplify the algorithm. double epsilon = this.CalculateSimplificationEpsilon(thisMaxZoom); double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y }, epsilon); double distance = epsilon * 2; if (simplified[0].Length == 2) { // check if the simplified version is smaller than epsilon. OsmSharp.Math.Primitives.PointF2D point1 = new OsmSharp.Math.Primitives.PointF2D( simplified[0][0], simplified[0][1]); OsmSharp.Math.Primitives.PointF2D point2 = new OsmSharp.Math.Primitives.PointF2D( simplified[1][0], simplified[0][1]); distance = point1.Distance(point2); } if (distance >= epsilon) { // add to the scene. if (_scenes[idx] == null) { _scenes[idx] = new Scene2DSimple(); } _scenes[idx].AddLine(layer, thisMinZoom, thisMaxZoom, simplified[0], simplified[1], color, width, lineJoin, dashes); } } currentMaxZoom = currentMinZoom; // move to the next cutoff. } return 0; }
/// <summary> /// Calculates the distance between this point and the given point. /// </summary> /// <param name="p"></param> /// <returns></returns> public override double Distance(PointF2D p) { return(PointF2D.Distance(this, p)); }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, out Scene2D.ScenePoints found) { PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in lines) { if (line.Value.Equals(style)) { // check first. PointF2D potentialFirst = new PointF2D(line.Key.X[0], line.Key.Y[0]); if (first.Distance(potentialFirst) < _epsilon) { found = line.Key; position = MatchPosition.FirstFirst; break; } if (last.Distance(potentialFirst) < _epsilon) { found = line.Key; position = MatchPosition.LastFirst; break; } PointF2D potentialLast = new PointF2D(line.Key.X[line.Key.X.Length - 1], line.Key.Y[line.Key.Y.Length - 1]); if (first.Distance(potentialLast) < _epsilon) { found = line.Key; position = MatchPosition.FirstLast; break; } if (last.Distance(potentialLast) < _epsilon) { found = line.Key; position = MatchPosition.LastLast; break; } } } return position; }
/// <summary> /// Returns the distance from the point to this line. /// </summary> /// <param name="point"></param> /// <returns></returns> public override double Distance(PointF2D point) { double distance = 0.0f; // get the second vector for the cross product. VectorF2D a_point = point - _a; // get the cross product. double cross = VectorF2D.Cross(this.Direction, a_point); // distances between a, b and point. double distance_a_b = this.Length; double distance_a = point.Distance(_a); double distance_b = point.Distance(_b); // calculate distance to line as if it were no segment. distance = System.Math.Abs(cross / distance_a_b); // if this line is a segment. if(this.IsSegment) { double dot1 = VectorF2D.Dot(a_point, this.Direction); if (dot1 < 0 && cross != 0) { distance = _a.Distance(point); } else if (cross == 0 && (distance_a >= distance_a_b || distance_b >= distance_a_b)) { // check if the point is between the points. if (distance_a > distance_b) { // if the distance to a is greater then the point is at the b-side. distance = _b.Distance(point); } else {// if the distance to b is greater then the point is at the a-side. distance = _a.Distance(point); } } VectorF2D b_point = point - _b; double dot2 = VectorF2D.Dot(b_point, this.Direction.Inverse); if (dot2 < 0 && cross != 0) { distance = _b.Distance(point); } } return distance; }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(ILocatedObjectIndex<PointF2D, Scene2D.ScenePoints> linesIndex, Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, float epsilon, out Scene2D.ScenePoints found) { // build box. var box = new BoxF2D(x, y); box = box.ResizeWith(epsilon * 1.1); // get all geometries in this box. var potentialMatches = linesIndex.GetInside(box); // find a match in the potential matches list. PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in potentialMatches) { // check first. PointF2D potentialFirst = new PointF2D(line.X[0], line.Y[0]); PointF2D potentialLast = new PointF2D(line.X[line.X.Length - 1], line.Y[line.Y.Length - 1]); if (first.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.FirstFirst; } else if (last.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.LastFirst; } else if (first.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.FirstLast; } else if (last.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.LastLast; } Scene2DStylesSet styleValue; if (position != MatchPosition.None && lines.TryGetValue(line, out styleValue) && styleValue.Equals(style)) { break; } else { position = MatchPosition.None; found = null; } } return position; }