public override object Clone() { return(new DrawablePath { Path = Path?.Clone() as GraphicsPath, Brush = Brush?.Clone() as Brush, Pen = Pen?.Clone() as Pen }); }
public override object Clone() { return(new DrawablePolygon { Points = Points?.Clone() as PointF[], Brush = Brush?.Clone() as Brush, Pen = Pen?.Clone() as Pen, PenClosed = PenClosed }); }
public Bitmap ToBitmapUncached(byte xiOrientation) { Bitmap lBmp = new Bitmap(8 * SCALE, 8 * SCALE); Graphics g = Graphics.FromImage(lBmp); bool[,] lDrawn = new bool[8, 8]; for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { if (lDrawn[x, y]) { continue; } int lDirection = GetDirection(xiOrientation, x, y); int lWidth = 1; int lHeight = 1; int lFarX = x; int lFarY = y; //=================================================================== // Try to find as many pixels to the right and below this one with // the same direction as possible, so we can combine them together // into one arrow on the image. //=================================================================== while (lFarX < 7 || lFarY < 7) { bool lCanExtendRight = lFarX < 7; for (int lTestY = y; lCanExtendRight && lTestY <= lFarY; lTestY++) { if (GetDirection(xiOrientation, lFarX + 1, lTestY) != lDirection) { lCanExtendRight = false; } } if (lCanExtendRight) { lWidth++; lFarX += 1; } bool lCanExtendDown = lFarY < 7; for (int lTestX = x; lCanExtendDown && lTestX <= lFarX; lTestX++) { if (GetDirection(xiOrientation, lTestX, lFarY + 1) != lDirection) { lCanExtendDown = false; } } if (lCanExtendDown) { lHeight++; lFarY += 1; } if (!lCanExtendRight && !lCanExtendDown) { break; } else if (Math.Abs((lFarX - x) - (lFarY - y)) > 1) { break; // Don't make a shape that's too long and thin } } //=================================================================== // Mark all the squares we're drawing in one go as having been drawn, // so we don't try and draw them again. //=================================================================== for (int lDrawnX = x; lDrawnX <= lFarX; lDrawnX++) { for (int lDrawnY = y; lDrawnY <= lFarY; lDrawnY++) { lDrawn[lDrawnX, lDrawnY] = true; } } //=================================================================== // Draw the arrow //=================================================================== double lMidX = x + (lFarX - x) / 2.0; double lMidY = y + (lFarY - y) / 2.0; double lSize = Math.Sqrt(((1 + lFarX - x) ^ 2) + ((1 + lFarY - y) ^ 2)); Pen lWidePen = (Pen)mActivePen.Clone(); lWidePen.Width = (float)lSize * 0.75f; Utils.DrawArrow(g, lWidePen, new Point((int)((lMidX * SCALE) + (SCALE / 2.0)), (int)((lMidY * SCALE) + (SCALE / 2.0))), lDirection, (int)(lSize * SCALE), (int)Math.Ceiling(lWidePen.Width), true); //=================================================================== // Uncomment this section to debug //=================================================================== // lWidePen.Width = 2; // g.DrawRectangle(lWidePen, SCALE * x, SCALE * y, SCALE * (1 + lFarX - x), SCALE * (1 + lFarY - y)); } } return(lBmp); }
public SimplePen(Pen pen) { _pen = pen.Clone() as Pen; }
private void Process(Graphics g, Size s) { Boolean analyze = (g == null); Boolean drawing = (g != null); if (drawing && !mRange.DrawingRange.ValidRange) { return; } float zoom = drawing ? DrawJobRange(g, ref s) : 1; bool firstline = true; bool laser = false; decimal curX = 0; decimal curY = 0; decimal speed = 0; int curAlpha = 0; bool cw = false; //cw-ccw memo bool abs = false; //absolute-relative memo if (analyze) { mRange.ResetRange(); mRange.UpdateXYRange(0, 0, false); mTotalTravelOn = 0; mTotalTravelOff = 0; mEstimatedTimeOn = TimeSpan.Zero; mEstimatedTimeOff = TimeSpan.Zero; } if (drawing && !mRange.SpindleRange.ValidRange) //assign max alpha if no S range available { curAlpha = 255; } foreach (GrblCommand cmd in list) { TimeSpan delay = TimeSpan.Zero; if (cmd.IsLaserON) { laser = true; } else if (cmd.IsLaserOFF) { laser = false; } if (cmd.IsRelativeCoord) { abs = false; } if (cmd.IsAbsoluteCoord) { abs = true; } if (cmd.F != null) { speed = cmd.F.Number; } if (drawing && cmd.S != null) { if (mRange.SpindleRange.ValidRange) { curAlpha = (int)((cmd.S.Number - mRange.SpindleRange.S.Min) * 255 / (mRange.SpindleRange.S.Max - mRange.SpindleRange.S.Min)); } else { curAlpha = 255; } } if (analyze && cmd.S != null) { mRange.UpdateSRange(cmd.S.Number); } if (cmd.IsMovement && cmd.TrueMovement(curX, curY, abs)) { decimal newX = cmd.X != null ? (abs ? cmd.X.Number : curX + cmd.X.Number) : curX; decimal newY = cmd.Y != null ? (abs ? cmd.Y.Number : curY + cmd.Y.Number) : curY; if (analyze) { mRange.UpdateXYRange(newX, newY, laser); decimal distance = 0; if (cmd.IsLinearMovement) { distance = Tools.MathHelper.LinearDistance(curX, curY, newX, newY); } else if (cmd.IsArcMovement) //arc of given radius { distance = Tools.MathHelper.ArcDistance(curX, curY, newX, newY, cmd.GetArcRadius()); } if (laser) { mTotalTravelOn += distance; } else { mTotalTravelOff += distance; } if (distance != 0 && speed != 0) { delay = TimeSpan.FromMinutes((double)distance / (double)speed); } } if (drawing) { Pen colorpen = firstline ? Pens.Blue : laser ? Pens.Red : Pens.LightGray; using (Pen pen = colorpen.Clone() as Pen) { pen.ScaleTransform(1 / zoom, 1 / zoom); if (laser) { pen.Color = Color.FromArgb(curAlpha, pen.Color); } if (!laser) { pen.Color = Color.FromArgb(150, pen.Color); pen.DashStyle = DashStyle.Dash; pen.DashPattern = new float[] { 1f, 1f }; } if (cmd.IsLinearMovement) { g.DrawLine(pen, new PointF((float)curX, (float)curY), new PointF((float)newX, (float)newY)); } else if (cmd.IsArcMovement) { cw = cmd.IsCW(cw); PointF center = cmd.GetCenter((float)curX, (float)curY); double cX = center.X; double cY = center.Y; double aX = (double)curX; double aY = (double)curY; double bX = (double)newX; double bY = (double)newY; double ray = cmd.GetArcRadius(); double rectX = cX - ray; double rectY = cY - ray; double rectW = 2 * ray; double rectH = 2 * ray; double aA = Tools.MathHelper.CalculateAngle(cX, cY, aX, aY); //180/Math.PI*Math.Atan2(y1-y0, x1-x0); double bA = Tools.MathHelper.CalculateAngle(cX, cY, bX, bY); //180/Math.PI*Math.Atan2(y2-y0, x2-x0); double sA = aA; //start angle double wA = Tools.MathHelper.AngularDistance(aA, bA, cw); if (rectW > 0 && rectH > 0) { try{ g.DrawArc(pen, (float)rectX, (float)rectY, (float)rectW, (float)rectH, (float)sA, (float)wA); } catch { System.Diagnostics.Debug.WriteLine(String.Format("Ex drwing arc: W{0} H{1}", rectW, rectH)); } } } } firstline = false; } curX = newX; curY = newY; } else if (cmd.IsPause) { if (analyze) { //TimeSpan delay = cmd.P != null ? TimeSpan.FromMilliseconds((double)cmd.P.Number) : cmd.S != null ? TimeSpan.FromSeconds((double)cmd.S.Number) : TimeSpan.Zero; //grbl seem to use both P and S as number of seconds delay = cmd.P != null?TimeSpan.FromSeconds((double)cmd.P.Number) : cmd.S != null?TimeSpan.FromSeconds((double)cmd.S.Number) : TimeSpan.Zero; } } if (laser) { mEstimatedTimeOn += delay; } else { mEstimatedTimeOff += delay; } if (analyze) { cmd.SetOffset(mTotalTravelOn + mTotalTravelOff, mEstimatedTimeOn + mEstimatedTimeOff); } } }
public void ChangePen(Pen pen) { Pen = (Pen)pen.Clone(); Pen.DashPattern = new float[] { 1f, 1f }; }
void DrawEdge(Graphics g, Edge item, PointF p1, PointF p2, bool selected) { string distance = GetDistance(Point.Round(p1), Point.Round(p2)).ToString(); p1.X += NODE_RADIUS; p1.Y += NODE_RADIUS; p2.X += NODE_RADIUS; p2.Y += NODE_RADIUS; Vector2D v1 = new Vector2D(p1.X - p2.X, p1.Y - p2.Y); if (v1.Length - NODE_RADIUS > 0) { v1.Contract(NODE_RADIUS); p1.X = p2.X + v1.X; p1.Y = p2.Y + v1.Y; } Vector2D v = new Vector2D(p2.X - p1.X, p2.Y - p1.Y); if (v.Length - NODE_RADIUS > 0) { v.Contract(NODE_RADIUS); p2.X = p1.X + v.X; p2.Y = p1.Y + v.Y; } if (!IsUndirectedGraph && item.IsUndirected) { _penEdge.StartCap = LineCap.ArrowAnchor; } else { _penEdge.StartCap = LineCap.NoAnchor; } if (item.IsRemoving) { Pen p = new Pen(Color.Red, 4); g.DrawLine(p, p1, p2); } else { if (_path != null && (_path.Contains(new Point(item.Start, item.End)) || _path.Contains(new Point(item.End, item.Start)))) { Pen p = (Pen)_penEdge.Clone(); p.Color = Color.Green; p.DashStyle = DashStyle.Dash; g.DrawLine(p, p1, p2); } else if (selected) { var hPen = (Pen)_penEdge.Clone(); hPen.Color = Color.Red; g.DrawLine(hPen, p1, p2); } else { g.DrawLine(_penEdge, p1, p2); } } // draw distance SizeF size = g.MeasureString(distance, this.Font); PointF pp = p1; pp.X += p2.X; pp.Y += p2.Y; pp.X /= 2; pp.Y /= 2; pp.X -= size.Width / 2; pp.Y -= size.Height / 2; g.FillEllipse(Brushes.Yellow, pp.X - 5, pp.Y - 5, size.Width + 10, size.Height + 5); g.DrawString(distance.ToString(), this.Font, Brushes.Blue, pp); }
private DrawingPen(Pen other) { this.pen = other.Clone(); }
public Line(Graphics g, Pen p) { this.g = g; this.p = (Pen)p.Clone(); this.vertexList = new List <PointF>(2); }
protected override void OnRender(DrawingContext drawingContext) { Brush brush = _solidColorBrush; Pen pen = _dashPen; BondLayout layout; var length = CurrentEditor.Chemistry.Model.XamlBondLength; if (ExistingBond == null || !ExistingBond.IsCyclic()) { layout = GetBondLayout(StartPoint, EndPoint, length, Stereo, BondOrder); } else { layout = GetBondLayout(StartPoint, EndPoint, length, Stereo, BondOrder, ExistingBond.PrimaryRing, ExistingBond.SubsidiaryRing); } if (Stereo == Globals.BondStereo.Hatch) { brush = new LinearGradientBrush { MappingMode = BrushMappingMode.Absolute, SpreadMethod = GradientSpreadMethod.Repeat, StartPoint = new Point(50, 0), EndPoint = new Point(50, 3), GradientStops = new GradientStopCollection() { new GradientStop { Offset = 0d, Color = _solidColorBrush.Color }, new GradientStop { Offset = 0.25d, Color = _solidColorBrush.Color }, new GradientStop { Offset = 0.25d, Color = Colors.Transparent }, new GradientStop { Offset = 0.30, Color = Colors.Transparent } }, Transform = new RotateTransform { Angle = Vector.AngleBetween(Model2.Geometry.BasicGeometry.ScreenNorth, EndPoint - StartPoint) } }; } switch (BondOrder) { case Globals.OrderZero: case Globals.OrderOther: case "unknown": pen = pen.Clone(); pen.DashStyle = DashStyles.Dot; drawingContext.DrawGeometry(brush, pen, layout.DefiningGeometry); break; case Globals.OrderPartial01: pen = pen.Clone(); pen.DashStyle = DashStyles.Dash; drawingContext.DrawGeometry(brush, pen, layout.DefiningGeometry); break; case Globals.OrderAromatic: case Globals.OrderPartial12: var secondPen = pen.Clone(); secondPen.DashStyle = DashStyles.Dash; drawingContext.DrawLine(pen, layout.Start, layout.End); var doubleBondDescriptor = (layout as DoubleBondLayout); drawingContext.DrawLine(secondPen, doubleBondDescriptor.SecondaryStart, doubleBondDescriptor.SecondaryEnd); break; case Globals.OrderPartial23: var tbd = (layout as TripleBondLayout); secondPen = pen.Clone(); secondPen.DashStyle = DashStyles.Dash; drawingContext.DrawLine(pen, tbd.SecondaryStart, tbd.SecondaryEnd); drawingContext.DrawLine(pen, tbd.Start, tbd.End); drawingContext.DrawLine(secondPen, tbd.TertiaryStart, tbd.TertiaryEnd); break; case Globals.OrderTriple: tbd = (layout as TripleBondLayout); drawingContext.DrawLine(pen, tbd.SecondaryStart, tbd.SecondaryEnd); drawingContext.DrawLine(pen, tbd.Start, tbd.End); drawingContext.DrawLine(pen, tbd.TertiaryStart, tbd.TertiaryEnd); break; default: drawingContext.DrawGeometry(brush, pen, layout.DefiningGeometry); break; } }
public override void Plot(Graphics graphics, Rectangle bounds, double min, double max) { if (Bars == null) { return; } if (useplot) { base.Plot(graphics, bounds, min, max); int lastBar = Math.Min(this.LastBarIndexPainted, Bars.Count - 1); int firstBar = this.FirstBarIndexPainted; Pen outlinePen = ChartControl.ChartStyle.Pen; int barPaintWidth = (int)(1 + 2 * (ChartControl.ChartStyle.BarWidthUI - 1) + 2 * outlinePen.Width); //ChartControl.ChartStyle.GetBarPaintWidth(ChartControl.BarWidth); int barwidth = ChartControl.BarWidth; Color ColorNeutral = outlinePen.Color; Pen HiLoPen = (Pen)outlinePen.Clone(); if (EnhanceHL) { HiLoPen.Width *= 2; } int penSize; if (ChartControl.ChartStyle.ChartStyleType == ChartStyleType.OHLC) { penSize = Math.Max(0, barwidth - 2); } else if (ChartControl.ChartStyle.ChartStyleType == ChartStyleType.HiLoBars) { penSize = barwidth; } else if (chart == GomCDChartType.NonCumulativeChart && ForceHiLo) { penSize = ForcedHiLoBS; } else { penSize = 1; } drawPen.Width = penSize; int x, yHigh, yClose, yOpen, yLow; int direction; //zero line int y0 = ChartControl.GetYByValue(this, 0.0); if ((chart == GomCDChartType.NonCumulativeChart) || ReinitSession) { graphics.DrawLine(new Pen(Color.Blue), bounds.X, y0, bounds.X + bounds.Width, y0); } for (int index = firstBar; index <= lastBar; index++) { direction = 0; if ((index <= lastcalcbar) && (index >= Math.Max(1, startbar))) { x = ChartControl.GetXByBarIdx(BarsArray[0], index); yHigh = ChartControl.GetYByValue(this, dsHigh.Get(index)); yClose = ChartControl.GetYByValue(this, dsClose.Get(index)); yOpen = ChartControl.GetYByValue(this, dsOpen.Get(index)); yLow = ChartControl.GetYByValue(this, dsLow.Get(index)); if (PtType == GomPaintType.StrongUpDown) { if (dsClose.Get(index) < dsLow.Get(index - 1)) { direction = -1; } else if (dsClose.Get(index) > dsHigh.Get(index - 1)) { direction = 1; } } else if (PtType == GomPaintType.UpDown) { if (dsClose.Get(index) < dsOpen.Get(index)) { direction = -1; } else if (dsClose.Get(index) > dsOpen.Get(index)) { direction = 1; } } if (direction == 1) { drawPen.Color = ChartControl.UpColor; } else if (direction == -1) { drawPen.Color = ChartControl.DownColor; } else { drawPen.Color = ColorNeutral; } drawBrush.Color = drawPen.Color; if ((ChartControl.ChartStyle.ChartStyleType == ChartStyleType.HiLoBars) || (chart == GomCDChartType.NonCumulativeChart && ForceHiLo)) { graphics.DrawLine(drawPen, x, yHigh, x, yLow); } else if (ChartControl.ChartStyle.ChartStyleType == ChartStyleType.CandleStick) { graphics.DrawLine(HiLoPen, x, yLow, x, yHigh); if (yClose == yOpen) { graphics.DrawLine(outlinePen, x - barwidth - outlinePen.Width, yClose, x + barwidth + outlinePen.Width, yClose); } else { graphics.FillRectangle(drawBrush, x - barPaintWidth / 2, Math.Min(yClose, yOpen) + 1, barPaintWidth, Math.Abs(yClose - yOpen)); if (ShowOutline) { // graphics.FillRectangle(neutralBrush,x-barwidth-outlinepenwidth,Math.Min(yClose,yOpen)+1,2*(barwidth+outlinepenwidth)+1,Math.Abs(yClose-yOpen)-1); // graphics.FillRectangle(drawBrush,x-barwidth,Math.Min(yClose,yOpen)+1,2*barwidth+1,Math.Abs(yClose-yOpen)-1); //graphics.DrawRectangle(outlinePen, x - barwidth - outlinePen.Width / 2, Math.Min(yClose, yOpen), 2 * (barwidth) + outlinePen.Width + 1, Math.Abs(yClose - yOpen)); graphics.DrawRectangle(outlinePen, x - (barPaintWidth / 2) + (outlinePen.Width / 2), Math.Min(yClose, yOpen), barPaintWidth - outlinePen.Width, Math.Abs(yClose - yOpen)); } } } else { graphics.DrawLine(drawPen, x, yLow + penSize / 2, x, yHigh - penSize / 2); graphics.DrawLine(drawPen, x, yClose, x + barwidth, yClose); graphics.DrawLine(drawPen, x - barwidth, yOpen, x, yOpen); } } } } else { base.Plot(graphics, bounds, min, max); } }
public void setPaint(Point start, Point finish, Pen shapePen) { point[0] = start; point[1] = finish; this.pen = (Pen)shapePen.Clone(); }
public virtual void DrawGraphic(GTranslator gt) { float m_zoom = gt.zoom.X; Pen pen = new Pen(penColor, penWidth / m_zoom); //g.SmoothingMode = SmoothingMode.HighQuality; switch (drawingMode) { /* * case DrawModes.DrawLines: #region For each ( PointF[] segment in graphic ) check visibility and draw * foreach (PointF[] segment in graphic) * { * for (int i = 0; i < segment.Length - 1; i++) * { * PointF pt1 = segment[i]; * PointF pt2 = segment[i + 1]; * * if (g.ClipBounds.Left > pt1.X) * pt1.X = g.ClipBounds.Left; * * if (g.ClipBounds.Right < pt1.X) * pt1.X = g.ClipBounds.Right; * * if (g.ClipBounds.Top > pt1.Y) * pt1.Y = g.ClipBounds.Top; * * if (g.ClipBounds.Bottom < pt1.Y) * pt1.Y = g.ClipBounds.Bottom; * * if (g.ClipBounds.Left > pt2.X) * pt2.X = g.ClipBounds.Left; * * if (g.ClipBounds.Right < pt2.X) * pt2.X = g.ClipBounds.Right; * * if (g.ClipBounds.Top > pt2.Y) * pt2.Y = g.ClipBounds.Top; * * if (g.ClipBounds.Bottom < pt2.Y) * pt2.Y = g.ClipBounds.Bottom; * * g.DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y); * } * } #endregion * break; */ case DrawModes.DrawPoints: float dotWidth = pen.Width; foreach (PointF[] segment in graphic) { for (int i = 0; i < segment.Length; i++) { gt.DrawEllipse(pen, segment[i].X - dotWidth / 2f, segment[i].Y - dotWidth / 2f, dotWidth, dotWidth); } } break; case DrawModes.DrawFilledPolygon: SolidBrush brush = new SolidBrush(pen.Color); Pen pen1 = (Pen)pen.Clone(); pen1.Width = 2f / m_zoom; foreach (PointF[] segment in graphic) { if (segment.Length < 2) { continue; } gt.FillPolygon(brush, segment); gt.DrawPolygon(pen1, segment); } break; } }
private double[] factorialMas = FillFactorialMas(MaxNumOfPoints); // array of factorials public Bezie(Graphics g, Pen p) { this.g = g; this.p = (Pen)p.Clone(); this.vertexList = new List <PointF>(MaxNumOfPoints); }
/// <summary> /// Draws the line plot on a GDI+ surface against the provided x and y axes. /// </summary> /// <param name="g">The GDI+ surface on which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow) { Pen shadowPen = null; if (drawShadow) { shadowPen = (Pen)Pen.Clone(); shadowPen.Color = ShadowColor; } SequenceAdapter data = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis); int numberPoints = data.Count; if (data.Count == 0) { return; } // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { PointF physical = t.Transform(data[0]); if (drawShadow) { g.DrawLine(shadowPen, physical.X - 0.5f + ShadowOffset.X, physical.Y + ShadowOffset.Y, physical.X + 0.5f + ShadowOffset.X, physical.Y + ShadowOffset.Y); } else { g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap(ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0, 0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i - 1].X; double dx2 = data[i].X; double dy1 = data[i - 1].Y; double dy2 = data[i].Y; if (Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2)) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff || rightCutoff < dx1) && (dx2 < leftCutoff || rightCutoff < dx2)) { continue; } // else draw line. PointF p1 = t.Transform(data[i - 1]); PointF p2 = t.Transform(data[i]); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) { continue; } if (drawShadow) { g.DrawLine(shadowPen, p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y, p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y); } else { g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y); } } } }
/// <summary> /// Creates the reachspec connections from this pathfinding node to others. /// </summary> public override void CreateConnections(List <PathfindingNodeMaster> graphNodes) { ReachSpecs = (SharedPathfinding.GetReachspecExports(export)); foreach (ExportEntry spec in ReachSpecs) { Pen penToUse = blackPen; switch (spec.ObjectName.Name) { case "SlotToSlotReachSpec": penToUse = slotToSlotPen; break; case "CoverSlipReachSpec": penToUse = coverSlipPen; break; case "SFXLadderReachSpec": penToUse = sfxLadderPen; break; case "SFXLargeBoostReachSpec": penToUse = sfxLargeBoostPen; break; case "SFXBoostReachSpec": penToUse = sfxBoostPen; break; case "SFXJumpDownReachSpec": penToUse = sfxJumpDownPen; break; } //Get ending PropertyCollection props = spec.GetProperties(); ExportEntry otherEndExport = SharedPathfinding.GetReachSpecEndExport(spec, props); /* * if (props.GetProp<StructProperty>("End") is StructProperty endProperty && * endProperty.GetProp<ObjectProperty>(SharedPathfinding.GetReachSpecEndName(spec)) is ObjectProperty otherNodeValue) * { * othernodeidx = otherNodeValue.Value; * }*/ if (otherEndExport != null) { bool isTwoWay = false; PathfindingNodeMaster othernode = graphNodes.FirstOrDefault(x => x.export == otherEndExport); if (othernode != null) { //Check for returning reachspec for pen drawing. This is going to incur a significant performance penalty... var othernodeSpecs = SharedPathfinding.GetReachspecExports(otherEndExport); foreach (var path in othernodeSpecs) { if (SharedPathfinding.GetReachSpecEndExport(path) == export) { isTwoWay = true; break; } } //var // PropertyCollection otherSpecProperties = possibleIncomingSpec.GetProperties(); // if (otherSpecProperties.GetProp<StructProperty>("End") is StructProperty endStruct) // { // if (endStruct.GetProp<ObjectProperty>(SharedPathfinding.GetReachSpecEndName(possibleIncomingSpec)) is ObjectProperty incomingTargetIdx) // { // if (incomingTargetIdx.Value == export.UIndex) // { // isTwoWay = true; // break; // } // } // } //} //if (othernode != null) //{ var radius = props.GetProp <IntProperty>("CollisionRadius"); var height = props.GetProp <IntProperty>("CollisionHeight"); bool penCloned = false; if (radius != null && height != null && (radius >= ReachSpecSize.MINIBOSS_RADIUS || height >= ReachSpecSize.MINIBOSS_HEIGHT)) { penCloned = true; penToUse = (Pen)penToUse.Clone(); if (radius >= ReachSpecSize.BOSS_RADIUS && height >= ReachSpecSize.BOSS_HEIGHT) { penToUse.Width = 3; } else { penToUse.Width = 2; } } if (!isTwoWay) { if (!penCloned) { penToUse = (Pen)penToUse.Clone(); penCloned = true; } penToUse.DashStyle = DashStyle.Dash; } if (!penCloned) { //This will prevent immutable modifications later if we delete or modify reachspecs without a full //graph redraw penToUse = (Pen)penToUse.Clone(); penCloned = true; } PathfindingEditorEdge edge = new PathfindingEditorEdge { Pen = penToUse, EndPoints = { [0] = this, [1] = othernode }, OutboundConnections = { [0] = true, [1] = isTwoWay } }; if (!Edges.Any(x => x.DoesEdgeConnectSameNodes(edge)) && !othernode.Edges.Any(x => x.DoesEdgeConnectSameNodes(edge))) { //Only add edge if neither node contains this edge Edges.Add(edge); othernode.Edges.Add(edge); g.edgeLayer.AddChild(edge); } } } } }
/// <summary> /// Renders a bond to the display /// </summary> public override void Render() { //set up the shared variables first Point startPoint = ParentBond.StartAtom.Position; Point endPoint = ParentBond.EndAtom.Position; double bondLength = ParentBond.Model.XamlBondLength; bool firstVisualExists = ChemicalVisuals.ContainsKey(ParentBond.StartAtom); bool secondVisualExists = ChemicalVisuals.ContainsKey(ParentBond.EndAtom); //bale out in case we have a null start or end or zero length bond if (startPoint != endPoint && firstVisualExists && secondVisualExists) { //now get the geometry of start and end atoms AtomVisual startVisual = (AtomVisual)ChemicalVisuals[ParentBond.StartAtom]; AtomVisual endVisual = (AtomVisual)ChemicalVisuals[ParentBond.EndAtom]; //first grab the main descriptor BondDescriptor = GetBondDescriptor(ParentBond, startVisual, endVisual, bondLength); _enclosingPoly = BondDescriptor.Boundary; //set up the default pens for rendering _mainBondPen = new Pen(Brushes.Black, BondThickness) { StartLineCap = PenLineCap.Round, EndLineCap = PenLineCap.Round, LineJoin = PenLineJoin.Miter }; _subsidiaryBondPen = _mainBondPen.Clone(); switch (ParentBond.Order) { case Globals.OrderZero: case Globals.OrderOther: case "unknown": // Handle Zero Bond _mainBondPen.DashStyle = DashStyles.Dot; using (DrawingContext dc = RenderOpen()) { dc.DrawGeometry(Brushes.Black, _mainBondPen, BondDescriptor.DefiningGeometry); //we need to draw another transparent rectangle to expand the bounding box DrawHitTestOverlay(dc); dc.Close(); } DoubleBondLayout dbd = new DoubleBondLayout { Start = startPoint, End = endPoint, Placement = ParentBond.Placement }; BondGeometry.GetDoubleBondPoints(dbd, bondLength); _enclosingPoly = dbd.Boundary; break; case Globals.OrderPartial01: _mainBondPen.DashStyle = DashStyles.Dash; using (DrawingContext dc = RenderOpen()) { dc.DrawGeometry(Brushes.Black, _mainBondPen, BondDescriptor.DefiningGeometry); //we need to draw another transparent thicker line on top of the existing one DrawHitTestOverlay(dc); dc.Close(); } //grab the enclosing polygon as for a double ParentBond - this overcomes a hit testing bug DoubleBondLayout dbd2 = new DoubleBondLayout { Start = startPoint, End = endPoint, Placement = ParentBond.Placement }; BondGeometry.GetDoubleBondPoints(dbd2, bondLength); _enclosingPoly = dbd2.Boundary; break; case "1": case Globals.OrderSingle: // Handle Single bond switch (ParentBond.Stereo) { case Globals.BondStereo.Indeterminate: case Globals.BondStereo.None: case Globals.BondStereo.Wedge: using (DrawingContext dc = RenderOpen()) { dc.DrawGeometry(Brushes.Black, _mainBondPen, BondDescriptor.DefiningGeometry); //we need to draw another transparent rectangle to expand the bounding box DrawHitTestOverlay(dc); dc.Close(); } break; case Globals.BondStereo.Hatch: using (DrawingContext dc = RenderOpen()) { dc.DrawGeometry(GetHatchBrush(ParentBond.Angle), _mainBondPen, BondDescriptor.DefiningGeometry); //we need to draw another transparent rectangle to expand the bounding box DrawHitTestOverlay(dc); dc.Close(); } break; } break; case Globals.OrderPartial12: case Globals.OrderAromatic: case "2": case Globals.OrderDouble: DoubleBondLayout dbd3 = (DoubleBondLayout)BondDescriptor; Point? centroid = ParentBond.Centroid; dbd3.PrimaryCentroid = centroid; if (ParentBond.Order == Globals.OrderPartial12 || ParentBond.Order == Globals.OrderAromatic ) // Handle 1.5 bond { _subsidiaryBondPen.DashStyle = DashStyles.Dash; } _enclosingPoly = dbd3.Boundary; if (ParentBond.Stereo != Globals.BondStereo.Indeterminate) { using (DrawingContext dc = RenderOpen()) { dc.DrawLine(_mainBondPen, BondDescriptor.Start, BondDescriptor.End); dc.DrawLine(_subsidiaryBondPen, dbd3.SecondaryStart, dbd3.SecondaryEnd); dc.Close(); } } else { using (DrawingContext dc = RenderOpen()) { dc.DrawGeometry(_mainBondPen.Brush, _mainBondPen, BondDescriptor.DefiningGeometry); dc.Close(); } } break; case Globals.OrderPartial23: case "3": case Globals.OrderTriple: if (ParentBond.Order == Globals.OrderPartial23) // Handle 2.5 bond { _subsidiaryBondPen.DashStyle = DashStyles.Dash; } var tbd = (BondDescriptor as TripleBondLayout); using (DrawingContext dc = RenderOpen()) { if (ParentBond.Placement == Globals.BondDirection.Clockwise) { dc.DrawLine(_mainBondPen, tbd.SecondaryStart, tbd.SecondaryEnd); dc.DrawLine(_mainBondPen, tbd.Start, tbd.End); dc.DrawLine(_subsidiaryBondPen, tbd.TertiaryStart, tbd.TertiaryEnd); } else { dc.DrawLine(_subsidiaryBondPen, tbd.SecondaryStart, tbd.SecondaryEnd); dc.DrawLine(_mainBondPen, tbd.Start, tbd.End); dc.DrawLine(_mainBondPen, tbd.TertiaryStart, tbd.TertiaryEnd); } dc.Close(); } break; } } //local function void DrawHitTestOverlay(DrawingContext dc) { SolidColorBrush outliner = new SolidColorBrush(Colors.Salmon); #if SHOWBOUNDS outliner.Opacity = 0.2d; #else outliner.Opacity = 0d; #endif Pen outlinePen = new Pen(outliner, BondThickness * 5); dc.DrawGeometry(outliner, outlinePen, BondDescriptor.DefiningGeometry); } }