public static GraphicsPath CreateTriangle(Rectangle bounds, TriangleOrientation orientation) { GraphicsPath path = new GraphicsPath(); int halfX = bounds.Width / 2; //int halfY = bounds.Height / 2; switch (orientation) { case TriangleOrientation.Up: path.AddLine(bounds.X, bounds.Y + bounds.Height, bounds.X + halfX, bounds.Y); // bottom-left to top path.AddLine(bounds.X + halfX, bounds.Y, bounds.X + bounds.Width, bounds.Y + bounds.Height); // top to bottom-right break; case TriangleOrientation.Down: path.AddLine(bounds.X, bounds.Y, bounds.X + halfX, bounds.Y + bounds.Height); // top-left to bottom path.AddLine(bounds.X + halfX, bounds.Y + bounds.Height, bounds.X + bounds.Width, bounds.Y); // bottom to top-right break; } path.CloseFigure(); return(path); }
/// <summary> /// Returns the point location value. The assumption is that the polyline goes clockwise and is closed and convex. /// </summary> /// <param name="point">Point to find.</param> /// <param name="witness">if the point belongs to the boundary then witness is /// the first point of the boundary segment containing p </param> /// <returns></returns> internal PointLocation GetPointLocation(Point point, out PolylinePoint witness) { Debug.Assert(Closed && IsClockwise()); witness = null; foreach (PolylinePoint polyPoint in PolylinePoints) { PolylinePoint secondPoint = Next(polyPoint); TriangleOrientation triangleOrientation = Point.GetTriangleOrientation(point, polyPoint.Point, secondPoint.Point); if (triangleOrientation == TriangleOrientation.Counterclockwise) { return(PointLocation.Outside); } if (triangleOrientation == TriangleOrientation.Collinear) { if ((point - polyPoint.Point) * (secondPoint.Point - point) >= 0) { witness = polyPoint; return(PointLocation.Boundary); } } } return(PointLocation.Inside); }
public Triangle(TriangleOrientation orientation, SubTriangles id, int resolution) { Resolution = resolution; Orientation = orientation; Children = new Dictionary <SubTriangles, Triangle>(); Cells = new Dictionary <TriangleCells, Cell>(); Id = id; if (resolution == 0) { return; } var nextResolution = resolution - 1; Children.Add(SubTriangles.TriTopBot, new Triangle(orientation, SubTriangles.TriTopBot, nextResolution)); Children.Add(SubTriangles.TriLeft, new Triangle(orientation, SubTriangles.TriLeft, nextResolution)); Children.Add(SubTriangles.TriRight, new Triangle(orientation, SubTriangles.TriRight, nextResolution)); Children.Add(SubTriangles.HexBot, new Triangle(TriangleOrientation.Up, SubTriangles.HexBot, nextResolution)); Children.Add(SubTriangles.HexBotLeft, new Triangle(TriangleOrientation.Down, SubTriangles.HexBotLeft, nextResolution)); Children.Add(SubTriangles.HexBotRight, new Triangle(TriangleOrientation.Down, SubTriangles.HexBotRight, nextResolution)); Children.Add(SubTriangles.HexTop, new Triangle(TriangleOrientation.Down, SubTriangles.HexTop, nextResolution)); Children.Add(SubTriangles.HexTopLeft, new Triangle(TriangleOrientation.Up, SubTriangles.HexTopLeft, nextResolution)); Children.Add(SubTriangles.HexTopRight, new Triangle(TriangleOrientation.Up, SubTriangles.HexTopRight, nextResolution)); }
IEnumerable <Stem> GetInitialVisibleBoundaryStemsAndInsertActiveSides() { foreach (var keyValuePair in visibleBoundaries) { Polyline hole = keyValuePair.Key; Stem stem = keyValuePair.Value; bool crosses = false; foreach (PolylinePoint side in stem.Sides) { PolylinePoint source = side; if (source.Point.Y < q.Y) { if (side.NextOnPolyline.Point.Y >= q.Y) { TriangleOrientation orientation = Point.GetTriangleOrientation(q, source.Point, side.NextOnPolyline.Point); if (orientation == TriangleOrientation.Counterclockwise || orientation == TriangleOrientation.Collinear) { crosses = true; //we have two stems here yield return(new Stem(stem.Start, side)); yield return(new Stem(side.NextOnPolyline, stem.End)); RegisterActiveSide(side); break; } } } else if (source.Point.Y > q.Y) { break; } else if (side.Point.X >= q.X) { //we have pp.Y==q.Y crosses = true; //we need to add one or two stems here yield return(new Stem(side, stem.End)); if (side != stem.Start) { yield return(new Stem(stem.Start, hole.Prev(source))); } RegisterActiveSide(side); break; } } //there is no intersection with the ray if (!crosses) { yield return(stem); } } }
bool SomePreviousPointIsOnOtherSiteOfEdge(CdtEdge cdtEdge, TriangleOrientation segEndOrientation) { foreach (PolylinePoint polylinePoint in polylineHead) { var orientation = Point.GetTriangleOrientation(polylinePoint.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); if (orientation != TriangleOrientation.Collinear) return orientation != segEndOrientation; } return false; }
// Private members private void PaintButton(ControlPaintArgs e, Rectangle clientRect, TriangleOrientation arrowOrientation, IRuleset ruleset) { e.StyleRenderer.PaintBackground(e.Graphics, clientRect, ruleset); e.StyleRenderer.PaintBorder(e.Graphics, clientRect, ruleset); clientRect.Inflate(new Size(-5, -3)); clientRect.Offset(1, 0); using (Brush brush = new SolidBrush(ruleset.Color?.Value ?? Color.Black)) e.Graphics.FillTriangle(brush, clientRect, arrowOrientation); }
bool SomePreviousPointIsOnOtherSiteOfEdge(CdtEdge cdtEdge, TriangleOrientation segEndOrientation) { foreach (PolylinePoint polylinePoint in polylineHead) { var orientation = Point.GetTriangleOrientation(polylinePoint.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); if (orientation != TriangleOrientation.Collinear) { return(orientation != segEndOrientation); } } return(false); }
static void PickNextVertex(ref PolylinePoint p0, ref PolylinePoint p1) { Point d = p1.Point - p0.Point; TriangleOrientation orient = Point.GetTriangleOrientation(p1.Point, p1.Polyline.Next(p1).Point, p0.Polyline.Next(p0).Point + d); if (orient == TriangleOrientation.Counterclockwise) { p0 = p0.Polyline.Next(p0); } else { p1 = p1.Polyline.Next(p1); } }
bool InternalCut(ref int p1, ref int p2, ref int q1, ref int q2, int mp, int mq, double a1, double a2, double b1, double b2) { bool ret = false; if (a1 >= Math.PI && a2 >= Math.PI) { //Find out who is on the same side from [mq,mp] as Q[0], the next or the prev. Remember that we found the first chunk from Q[0] //System.Diagnostics.Debug.WriteLine("cutting P"); // if(debug) LayoutAlgorithmSettings.Show(P.Polyline, Q.Polyline, Ls(p1, q1), Ls(p2, q2), Ls(mp, mq)); Point mpp = P[mp].Point; Point mqp = Q[mq].Point; Point mpnp = P[P.Next(mp)].Point; TriangleOrientation orientation = Point.GetTriangleOrientation(mpp, mqp, Q[0].Point); TriangleOrientation nextOrientation = Point.GetTriangleOrientation(mpp, mqp, mpnp); if (orientation == nextOrientation) { p1 = P.Next(mp); } else { p2 = P.Prev(mp); } ret = true; } if (b1 >= Math.PI && b2 >= Math.PI) { //Find out who is on the same side from [mq,mp] as P[0], the next or the prev. Remember that we found the first chunk from P[0] //System.Diagnostics.Debug.WriteLine("cutting Q"); // if (debug) LayoutAlgorithmSettings.Show(P.Polyline, Q.Polyline, Ls(p1, q1), Ls(p2, q2), Ls(mp, mq)); Point mpp = P[mp].Point; Point mqp = Q[mq].Point; Point mqnp = Q[Q.Next(mq)].Point; TriangleOrientation orientation = Point.GetTriangleOrientation(mpp, mqp, P[0].Point); TriangleOrientation nextOrientation = Point.GetTriangleOrientation(mpp, mqp, mqnp); if (orientation == nextOrientation) { q2 = Q.Next(mq); } else { q1 = Q.Prev(mq); } ret = true; } return(ret); }
static bool CurveIsConvex(Polyline poly) { TriangleOrientation orientation = Point.GetTriangleOrientation(poly.EndPoint.Point, poly.StartPoint.Point, poly.StartPoint.Next.Point); if (Point.GetTriangleOrientation(poly.EndPoint.Prev.Point, poly.EndPoint.Point, poly.StartPoint.Point) != orientation) { return(false); } PolylinePoint pp = poly.StartPoint; while (pp.Next.Next != null) { if (Point.GetTriangleOrientation(pp.Point, pp.Next.Point, pp.Next.Next.Point) != orientation) { return(false); } pp = pp.Next; } return(true); }
internal static void CheckThatPolylineIsConvex(Polyline polyline) { Debug.Assert(polyline.Closed, "Polyline is not closed"); PolylinePoint a = polyline.StartPoint; PolylinePoint b = a.Next; PolylinePoint c = b.Next; TriangleOrientation orient = Point.GetTriangleOrientation(a.Point, b.Point, c.Point); while (c != polyline.EndPoint) { a = a.Next; b = b.Next; c = c.Next; var currentOrient = Point.GetTriangleOrientation(a.Point, b.Point, c.Point); if (currentOrient == TriangleOrientation.Collinear) { continue; } if (orient == TriangleOrientation.Collinear) { orient = currentOrient; } else if (orient != currentOrient) { throw new InvalidOperationException(); } } var o = Point.GetTriangleOrientation(polyline.EndPoint.Point, polyline.StartPoint.Point, polyline.StartPoint.Next.Point); if (o != TriangleOrientation.Collinear && o != orient) { throw new InvalidOperationException(); } }
void ShrinkBasesToMakeTwoConsecutiveNeighborsHappy(BundleBase rBase, BundleBase lBase) { if (!rBase.Intersect(lBase)) { return; } //segments are now [l1..r1] and [l2..r2] double l1 = rBase.ParRight; double r1 = rBase.ParLeft; double l2 = lBase.ParRight; double r2 = lBase.ParLeft; double span = lBase.ParameterSpan; //make them regular if (l1 > r1) { l1 -= span; } if (l2 > r2) { l2 -= span; } //make them intersecting if (l2 > r1) { l2 -= span; r2 -= span; } if (l1 > r2) { l1 -= span; r1 -= span; } //they do intersect! Debug.Assert(!(l2 >= r1) && !(l1 >= r2)); double t = RegularCut(l1, r1, l2, r2, rBase.Span, lBase.Span); TriangleOrientation to = Point.GetTriangleOrientation(lBase.CurveCenter, lBase.OppositeBase.InitialMidPoint, rBase.OppositeBase.InitialMidPoint); if (to == TriangleOrientation.Clockwise) { r1 = t; l2 = t; } else if (to == TriangleOrientation.Counterclockwise) { r2 = t; l1 = t; } else { if (r2 - l1 >= r1 - l2) { r1 = t; l2 = t; } else { r2 = t; l1 = t; } } Debug.Assert(!rBase.Intersect(l1, r1, l2, r2)); lBase.ParRight = lBase.AdjustParam(l2); lBase.ParLeft = lBase.AdjustParam(r2); rBase.ParRight = rBase.AdjustParam(l1); rBase.ParLeft = rBase.AdjustParam(r1); }
public static void FillTriangle(this Graphics graphics, Brush brush, Rectangle bounds, TriangleOrientation orientation) { if (graphics is null) { throw new ArgumentNullException(nameof(graphics)); } if (brush is null) { throw new ArgumentNullException(nameof(brush)); } using (GraphicsPath path = CreateTriangle(bounds, orientation)) graphics.FillPath(brush, path); }
public static void DrawTriangle(this Graphics graphics, Pen pen, Rectangle bounds, TriangleOrientation orientation) { if (graphics is null) { throw new ArgumentNullException(nameof(graphics)); } if (pen is null) { throw new ArgumentNullException(nameof(pen)); } using (GraphicsPath path = CreateTriangle(bounds, orientation)) graphics.DrawPath(pen, path); }
internal bool InverseIsFree(TriangleOrientation orientation) { throw new NotImplementedException(); }