internal override void ShowResult() { base.ShowResult(); // Now show the bearings too. Don't bother if we've // only got 1 point, since that may involve more than // one circle (also true when we have 2 points, but in // that case, we use the first circle arbitrarily). if (Point1 != null && Point2 != null) { // It's conceivable that the two points share more than // one common circle. For now, just pick off the first // common circle and use that. Circle circle = FirstCommonCircle; if (circle == null) { return; } // Get the bearing from the center to both points double bear1 = Geom.BearingInRadians(Point1, circle.Center); double bear2 = Geom.BearingInRadians(Point2, circle.Center); bearing1TextBox.Text = RadianValue.AsString(bear1); bearing2TextBox.Text = RadianValue.AsString(bear2); } else { bearing1TextBox.Text = bearing2TextBox.Text = "<no bearing>"; } }
/// <summary> /// Returns the offset for the parallel, in units on the mapping plane. In order /// for this to work, a prior call to Calculate must be made. /// </summary> /// <returns>The offset distance on the mapping plane (>= 0).</returns> internal double GetPlanarOffset() { // If the reference line or the parallel points are undefined, there's nothing we can do. if (m_Line == null || m_Par1 == null || m_Par2 == null) { return(0.0); } // If the reference line is a curve, get the curve info. ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { // Get the (planar) radial offset from the circle to one of the parallel positions. double radius = arc.Circle.Radius; IPosition center = arc.Circle.Center; return(Math.Abs(Geom.Distance(center, m_Par1) - radius)); } // Get the ends of the reference line. IPosition spos = m_Line.StartPoint; IPosition epos = m_Line.EndPoint; // And its bearing. double bearing = Geom.BearingInRadians(spos, epos); // Get the perpendicular distance (signed) from one of the // parallel points to the reference line. double offdist = Geom.SignedDistance(spos.X, spos.Y, bearing, m_Par1.X, m_Par1.Y); return(Math.Abs(offdist)); }
internal override void ShowResult() { base.ShowResult(); // Now show the bearing too. if (Point1 != null && Point2 != null) { double bearing = Geom.BearingInRadians(Point1, Point2); bearingTextBox.Text = RadianValue.AsString(bearing); } }
/// <summary> /// Calculates positions that are parallel to a line. /// </summary> /// <param name="line">The reference line.</param> /// <param name="offpoint">The point the parallel must pass through.</param> /// <param name="sres">The position of the start of the parallel.</param> /// <param name="eres">The position of the end of the parallel.</param> /// <returns>True if positions calculated ok</returns> internal static bool Calculate(LineFeature refline, PointFeature offpoint, out IPosition sres, out IPosition eres) { // No result positions so far. sres = eres = null; // Get the ends of the reference line. IPosition spos = refline.StartPoint; IPosition epos = refline.EndPoint; // If the reference line is a circular arc ArcFeature arc = refline.GetArcBase(); if (arc != null) { // Get the curve info Circle circle = arc.Circle; double radius = circle.Radius; IPosition centre = circle.Center; bool iscw = arc.IsClockwise; // Get the (planar) distance from the centre of the // circle to the offset point. double offdist = Geom.Distance(offpoint, centre); // Project the BC/EC radially. double sbear = Geom.BearingInRadians(centre, spos); sres = Geom.Polar(centre, sbear, offdist); double ebear = Geom.BearingInRadians(centre, epos); eres = Geom.Polar(centre, ebear, offdist); } else { double bearing = Geom.BearingInRadians(spos, epos); // Get the perpendicular distance (signed) from the offset point // to the reference line. double offdist = Geom.SignedDistance(spos.X, spos.Y, bearing, offpoint.X, offpoint.Y); // Calculate the parallel points. bearing += Constants.PIDIV2; sres = Geom.Polar(spos, bearing, offdist); eres = Geom.Polar(epos, bearing, offdist); } return(true); }
internal void Draw() // was Paint { // Nothing to do if parallel points undefined. if (m_South == null || m_North == null) { return; } Debug.Assert(m_Line != null); ISpatialDisplay draw = m_Cmd.ActiveDisplay; IDrawStyle solidStyle = EditingController.Current.Style(Color.Magenta); IDrawStyle dottedStyle = new DottedStyle(); ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { // The parallel portion is solid, while the remaining portion of the circle is dotted. CircularArcGeometry cg = new CircularArcGeometry(arc.Circle.Center, m_South, m_North, arc.IsClockwise); solidStyle.Render(draw, cg); cg.IsClockwise = !cg.IsClockwise; dottedStyle.Render(draw, cg); } else { // What's the bearing from the start to the end of the parallel? double bearing = Geom.BearingInRadians(m_South, m_North); // What's the max length of a diagonal crossing the entire screen? double maxdiag = m_Cmd.MaxDiagonal; // Project to a point below the southern end of the parallel, as // well as a point above the northern end. IPosition below = Geom.Polar(m_South, bearing + Constants.PI, maxdiag); IPosition above = Geom.Polar(m_North, bearing, maxdiag); LineSegmentGeometry.Render(below, m_South, draw, dottedStyle); LineSegmentGeometry.Render(m_South, m_North, draw, solidStyle); LineSegmentGeometry.Render(m_North, above, draw, dottedStyle); // If we have an offset point, draw it in green. if (m_Point != null) { m_Point.Draw(draw, Color.Green); } } }
/// <summary> /// Returns the intersection of the parallel with a line. A prior call to Calculate is required. /// </summary> /// <param name="line">The line to intersect with.</param> /// <param name="isEndParallel">Is the intersection biased towards the end of the parallel?</param> /// <returns>The intersection (if any). In cases where the line intersects the parallel /// more than once, you get an arbitrary intersection.</returns> internal IPosition GetIntersect(LineFeature line, bool isEndParallel) { // Make sure the intersection is undefined. IPosition result = null; // Return if the parallel points are undefined. if (m_Par1 == null || m_Par2 == null) { return(null); } // If the reference line is a circular arc, get the curve info. ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { Circle circle = arc.Circle; double radius = circle.Radius; IPointGeometry centre = circle.Center; bool iscw = arc.IsClockwise; // Construct a circle that passes through // the parallel points (assumed to have the same distance // with respect to the centre of the circle). double parrad = Geom.Distance(centre, m_Par1); // Intersect the circle with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); uint nx = xres.Intersect(centre, parrad); if (nx == 0) { return(null); } // If there is only one intersection, that's what we want. if (nx == 1) { return(xres.Intersections[0].P1); } // Get the intersection that is closest to the parallel point // that has the bias. if (isEndParallel) { xres.GetClosest(m_Par2, out result, 0.0); } else { xres.GetClosest(m_Par1, out result, 0.0); } } else { // Get the bearing from the start to the end of the parallel. double bearing = Geom.BearingInRadians(m_Par1, m_Par2); // Get the ground dimension of a line that crosses the // extent of the draw window. double dist = MaxDiagonal; // Project the parallel line to positions that are well // beyond the draw extent. IPosition start = Geom.Polar(m_Par1, bearing + Constants.PI, dist); IPosition end = Geom.Polar(m_Par2, bearing, dist); // Intersect the line segment with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); IPointGeometry sg = PointGeometry.Create(start); IPointGeometry eg = PointGeometry.Create(end); uint nx = xres.Intersect(sg, eg); if (nx == 0) { return(null); } // If there is only one intersection, that's what we want. if (nx == 1) { return(xres.Intersections[0].P1); } // Get the intersection that is closest to the parallel point // that has the bias. if (isEndParallel) { xres.GetClosest(m_Par2, out result, 0.0); } else { xres.GetClosest(m_Par1, out result, 0.0); } } return(result); }
/// <summary> /// Calculates positions that are parallel to a line. /// </summary> /// <param name="line">The reference line.</param> /// <param name="offset">The offset to the parallel, in ground units. Signed to denote /// which side (less than zero means it's to the left of the reference line).</param> /// <param name="sres">The position of the start of the parallel.</param> /// <param name="eres">The position of the end of the parallel.</param> /// <returns>True if positions calculated ok</returns> static bool Calculate(LineFeature line, Distance offset, out IPosition sres, out IPosition eres) { // No result positions so far. sres = eres = null; // Get the ends of the reference line. IPosition spos = line.StartPoint; IPosition epos = line.EndPoint; ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem; // If the reference line is a circular arc, get the curve info. ArcFeature arc = line.GetArcBase(); if (arc != null) { Circle circle = arc.Circle; double radius = circle.Radius; IPosition centre = circle.Center; bool iscw = arc.IsClockwise; // Get the midpoint of the curve. The reduction of the // ground distance will be along the line that goes // from the centre of the circle & through this position. ILength len = line.Length; ILength halfLen = new Length(len.Meters * 0.5); IPosition middle; line.LineGeometry.GetPosition(halfLen, out middle); // Get the bearing from the centre to the mid-position // and use that to reduce the offset to the mapping plane. double bearing = Geom.BearingInRadians(centre, middle); double offdist = offset.GetPlanarMetric(middle, bearing, sys); // No parallel if the offset exceeds the radius. // if ( offdist > radius ) return FALSE; // Calculate the parallel points. double sbear = Geom.BearingInRadians(centre, spos); sres = Geom.Polar(centre, sbear, offdist + radius); double ebear = Geom.BearingInRadians(centre, epos); eres = Geom.Polar(centre, ebear, offdist + radius); } else { // Get the bearing.of the line. double bearing = Geom.BearingInRadians(spos, epos); // Get the planar distance for a perpendicular line that passes // through the midpoint of the reference line. The planar distance // will have the same sign as the ground value. IPosition middle = Position.CreateMidpoint(spos, epos); bearing += Constants.PIDIV2; double offdist = offset.GetPlanarMetric(middle, bearing, sys); // Calculate the parallel points. sres = Geom.Polar(spos, bearing, offdist); eres = Geom.Polar(epos, bearing, offdist); } return(true); }
/// <summary> /// Draws the current state of the edit /// </summary> internal void Draw() { Debug.Assert(m_Line != null); ISpatialDisplay view = ActiveDisplay; // Figure out the positions for the ends of the parallel line (if any) ... // Assume we already know both terminals. IPosition start = m_Term1; IPosition end = m_Term2; // If either one is undefined, but a dialog for it is active, // try to get the terminal from there instead. if (m_TermDial1 != null && start == null) { start = m_TermDial1.TerminalPosition; } if (m_TermDial2 != null && end == null) { end = m_TermDial2.TerminalPosition; } // If they weren't actually defined, use the parallel points instead. if (start == null) { start = m_Par1; } if (end == null) { end = m_Par2; } // If those weren't defined either, try to calculate them now. if (end == null && Calculate()) { start = m_Par1; end = m_Par2; } // Any offset point if (m_OffsetPoint != null) { m_OffsetPoint.Draw(view, Color.Green); } // Everything else should draw in usual command-style colour. IDrawStyle style = EditingController.Current.Style(Color.Magenta); IDrawStyle dottedStyle = new DottedStyle(); // If the reference line is a curve, get the curve info. ArcFeature arc = m_Line.GetArcBase(); if (arc != null) { bool iscw = arc.IsClockwise; // Reverse the direction if necessary. if (m_IsReversed) { iscw = !iscw; } // Draw the parallel line (the rest of the circle being dotted). if (start != null) { CircularArcGeometry parArc = new CircularArcGeometry(arc.Circle, start, end, iscw); style.Render(view, parArc); parArc.IsClockwise = !parArc.IsClockwise; dottedStyle.Render(view, parArc); } } else { // PARALLEL IS STRAIGHT // If we've got something, figure out positions for dotted portion. if (start != null) { // What's the max length of a diagonal crossing the entire screen? double maxdiag = this.MaxDiagonal; // What's the bearing from the start to the end of the parallel? double bearing = Geom.BearingInRadians(start, end); // Project to a point before the start end of the parallel, as // well as a point after the end. IPosition before = Geom.Polar(start, bearing + Constants.PI, maxdiag); IPosition after = Geom.Polar(end, bearing, maxdiag); LineSegmentGeometry.Render(before, start, view, dottedStyle); LineSegmentGeometry.Render(start, end, view, style); LineSegmentGeometry.Render(end, after, view, dottedStyle); } } // Draw terminal positions (if defined). if (m_Term1 != null) { style.Render(view, m_Term1); } if (m_Term2 != null) { style.Render(view, m_Term2); } // The terminal lines. if (m_TermLine1 != null) { m_TermLine1.Render(view, style); } if (m_TermLine2 != null) { m_TermLine2.Render(view, style); } // Do the active dialog last so their stuff draws on top. if (m_ParDial != null) { m_ParDial.Draw(); } if (m_TermDial1 != null) { m_TermDial1.Draw(); } if (m_TermDial2 != null) { m_TermDial2.Draw(); } }
/// <summary> /// Returns the intersection of the parallel with a line. /// </summary> /// <param name="refline">The reference line.</param> /// <param name="parpos">Search position that coincides with the parallel.</param> /// <param name="line">The line to intersect with.</param> /// <returns>The intersection (if any). In cases where the line intersects the /// parallel more than once, you get the intersection that is closest to the /// search position.</returns> internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line) { // Make sure the intersection is undefined. IPosition result = null; // Return if the parallel point is undefined. if (parpos == null) { return(null); } // If the reference line is a circular arc (or a section based on an arc), get the curve info. ArcFeature arc = refline.GetArcBase(); if (arc != null) { Circle circle = arc.Circle; double radius = circle.Radius; IPointGeometry centre = circle.Center; bool iscw = arc.IsClockwise; // Construct a circle that passes through the search position double parrad = Geom.Distance(centre, parpos); // Intersect the circle with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); uint nx = xres.Intersect(centre, parrad); if (nx == 0) { return(null); } // If there is only one intersection, that's what we want. if (nx == 1) { return(xres.Intersections[0].P1); } // Get the intersection that is closest to the search position. xres.GetClosest(parpos, out result, 0.0); } else { // Get the bearing from the start to the end of the reference line. IPosition spos = refline.StartPoint; IPosition epos = refline.EndPoint; double bearing = Geom.BearingInRadians(spos, epos); // Project the parallel line to positions that are a long way away (but make sure we // don't end up with negative numbers). Window searchWindow = new Window(line.Extent); searchWindow.Union(refline.Extent); searchWindow.Union(parpos); double dist = Geom.Distance(searchWindow.Min, searchWindow.Max); IPosition start = Geom.Polar(parpos, bearing + Constants.PI, dist); IPosition end = Geom.Polar(parpos, bearing, dist); // Intersect the line segment with the line to intersect with. IntersectionResult xres = new IntersectionResult(line); IPointGeometry sg = new PointGeometry(start); IPointGeometry eg = new PointGeometry(end); uint nx = xres.Intersect(sg, eg); if (nx == 0) { return(null); } // If there is only one intersection, that's what we want. if (nx == 1) { return(xres.Intersections[0].P1); } // Get the intersection that is closest to the search position xres.GetClosest(parpos, out result, 0.0); } return(result); }