public double[] TransformFrom(double width, double height, bool reverseX, bool reverseY, double x, double y) { PointF2D pointF2D = this._bottomLeft; VectorF2D vectorF2D1 = this._vectorX; VectorF2D vectorF2D2 = this._vectorY; if (reverseX && !reverseY) { pointF2D = this.BottomRight; vectorF2D1 = this._vectorX * -1.0; } else if (!reverseX & reverseY) { pointF2D = this.TopLeft; vectorF2D2 = this._vectorY * -1.0; } else if (reverseX & reverseY) { pointF2D = this.TopRight; vectorF2D1 = this._vectorX * -1.0; vectorF2D2 = this._vectorY * -1.0; } double num1 = x / width; double num2 = y / height; return((pointF2D + vectorF2D1 * num1 + vectorF2D2 * num2).ToArray()); }
/// <summary> /// Returns all the intersections the line has with this polygon. /// </summary> /// <param name="line"></param> /// <returns></returns> public PointF2D[] Intersections(LineF2D line) { List <PointF2D> points = new List <PointF2D>(); foreach (LineF2D polygon_line in this.LineEnumerator) { // calculate the intersection. PrimitiveF2D primitive = line.Intersection(polygon_line); // the primitive not null. if (primitive != null) { if (primitive is LineF2D) { // primitive is a line; convert. LineF2D intersect_line = (primitive as LineF2D); // we are sure the line is a segment. // if the line is not a segment this means that the polygon contains an line with infinite length; impossible. // TODO: how to determine the order? points.Add(intersect_line.Point1); points.Add(intersect_line.Point2); } else if (primitive is PointF2D) { // primitive is a point; convert. PointF2D point = (primitive as PointF2D); points.Add(point); } } } return(points.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="x">The x coordinate of the bottom-left corner.</param> /// <param name="y">The y coordinate of the bottom-left corner.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="angleY">The angle relative to the y-axis.</param> public RectangleF2D(double x, double y, double width, double height, Degree angleY) { _bottomLeft = new PointF2D (x, y); VectorF2D directionY = VectorF2D.FromAngleY (angleY); _vectorY = directionY * height; _vectorX = directionY.Rotate90 (true) * width; }
/// <summary> /// Transforms the given coordinates to the coordinate system this rectangle is defined in. /// </summary> /// <param name="width">The width of the rectangle in the coordinate system of the given coordinates.</param> /// <param name="height">The height of the rectangle in the coordinate system of the given coordinates.</param> /// <param name="reverseX">Assumes that the origin of the x-axis is on the top of this rectangle if false.</param> /// <param name="reverseY">Assumes that the origin of the y-axis is on the right of this rectangle if false.</param> /// <param name="x">The x-coordinates to transform.</param> /// <param name="y">The y-coordinates to transform.</param> public double[] TransformFrom(double width, double height, bool reverseX, bool reverseY, double x, double y) { PointF2D reference = _bottomLeft; VectorF2D vectorX = _vectorX; VectorF2D vectorY = _vectorY; if (reverseX && !reverseY) { reference = this.BottomRight; vectorX = _vectorX * -1; } else if (!reverseX && reverseY) { reference = this.TopLeft; vectorY = _vectorY * -1; } else if (reverseX && reverseY) { reference = this.TopRight; vectorX = _vectorX * -1; vectorY = _vectorY * -1; } double widthFactor = x / width; double heightFactor = y / height; PointF2D result = reference + (vectorX * widthFactor) + (vectorY * heightFactor); return(result.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">Direction y.</param> public RectangleF2D(double x, double y, double width, double height, VectorF2D directionY) { _bottomLeft = new PointF2D(x, y); directionY = directionY.Normalize(); _vectorY = directionY * height; _vectorX = directionY.Rotate90(true) * width; }
public PointF2D ProjectOn(PointF2D point) { if (this.Length == 0.0 && this.IsSegment) { return((PointF2D)null); } VectorF2D vectorF2D = this.Direction.Rotate90(true); PointF2D b = new PointF2D((point + vectorF2D).ToArray()); if (point[0] == b[0] && point[1] == b[1]) { return(b); } PrimitiveF2D primitiveF2D = this.Intersection(new LineF2D(point, b, false, false), true); if (primitiveF2D == null) { return((PointF2D)null); } if ((object)(primitiveF2D as PointF2D) != null) { return(primitiveF2D as PointF2D); } throw new InvalidOperationException(); }
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); }
public double[][] TransformFrom(double width, double height, bool reverseX, bool reverseY, double[] x, double[] y) { PointF2D pointF2D1 = this._bottomLeft; VectorF2D vectorF2D1 = this._vectorX; VectorF2D vectorF2D2 = this._vectorY; if (reverseX && !reverseY) { pointF2D1 = this.BottomRight; vectorF2D1 = this._vectorX * -1.0; } else if (!reverseX & reverseY) { pointF2D1 = this.TopLeft; vectorF2D2 = this._vectorY * -1.0; } else if (reverseX & reverseY) { pointF2D1 = this.TopRight; vectorF2D1 = this._vectorX * -1.0; vectorF2D2 = this._vectorY * -1.0; } double[][] numArray = new double[x.Length][]; for (int index = 0; index < x.Length; ++index) { double num1 = x[index] / width; double num2 = y[index] / height; PointF2D pointF2D2 = pointF2D1 + vectorF2D1 * num1 + vectorF2D2 * num2; numArray[index] = pointF2D2.ToArray(); } return(numArray); }
public RectangleF2D(PointF2D bottomLeft, double width, double height, VectorF2D directionY) { this._bottomLeft = bottomLeft; VectorF2D vectorF2D = directionY.Normalize(); this._vectorY = vectorF2D * height; this._vectorX = vectorF2D.Rotate90(true) * width; }
public RectangleF2D(double x, double y, double width, double height, Degree angleY) { this._bottomLeft = new PointF2D(x, y); VectorF2D vectorF2D = VectorF2D.FromAngleY(angleY); this._vectorY = vectorF2D * height; this._vectorX = vectorF2D.Rotate90(true) * width; }
/// <summary> /// Rotates this rectangle around the given center point with a given angle in clockwise direction. /// </summary> /// <returns>The around.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> public RectangleF2D RotateAround(Degree angle, PointF2D center) { PointF2D[] corners = new PointF2D[] { this.TopLeft, this.TopRight, this.BottomLeft, this.BottomRight }; PointF2D[] cornersRotated = Rotation.RotateAroundPoint(angle, center, corners); return(new RectangleF2D(cornersRotated [2], this.Width, this.Height, cornersRotated [0] - cornersRotated [2])); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="bottomLeft">Bottom left.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">Direction y.</param> public RectangleF2D(PointF2D bottomLeft, double width, double height, VectorF2D directionY) { _bottomLeft = bottomLeft; VectorF2D directionYNormal = directionY.Normalize(); _vectorY = directionYNormal * height; _vectorX = directionYNormal.Rotate90(true) * width; }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="x">The x coordinate of the bottom-left corner.</param> /// <param name="y">The y coordinate of the bottom-left corner.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="angleY">The angle relative to the y-axis.</param> public RectangleF2D(double x, double y, double width, double height, Degree angleY) { _bottomLeft = new PointF2D(x, y); VectorF2D directionY = VectorF2D.FromAngleY(angleY); _vectorY = directionY * height; _vectorX = directionY.Rotate90(true) * width; }
public LineF2D(PointF2D a, PointF2D b, bool is_segment1, bool is_segment2) { this._a = a; this._b = b; this._dir = this._b - this._a; this._is_segment1 = is_segment1; this._is_segment2 = is_segment2; }
/// <summary> /// Fits this rectangle to the given points. /// </summary> /// <param name="points">The points to wrap the rectangle around.</param> /// <param name="percentage">The margin in percentage.</param> /// <returns></returns> public RectangleF2D Fit(PointF2D[] points, double percentage) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); } // calculate the center. double[] center = new double[] { points[0][0], points[0][1] }; for (int idx = 1; idx < points.Length; idx++) { center[0] = center[0] + points[idx][0]; center[1] = center[1] + points[idx][1]; } center[0] = center[0] / points.Length; center[1] = center[1] / points.Length; PointF2D centerPoint = new PointF2D(center); LineF2D line = null; // calculate the width. double width = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorY); double distance = line.Distance(centerPoint); if (distance > width) { // the distance is larger. width = distance; } } width = width * 2; // calculate the height. double height = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorX); double distance = line.Distance(centerPoint); if (distance > height) { // this distance is larger. height = distance; } } height = height * 2; // expand with the given percentage. width = width + (width / 100.0 * percentage); height = height + (height / 100.0 * percentage); return(RectangleF2D.FromBoundsAndCenter(width, height, centerPoint[0], centerPoint[1], this.DirectionY)); }
/// <summary> /// Creates a new RectangleF2D from given bounds, center and direction. /// </summary> /// <param name="centerX"></param> /// <param name="centerY"></param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">The direction of the y-axis.</param> /// <returns></returns> public static RectangleF2D FromBoundsAndCenter(double width, double height, double centerX, double centerY, VectorF2D directionY) { VectorF2D directionYNormal = directionY.Normalize(); VectorF2D directionXNormal = directionYNormal.Rotate90(true); PointF2D center = new PointF2D(centerX, centerY); PointF2D bottomLeft = center - (directionYNormal * (height / 2)) - (directionXNormal * (width / 2)); return(new RectangleF2D(bottomLeft, width, height, directionY)); }
/// <summary> /// Creates a new polygon. /// </summary> /// <param name="points"></param> public PolygonF2D(PointF2D[] points) { // make a copy. _points = new List<PointF2D>(points).ToArray(); if (_points.Length <= 2) { throw new ArgumentOutOfRangeException("Minimum three points make a polygon!"); } }
/// <summary> /// Creates a new line. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="is_segment1"></param> /// <param name="is_segment2"></param> public LineF2D(PointF2D a, PointF2D b, bool is_segment1, bool is_segment2) { _a = a; _b = b; _dir = _b - _a; _is_segment1 = is_segment1; _is_segment2 = is_segment2; }
public bool Contains(PointF2D point) { double[] numArray = this.TransformTo(100.0, 100.0, false, false, point); if (numArray[0] >= 0.0 && numArray[0] <= 100.0 && numArray[1] >= 0.0) { return(numArray[1] <= 100.0); } return(false); }
/// <summary> /// Transforms the given the coordinates to a coordinate system defined inside this rectangle. /// </summary> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="reverseX">If set to <c>true</c> reverse x.</param> /// <param name="reverseY">If set to <c>true</c> reverse y.</param> /// <param name="point">Point.</param> /// <param name="transformed">Transformed.</param> public void TransformTo(double width, double height, bool reverseX, bool reverseY, PointF2D point, double[] transformed) { if (transformed == null) { throw new ArgumentNullException(); } if (transformed.Length != 2) { throw new ArgumentException("Tranformed array needs to be of length 2."); } PointF2D reference = _bottomLeft; VectorF2D vectorX = _vectorX; VectorF2D vectorY = _vectorY; if (reverseX && !reverseY) { reference = this.BottomRight; vectorX = _vectorX * -1; } else if (!reverseX && reverseY) { reference = this.TopLeft; vectorY = _vectorY * -1; } else if (reverseX && reverseY) { reference = this.TopRight; vectorX = _vectorX * -1; vectorY = _vectorY * -1; } LineF2D xLine = new LineF2D(point, point + vectorX, false); PointF2D yIntersection = xLine.Intersection(new LineF2D(reference, reference + vectorY)) as PointF2D; VectorF2D yIntersectionVector = (yIntersection - reference); double yFactor = yIntersectionVector.Size / vectorY.Size; if (!yIntersectionVector.CompareNormalized(vectorY, 0.0001)) { yFactor = -yFactor; } LineF2D yLine = new LineF2D(point, point + vectorY); PointF2D xIntersection = yLine.Intersection(new LineF2D(reference, reference + vectorX)) as PointF2D; VectorF2D xIntersectionVector = (xIntersection - reference); double xFactor = xIntersectionVector.Size / vectorX.Size; if (!xIntersectionVector.CompareNormalized(vectorX, 0.0001)) { xFactor = -xFactor; } transformed [0] = xFactor * width; transformed [1] = yFactor * height; }
public override bool Equals(object obj) { PointF2D pointF2D = obj as PointF2D; if (obj != null && this._values[0] == pointF2D[0]) { return(this._values[1] == pointF2D[1]); } return(false); }
/// <summary> /// Rotates a point around another around point with a given angle clockwise. /// </summary> /// <returns>The around point.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> /// <param name="point">Point.</param> public static PointF2D RotateAroundPoint(Radian angle, PointF2D center, PointF2D point) { double sin = System.Math.Sin (angle.Value); double cos = System.Math.Cos (angle.Value); double newX = center [0] + (cos * (point [0] - center[0]) + sin * (point [1] - center [1])); double newY = center [1] + (-sin * (point [0] - center[0]) + cos * (point [1] - center [1])); return new PointF2D (newX, newY); }
public LinePointPosition PositionOfPoint(PointF2D point) { double num = VectorF2D.Cross(this.Direction, point - this._a); if (num > 0.0) { return(LinePointPosition.Left); } return(num < 0.0 ? LinePointPosition.Right : LinePointPosition.On); }
public double[][] TransformTo(double width, double height, bool reverseX, bool reverseY, double[] x, double[] y) { PointF2D a1 = this._bottomLeft; VectorF2D vectorF2D1 = this._vectorX; VectorF2D vectorF2D2 = this._vectorY; if (reverseX && !reverseY) { a1 = this.BottomRight; vectorF2D1 = this._vectorX * -1.0; } else if (!reverseX & reverseY) { a1 = this.TopLeft; vectorF2D2 = this._vectorY * -1.0; } else if (reverseX & reverseY) { a1 = this.TopRight; vectorF2D1 = this._vectorX * -1.0; vectorF2D2 = this._vectorY * -1.0; } double[][] numArray = new double[x.Length][]; for (int index = 0; index < x.Length; ++index) { PointF2D a2 = new PointF2D(x[index], y[index]); VectorF2D vectorF2D3 = vectorF2D1; PointF2D b1 = a2 + vectorF2D3; int num1 = 0; VectorF2D vectorF2D4 = (new LineF2D(a2, b1, num1 != 0).Intersection(new LineF2D(a1, a1 + vectorF2D2)) as PointF2D) - a1; double num2 = vectorF2D4.Size / vectorF2D2.Size; VectorF2D other1 = vectorF2D2; double epsilon1 = 0.0001; if (!vectorF2D4.CompareNormalized(other1, epsilon1)) { num2 = -num2; } VectorF2D vectorF2D5 = vectorF2D2; PointF2D b2 = a2 + vectorF2D5; VectorF2D vectorF2D6 = (new LineF2D(a2, b2).Intersection(new LineF2D(a1, a1 + vectorF2D1)) as PointF2D) - a1; double num3 = vectorF2D6.Size / vectorF2D1.Size; VectorF2D other2 = vectorF2D1; double epsilon2 = 0.0001; if (!vectorF2D6.CompareNormalized(other2, epsilon2)) { num3 = -num3; } numArray[index] = new double[2] { num3 *width, num2 *height }; } return(numArray); }
/// <summary> /// Calculates the distance between two points. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> protected static double Distance(PointF2D a, PointF2D b) { double distance = 0.0f; for (int idx = 0; idx < 2; idx++) { double idx_diff = a[idx] - b[idx]; distance = distance + (idx_diff * idx_diff); } return((double)System.Math.Sqrt(distance)); }
public override double Distance(PointF2D p) { double num1 = double.MaxValue; foreach (PrimitiveF2D primitiveF2D in this.LineEnumerator) { double num2 = primitiveF2D.Distance(p); if (num2 < num1) num1 = num2; } return num1; }
protected static double Distance(PointF2D a, PointF2D b) { double d = 0.0; for (int index = 0; index < 2; ++index) { double num = a[index] - b[index]; d += num * num; } return(System.Math.Sqrt(d)); }
/// <summary> /// Returns true if the point is inside of the polygon. /// </summary> /// <param name="point"></param> /// <returns></returns> public bool IsInside(PointF2D point) { // http://en.wikipedia.org/wiki/Even-odd_rule // create a line parallel to the x-axis. // PointF2D second_point = new PointF2D( // new double[]{point[0] + 10,point[1]}); // intersect line with polygon. return(false); }
public RectangleF2D RotateAround(Degree angle, PointF2D center) { PointF2D[] points = new PointF2D[4] { this.TopLeft, this.TopRight, this.BottomLeft, this.BottomRight }; PointF2D[] pointF2DArray = Rotation.RotateAroundPoint((Radian)angle, center, points); return(new RectangleF2D(pointF2DArray[2], this.Width, this.Height, pointF2DArray[0] - pointF2DArray[2])); }
public void TransformTo(double width, double height, bool reverseX, bool reverseY, PointF2D point, double[] transformed) { if (transformed == null) { throw new ArgumentNullException(); } if (transformed.Length != 2) { throw new ArgumentException("Tranformed array needs to be of length 2."); } PointF2D a = this._bottomLeft; VectorF2D vectorF2D1 = this._vectorX; VectorF2D vectorF2D2 = this._vectorY; if (reverseX && !reverseY) { a = this.BottomRight; vectorF2D1 = this._vectorX * -1.0; } else if (!reverseX & reverseY) { a = this.TopLeft; vectorF2D2 = this._vectorY * -1.0; } else if (reverseX & reverseY) { a = this.TopRight; vectorF2D1 = this._vectorX * -1.0; vectorF2D2 = this._vectorY * -1.0; } VectorF2D vectorF2D3 = (new LineF2D(point, point + vectorF2D1, false).Intersection(new LineF2D(a, a + vectorF2D2)) as PointF2D) - a; double num1 = vectorF2D3.Size / vectorF2D2.Size; VectorF2D other1 = vectorF2D2; double epsilon1 = 0.0001; if (!vectorF2D3.CompareNormalized(other1, epsilon1)) { num1 = -num1; } VectorF2D vectorF2D4 = (new LineF2D(point, point + vectorF2D2).Intersection(new LineF2D(a, a + vectorF2D1)) as PointF2D) - a; double num2 = vectorF2D4.Size / vectorF2D1.Size; VectorF2D other2 = vectorF2D1; double epsilon2 = 0.0001; if (!vectorF2D4.CompareNormalized(other2, epsilon2)) { num2 = -num2; } transformed[0] = num2 * width; transformed[1] = num1 * height; }
/// <summary> /// Rotates a set of points around another around point with a given angle clockwise. /// </summary> /// <returns>The around point.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> /// <param name="points">Points.</param> public static PointF2D[] RotateAroundPoint(Radian angle, PointF2D center, PointF2D[] points) { double sin = System.Math.Sin (angle.Value); double cos = System.Math.Cos (angle.Value); PointF2D[] rotated = new PointF2D[points.Length]; for (int idx = 0; idx < points.Length; idx++) { double newX = center [0] + (cos * (points[idx] [0] - center[0]) + sin * (points[idx] [1] - center [1])); double newY = center [1] + (-sin * (points[idx] [0] - center[0]) + cos * (points[idx] [1] - center [1])); rotated[idx] = new PointF2D (newX, newY); } return rotated; }
/// <summary> /// Transforms the given the coordinates to a coordinate system defined inside this rectangle. /// </summary> /// <param name="width">The width of the rectangle in the coordinate system of the given coordinates.</param> /// <param name="height">The height of the rectangle in the coordinate system of the given coordinates.</param> /// <param name="reverseX">Assumes that the origin of the x-axis is on the top of this rectangle if false.</param> /// <param name="reverseY">Assumes that the origin of the y-axis is on the right of this rectangle if false.</param> /// <param name="x">The x-coordinate to transform.</param> /// <param name="y">The y-coordinate to transform.</param> public double[][] TransformTo(double width, double height, bool reverseX, bool reverseY, double[] x, double[] y) { PointF2D reference = _bottomLeft; VectorF2D vectorX = _vectorX; VectorF2D vectorY = _vectorY; if (reverseX && !reverseY) { reference = this.BottomRight; vectorX = _vectorX * -1; } else if (!reverseX && reverseY) { reference = this.TopLeft; vectorY = _vectorY * -1; } else if (reverseX && reverseY) { reference = this.TopRight; vectorX = _vectorX * -1; vectorY = _vectorY * -1; } double[][] transformed = new double[x.Length][]; for (int idx = 0; idx < x.Length; idx++) { PointF2D point = new PointF2D(x [idx], y [idx]); LineF2D xLine = new LineF2D(point, point + vectorX, false); PointF2D yIntersection = xLine.Intersection(new LineF2D(reference, reference + vectorY)) as PointF2D; VectorF2D yIntersectionVector = (yIntersection - reference); double yFactor = yIntersectionVector.Size / vectorY.Size; if (!yIntersectionVector.CompareNormalized(vectorY, 0.0001)) { yFactor = -yFactor; } LineF2D yLine = new LineF2D(point, point + vectorY); PointF2D xIntersection = yLine.Intersection(new LineF2D(reference, reference + vectorX)) as PointF2D; VectorF2D xIntersectionVector = (xIntersection - reference); double xFactor = xIntersectionVector.Size / vectorX.Size; if (!xIntersectionVector.CompareNormalized(vectorX, 0.0001)) { xFactor = -xFactor; } transformed[idx] = new double[] { xFactor *width, yFactor *height }; } return(transformed); }
public RectangleF2D Fit(PointF2D[] points, double percentage) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); } double[] values = new double[2] { points[0][0], points[0][1] }; for (int index = 1; index < points.Length; ++index) { values[0] = values[0] + points[index][0]; values[1] = values[1] + points[index][1]; } values[0] = values[0] / (double)points.Length; values[1] = values[1] / (double)points.Length; PointF2D p = new PointF2D(values); double num1 = 0.0; for (int index = 0; index < points.Length; ++index) { double num2 = new LineF2D(points[index], points[index] + this._vectorY).Distance(p); if (num2 > num1) { num1 = num2; } } double num3 = num1 * 2.0; double num4 = 0.0; for (int index = 0; index < points.Length; ++index) { double num2 = new LineF2D(points[index], points[index] + this._vectorX).Distance(p); if (num2 > num4) { num4 = num2; } } double num5 = num4 * 2.0; return(RectangleF2D.FromBoundsAndCenter(num3 + num3 / 100.0 * percentage, num5 + num5 / 100.0 * percentage, p[0], p[1], this.DirectionY)); }
/// <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); }
public void RotationSimpleTest() { double delta = 0.00001; PointF2D center = new PointF2D (1, 1); PointF2D point = new PointF2D (1, 2); PointF2D rotated = Rotation.RotateAroundPoint ((Degree)90, center, point); Assert.AreEqual (2, rotated [0], delta); Assert.AreEqual (1, rotated [1], delta); rotated = Rotation.RotateAroundPoint ((Degree)180, center, point); Assert.AreEqual (1, rotated [0], delta); Assert.AreEqual (0, rotated [1], delta); }
/// <summary> /// Simplify the specified points using epsilon. /// </summary> /// <param name="points">Points.</param> /// <param name="epsilon">Epsilon.</param> /// <param name="first">First.</param> /// <param name="last">Last.</param> public static PointF2D[] SimplifyBetween(PointF2D[] points, double epsilon, int first, int last) { if (points == null) throw new ArgumentNullException ("points"); if (epsilon <= 0) throw new ArgumentOutOfRangeException("epsilon"); if (first > last) throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!", first, last)); if (first + 1 != last) { // find point with the maximum distance. double maxDistance = 0; int foundIndex = -1; // create the line between first-last. LineF2D line = new LineF2D (points[first], points [last]); for (int idx = first + 1; idx < last; idx++) { double distance = line.Distance (points[idx]); if (distance > maxDistance) { // larger distance found. maxDistance = distance; foundIndex = idx; } } if (foundIndex > 0 && maxDistance > epsilon) { // a point was found and it is far enough. PointF2D[] before = SimplifyCurve.SimplifyBetween (points, epsilon, first, foundIndex); PointF2D[] after = SimplifyCurve.SimplifyBetween (points, epsilon, foundIndex, last); // build result. PointF2D[] result = new PointF2D[before.Length + after.Length - 1]; for (int idx = 0; idx < before.Length - 1; idx++) { result [idx] = before [idx]; } for (int idx = 0; idx < after.Length; idx++) { result [idx + before.Length - 1] = after [idx]; } return result; } } return new PointF2D[] { points[first], points[last] }; }
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> /// Expands this geo coordinate box with the given coordinate. /// </summary> /// <param name="coordinate"></param> public void ExpandWith(GeoCoordinate coordinate) { if (!this.Contains(coordinate)) { PointF2D[] newCorners = new PointF2D[3]; newCorners[0] = this.TopLeft; newCorners[1] = this.BottomRight; newCorners[2] = coordinate; this.Mutate(newCorners); } }
/// <summary> /// Simplify the specified points using epsilon. /// </summary> /// <param name="points">Points.</param> /// <param name="epsilon">Epsilon.</param> public static PointF2D[] Simplify(PointF2D[] points, double epsilon) { return SimplifyCurve.SimplifyBetween (points, epsilon, 0, points.Length - 1); }
/// <summary> /// Serializes the given scene. /// </summary> /// <param name="stream"></param> /// <param name="scene"></param> /// <param name="compress"></param> public static void Serialize(Stream stream, TagsCollectionBase metaTags, Scene2D scene, bool compress) { RuntimeTypeModel typeModel = SceneSerializer.BuildRuntimeTypeModel(); // [MetaIndexLenght:4][Metadata][SeneIndexLength:4][SceneIndex][SceneLengths:4*zoomFactors.length][Scenes] // MetaIndexLenght: int The lenght of the meta index. // Metadata: a number of serialized tags. // SceneIndexLength: int The length of the sceneindex in bytes. // SceneIndex: the serialized scene index. // SceneLengths: int[] The lengths of the scenes per zoom level as in the zoomfactors array. // Scenes: The serialized scenes themselves. // serialize meta tags. (new TagsCollectionSerializer()).SerializeWithSize(metaTags, stream); // index index. SceneIndex sceneIndex = new SceneIndex(); sceneIndex.LineStyles = scene.GetStyleLines(); sceneIndex.PointStyles = scene.GetStylePoints(); sceneIndex.PolygonStyles = scene.GetStylePolygons(); sceneIndex.TextStyles = scene.GetStyleTexts(); sceneIndex.ZoomRanges = scene.GetZoomRanges(); sceneIndex.ZoomFactors = scene.GetZoomFactors(); sceneIndex.IconImage = scene.GetImages(); // write SceneIndex long positionAfterMeta = stream.Position; stream.Seek(positionAfterMeta + 4, SeekOrigin.Begin); long indexStart = stream.Position; typeModel.Serialize(stream, sceneIndex); // write SeneIndexLength int indexSize = (int)(stream.Position - indexStart); stream.Seek(positionAfterMeta + 0, SeekOrigin.Begin); stream.Write(BitConverter.GetBytes(indexSize), 0, 4); // write Scenes. stream.Seek(positionAfterMeta + 4 + indexSize + 4 * sceneIndex.ZoomFactors.Length, SeekOrigin.Begin); // index into r-trees and serialize. int[] lengths = new int[sceneIndex.ZoomFactors.Length]; for (int idx = 0; idx < lengths.Length; idx++) { long position = stream.Position; Dictionary<uint, SceneObject> sceneAtZoom = scene.GetObjectsAt(idx); RTreeMemoryIndex<SceneObject> memoryIndex = new RTreeMemoryIndex<SceneObject>(50, 100); float latestProgress = 0; int sceneObjectIdx = 0; foreach (KeyValuePair<uint, SceneObject> sceneObjectPair in sceneAtZoom) { // loop over all primitives in order. SceneObject sceneObject = sceneObjectPair.Value; uint id = sceneObjectPair.Key; switch (sceneObject.Enum) { case SceneObjectType.IconObject: case SceneObjectType.PointObject: case SceneObjectType.TextObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoint geo = scene.GetPoint(sceneObject.GeoId); PointF2D point = new PointF2D(geo.X, geo.Y); memoryIndex.Add(new BoxF2D(point), sceneObject); break; case SceneObjectType.LineObject: case SceneObjectType.LineTextObject: case SceneObjectType.PolygonObject: OsmSharp.UI.Renderer.Scene.Scene2D.ScenePoints geos = scene.GetPoints(sceneObject.GeoId); memoryIndex.Add(new BoxF2D(geos.X, geos.Y), sceneObject); break; } float progress = (float)System.Math.Round((((double)sceneObjectIdx / (double)sceneAtZoom.Count) * 100)); if (progress != latestProgress) { OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Indexing scene objects at zoom {1} ({2}/{3})... {0}%", progress, sceneIndex.ZoomFactors[idx], sceneObjectIdx, sceneAtZoom.Count); latestProgress = progress; } sceneObjectIdx++; } // serialize the r-tree. OsmSharp.Logging.Log.TraceEvent("SceneSerializer", OsmSharp.Logging.TraceEventType.Information, "Serializing RTRee..."); SceneObjectRTreeSerializer memoryIndexSerializer = new SceneObjectRTreeSerializer( scene, compress, idx, SceneSerializer.CalculateScaleFactor(sceneIndex.ZoomFactors[idx])); memoryIndexSerializer.Serialize(new LimitedStream(stream), memoryIndex); lengths[idx] = (int)(stream.Position - position); } // write SceneLengths long end = stream.Position; stream.Seek(positionAfterMeta + 4 + indexSize, SeekOrigin.Begin); for (int idx = 0; idx < lengths.Length; idx++) { stream.Write(BitConverter.GetBytes(lengths[idx]), 0, 4); } stream.Seek(end, SeekOrigin.Begin); }
/// <summary> /// Zooms to the given list of markers. /// </summary> /// <param name="markers"></param> public void ZoomToMarkers(List<MapMarker> markers, double percentage, bool notifyChange) { float height = this.Height; float width = this.Width; if (width > 0) { PointF2D[] points = new PointF2D[markers.Count]; for (int idx = 0; idx < markers.Count; idx++) { points [idx] = new PointF2D (this.Map.Projection.ToPixel (markers [idx].Location)); } View2D view = this.CreateView (); View2D fittedView = view.Fit (points, percentage); float zoom = (float)this.Map.Projection.ToZoomLevel (fittedView.CalculateZoom ( width, height)); GeoCoordinate center = this.Map.Projection.ToGeoCoordinates ( fittedView.Center [0], fittedView.Center [1]); if (notifyChange) { this.SetMapView (center, this.MapTilt, zoom, true); this.NotifyMovement (); this.Change (); } else { this.SetMapView (center, this.MapTilt, zoom, false); } } else { _latestZoomCall = new MapViewMarkerZoomEvent() { Markers = markers, Percentage = percentage }; } }
/// <summary> /// Creates a geo coordinate. /// </summary> public GeoCoordinate(PointF2D point) : this(point[1], point[0]) { }
/// <summary> /// Transforms the given the coordinates to a coordinate system defined inside this rectangle. /// </summary> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="reverseX">If set to <c>true</c> reverse x.</param> /// <param name="reverseY">If set to <c>true</c> reverse y.</param> /// <param name="point">Point.</param> /// <param name="transformed">Transformed.</param> public void TransformTo(double width, double height, bool reverseX, bool reverseY, PointF2D point, double[] transformed) { if (transformed == null) { throw new ArgumentNullException (); } if (transformed.Length != 2) { throw new ArgumentException ("Tranformed array needs to be of length 2."); } PointF2D reference = _bottomLeft; VectorF2D vectorX = _vectorX; VectorF2D vectorY = _vectorY; if (reverseX && !reverseY) { reference = this.BottomRight; vectorX = _vectorX * -1; } else if (!reverseX && reverseY) { reference = this.TopLeft; vectorY = _vectorY * -1; } else if (reverseX && reverseY) { reference = this.TopRight; vectorX = _vectorX * -1; vectorY = _vectorY * -1; } LineF2D xLine = new LineF2D (point, point + vectorX, false); PointF2D yIntersection = xLine.Intersection (new LineF2D (reference, reference + vectorY)) as PointF2D; VectorF2D yIntersectionVector = (yIntersection - reference); double yFactor = yIntersectionVector.Size / vectorY.Size; if (!yIntersectionVector.CompareNormalized (vectorY, 0.0001)) { yFactor = -yFactor; } LineF2D yLine = new LineF2D (point, point + vectorY); PointF2D xIntersection = yLine.Intersection (new LineF2D (reference, reference + vectorX)) as PointF2D; VectorF2D xIntersectionVector = (xIntersection - reference); double xFactor = xIntersectionVector.Size / vectorX.Size; if (!xIntersectionVector.CompareNormalized (vectorX, 0.0001)) { xFactor = -xFactor; } transformed [0] = xFactor * width; transformed [1] = yFactor * height; }
/// <summary> /// Calculates the distance of this primitive to the given point. /// </summary> /// <param name="p"></param> /// <returns></returns> public override double Distance(PointF2D p) { double distance = (new LineF2D (this.BottomLeft, this.BottomRight, true)).Distance (p); double newDistance = (new LineF2D (this.BottomRight, this.TopRight, true)).Distance (p); if (newDistance < distance) { distance = newDistance; } newDistance = (new LineF2D (this.TopRight, this.TopLeft, true)).Distance (p); if (newDistance < distance) { distance = newDistance; } newDistance = (new LineF2D (this.TopLeft, this.BottomLeft, true)).Distance (p); if (newDistance < distance) { distance = newDistance; } return distance; }
/// <summary> /// Fites this view around the given points but keeps aspect ratio and /// </summary> /// <param name="points"></param> /// <returns></returns> public View2D Fit(PointF2D[] points, double percentage) { RectangleF2D rotated = this.Rectangle.FitAndKeepAspectRatio(points, percentage); return new View2D(rotated, _invertX, _invertY); }
/// <summary> /// Fits this rectangle to this given points and keeps aspect ratio. /// </summary> /// <param name="points"></param> /// <param name="percentage"></param> /// <returns></returns> public RectangleF2D FitAndKeepAspectRatio(PointF2D[] points, double percentage) { RectangleF2D fitted = this.Fit(points, percentage); // although this may seem a strange approach, think about // numerical stability before change this! double width = fitted.Width; double height = fitted.Height; double targetRatio = this.Width / this.Height; // this is the target ratio. if (fitted.Height > fitted.Width) { // the height is bigger. double targetWidth = fitted.Height * targetRatio; if (targetWidth < fitted.Width) { // increase height instead. height = fitted.Width / targetRatio; } else { // ok, the width is increased and ratio's match now. width = targetWidth; } } else { // the width is bigger. double targetHeight = fitted.Width / targetRatio; if (targetHeight < fitted.Height) { // increase width instead. width = fitted.Height * targetRatio; } else { // ok, the height is increase and ratio's match now. height = targetHeight; } } return RectangleF2D.FromBoundsAndCenter(width, height, fitted.Center[0], fitted.Center[1], fitted.DirectionY); }
/// <summary> /// Fits this rectangle to the given points. /// </summary> /// <param name="points">The points to wrap the rectangle around.</param> /// <param name="percentage">The margin in percentage.</param> /// <returns></returns> public RectangleF2D Fit(PointF2D[] points, double percentage) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); } // calculate the center. double[] center = new double[] { points[0][0], points[0][1] }; for (int idx = 1; idx < points.Length; idx++) { center[0] = center[0] + points[idx][0]; center[1] = center[1] + points[idx][1]; } center[0] = center[0] / points.Length; center[1] = center[1] / points.Length; PointF2D centerPoint = new PointF2D(center); LineF2D line = null; // calculate the width. double width = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorY); double distance = line.Distance(centerPoint); if (distance > width) { // the distance is larger. width = distance; } } width = width * 2; // calculate the height. double height = 0; for (int idx = 0; idx < points.Length; idx++) { line = new LineF2D(points[idx], points[idx] + this._vectorX); double distance = line.Distance(centerPoint); if (distance > height) { // this distance is larger. height = distance; } } height = height * 2; // expand with the given percentage. width = width + (width / 100.0 * percentage); height = height + (height / 100.0 * percentage); return RectangleF2D.FromBoundsAndCenter(width, height, centerPoint[0], centerPoint[1], this.DirectionY); }
/// <summary> /// Rotates this rectangle around the given center point with a given angle in clockwise direction. /// </summary> /// <returns>The around.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> public RectangleF2D RotateAround(Degree angle, PointF2D center) { PointF2D[] corners = new PointF2D[] { this.TopLeft, this.TopRight, this.BottomLeft, this.BottomRight }; PointF2D[] cornersRotated = Rotation.RotateAroundPoint (angle, center, corners); return new RectangleF2D (cornersRotated [2], this.Width, this.Height, cornersRotated [0] - cornersRotated [2]); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="x">The x coordinate of the bottom-left corner.</param> /// <param name="y">The y coordinate of the bottom-left corner.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <remarks>This creates a rectangle in the direction of the x- and y-axis, performance is almost always better when using <see cref="OsmSharp.Math.Primitives.BoxF2D"/> in this case.</remarks> public RectangleF2D(double x, double y, double width, double height) { _bottomLeft = new PointF2D (x, y); _vectorX = new VectorF2D (width, 0); _vectorY = new VectorF2D (0, height); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">Direction y.</param> public RectangleF2D(double x, double y, double width, double height, VectorF2D directionY) { _bottomLeft = new PointF2D (x, y); directionY = directionY.Normalize (); _vectorY = directionY * height; _vectorX = directionY.Rotate90 (true) * width; }
/// <summary> /// Returns true if the point is inside of the polygon. /// </summary> /// <param name="point"></param> /// <returns></returns> public bool IsInside(PointF2D point) { // http://en.wikipedia.org/wiki/Even-odd_rule // create a line parallel to the x-axis. // PointF2D second_point = new PointF2D( // new double[]{point[0] + 10,point[1]}); // intersect line with polygon. return false; }
/// <summary> /// Zoom to the given makers list. /// </summary> /// <param name="marker"></param> public void ZoomToMarkers(List<MapMarker> markers, double percentage) { float width = (float)this.Frame.Width; float height = (float)this.Frame.Height; CGRect rect = this.Frame; if (width > 0) { PointF2D[] points = new PointF2D[markers.Count]; for (int idx = 0; idx < markers.Count; idx++) { points[idx] = new PointF2D(this.Map.Projection.ToPixel(markers[idx].Location)); } View2D view = this.CreateView(rect); View2D fittedView = view.Fit(points, percentage); float zoom = (float)this.Map.Projection.ToZoomLevel(fittedView.CalculateZoom( width, height)); GeoCoordinate center = this.Map.Projection.ToGeoCoordinates( fittedView.Center[0], fittedView.Center[1]); this.MapCenter = center; this.MapZoom = zoom; this.NotifyMovementByInvoke(); } }
/// <summary> /// Fites this view around the given points but keeps aspect ratio and /// </summary> /// <param name="points"></param> /// <returns></returns> public View2D Fit(PointF2D[] points) { return this.Fit(points, 0); }
/// <summary> /// Initializes a new instance of the <see cref="OsmSharp.Math.Primitives.RectangleF2D"/> class. /// </summary> /// <param name="bottomLeft">Bottom left.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">Direction y.</param> public RectangleF2D(PointF2D bottomLeft, double width, double height, VectorF2D directionY) { _bottomLeft = bottomLeft; VectorF2D directionYNormal = directionY.Normalize (); _vectorY = directionYNormal * height; _vectorX = directionYNormal.Rotate90 (true) * width; }
/// <summary> /// Zooms to the given list of markers. /// </summary> /// <param name="controls"></param> /// <param name="percentage"></param> public void ZoomToControls(List<MapControl> controls, double percentage) { try { if (this.SurfaceWidth > 0 && _bufferFactor > 0) { float height = this.SurfaceHeight / _bufferFactor; float width = this.SurfaceWidth / _bufferFactor; var points = new PointF2D[controls.Count]; for (int idx = 0; idx < controls.Count; idx++) { points[idx] = new PointF2D(this.Map.Projection.ToPixel(controls[idx].Location)); } var view = this.CreateView(); var fittedView = view.Fit(points, percentage); var zoom = (float)this.Map.Projection.ToZoomLevel(fittedView.CalculateZoom( width, height)); var center = this.Map.Projection.ToGeoCoordinates( fittedView.Center[0], fittedView.Center[1]); this.SetMapView(center, this.MapTilt, zoom); } else { _latestZoomCall = new MapViewControlZoomEvent() { Controls = controls, Percentage = percentage }; } } catch (Exception ex) { OsmSharp.Logging.Log.TraceEvent("MapViewSurface.ZoomToMarkers", TraceEventType.Critical, string.Format("An unhandled exception occured:{0}", ex.ToString())); } }
/// <summary> /// Starts tracking at a given location. /// </summary> /// <param name="location"></param> public void Track(GeoCoordinate location) { if (_lastTouch.HasValue) { // is tracking disabled now? TimeSpan timeFromLastTouch = new TimeSpan (DateTime.Now.Ticks - _lastTouch.Value); if (timeFromLastTouch.TotalSeconds >= this.RestartAfterTouch.Value) { // ok, the animator has waited long enough. _lastTouch = null; } else { // ok, the animator still has to wait for user-input. return; } } // check if the minimum gap between tracking events is respected. long now = DateTime.Now.Ticks; if (_lastTrack.HasValue) { if (_minimumTrackGap > now - _lastTrack.Value) { return; // too fast! } } _lastTrack = now; // animate the next step(s). TimeSpan lastTrackInterval = new TimeSpan(0, 0, 0, 0, 750); long ticks = DateTime.Now.Ticks; if (_lastTicks.HasValue) { // update the last track interval. lastTrackInterval = TimeSpan.FromTicks(ticks - _lastTicks.Value); } _lastTicks = ticks; OsmSharp.Logging.Log.TraceEvent("", System.Diagnostics.TraceEventType.Information, "Interval: {0}ms", lastTrackInterval.TotalMilliseconds); // give location to the route tracker. _routeTracker.Track(location); // calculate all map view parameters (zoom, location, tilt) to display the route/direction correctly. float zoom = this.DefaultZoom; GeoCoordinate center = _routeTracker.PositionRoute; double nextDistance = 20; Degree tilt = _mapView.MapTilt; GeoCoordinate next = _routeTracker.PositionIn(nextDistance); if (next != null) { IProjection projection = _mapView.Map.Projection; VectorF2D direction = new PointF2D(projection.ToPixel(next)) - new PointF2D(projection.ToPixel(center)); tilt = direction.Angle(new VectorF2D(0, -1)); } // animate to the given parameter (zoom, location, tilt). _animator.Stop(); _animator.Start(center, zoom, tilt, lastTrackInterval.Subtract(new TimeSpan(0, 0, 0, 0, 150))); }
/// <summary> /// Creates a new RectangleF2D from given bounds, center and direction. /// </summary> /// <param name="centerX"></param> /// <param name="centerY"></param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="directionY">The direction of the y-axis.</param> /// <returns></returns> public static RectangleF2D FromBoundsAndCenter(double width, double height, double centerX, double centerY, VectorF2D directionY) { VectorF2D directionYNormal = directionY.Normalize(); VectorF2D directionXNormal = directionYNormal.Rotate90(true); PointF2D center = new PointF2D(centerX, centerY); PointF2D bottomLeft = center - (directionYNormal * (height / 2)) - (directionXNormal * (width / 2)); return new RectangleF2D(bottomLeft, width, height, directionY); }
/// <summary> /// Transforms the given the coordinates to a coordinate system defined inside this rectangle. /// </summary> public double[] TransformTo(double width, double height, bool reverseX, bool reverseY, PointF2D point) { PointF2D reference = _bottomLeft; VectorF2D vectorX = _vectorX; VectorF2D vectorY = _vectorY; if (reverseX && !reverseY) { reference = this.BottomRight; vectorX = _vectorX * -1; } else if (!reverseX && reverseY) { reference = this.TopLeft; vectorY = _vectorY * -1; } else if (reverseX && reverseY) { reference = this.TopRight; vectorX = _vectorX * -1; vectorY = _vectorY * -1; } LineF2D xLine = new LineF2D (point, point + vectorX, false); PointF2D yIntersection = xLine.Intersection (new LineF2D (reference, reference + vectorY)) as PointF2D; VectorF2D yIntersectionVector = (yIntersection - reference); double yFactor = yIntersectionVector.Size / vectorY.Size; if (!yIntersectionVector.CompareNormalized (vectorY, 0.0001)) { yFactor = -yFactor; } LineF2D yLine = new LineF2D (point, point + vectorY); PointF2D xIntersection = yLine.Intersection (new LineF2D (reference, reference + vectorX)) as PointF2D; VectorF2D xIntersectionVector = (xIntersection - reference); double xFactor = xIntersectionVector.Size / vectorX.Size; if (!xIntersectionVector.CompareNormalized (vectorX, 0.0001)) { xFactor = -xFactor; } return new double[] { xFactor * width, yFactor * height }; }
/// <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> /// Returns true if this box contains the specified x, y. /// </summary> /// <param name="point">The point.</param> public bool Contains(PointF2D point) { double[] coordinates = this.TransformTo (100, 100, false, false, point); return (coordinates [0] >= 0 && coordinates [0] <= 100 && coordinates [1] >= 0 && coordinates [1] <= 100); }