DrawBeziers() public method

public DrawBeziers ( Pen pen, Point points ) : void
pen Pen
points Point
return void
Exemplo n.º 1
0
 internal override void Draw(Graphics g, Pen pen)
 {
     if (pointedBezier)
     {
         pen = new Pen(Color.Yellow, 1);
         g.DrawBeziers(pen, points);
         pen.Dispose();
     }
     else
         g.DrawBeziers(pen, points);
 }
Exemplo n.º 2
0
        public void DrawBeziers(Pen pen, PointD[] points)
        {
            if (pen == null)
            {
                throw new ArgumentNullException("pen");
            }
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            lock (bitmapLock) {
                double maxX = 0.0d;
                double maxY = 0.0d;

                for (long i = 0L; i < points.LongLength; i++)
                {
                    if (points[i].X > maxX)
                    {
                        maxX = points[i].X;
                    }
                    if (points[i].Y > maxY)
                    {
                        maxY = points[i].Y;
                    }
                }

                TryExpand(0.0d, 0.0d, maxX, maxY, pen.Width);
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap)) {
                    g.SmoothingMode = (Antialiasing) ? SmoothingMode.AntiAlias : SmoothingMode.None;
                    g.DrawBeziers(pen, ToPointFArray(points));
                }
                Texturize();
            }
        }
        /// <summary>
        /// Paints the polyline.
        /// </summary>
        /// <param name="g">Graphic context</param>
        /// <param name="p">Pen to use</param>
        protected override void PaintPolyline(Graphics g, Pen p)
        {
            if (From == null)
                return;
            if (To==null || ((this.Points.Count-4)%3!=0))
            {
                base.PaintPolyline(g,p);
                return;
            }

            // Get end points
            PointF s = From.Shape.ConnectionPoint(From);
            PointF e = To.Shape.ConnectionPoint(To);

            // Iterate the list of polyline points and paint the lines between them
            SmoothingMode m = g.SmoothingMode;
            g.SmoothingMode = SmoothingMode.HighQuality;

            PointF[] points = new PointF[this.Points.Count];
            this.Points.CopyTo(points,0);
            points[0]=s;
            points[points.Length-1]=e;

            g.DrawBeziers(p,points);
            g.SmoothingMode = m;

            // draw label
            if (label!=null && this.label.Length!=0)
            {
                PointF middle = (PointF)this.Points[this.Points.Count/2];
                SolidBrush labelBrush = new SolidBrush(this.LabelColor);
                g.DrawString(this.label,this.labelFont,labelBrush,middle);
            }
        }
 public override void Draw(Graphics g)
 {
     using(Pen p = new Pen(penColor,penWidth))
     {
         g.DrawBeziers(p,pointlist);
     }
 }
        /// <summary>
        /// Draw the disc flight.
        /// 
        /// Currently simply a straight line from A to B. Could enhance this so
        /// that it draws a cardinal spline instead at some point. The UI to draw
        /// that is the more difficult area.
        /// </summary>
        /// <param name="display"></param>
        /// <param name="startLocation"></param>
        /// <param name="controlPoint"></param>
        /// <param name="endLocation"></param>
        /// <param name="converter"></param>
        private void DrawDiscFlight(Graphics display,
                                PointF startLocation,
                                PointF controlPoint,
                                PointF endLocation,
                                PitchScreenCoordConverter converter)
        {
            Point screenCoordsStart = converter.pitchToScreenCoords(startLocation);
              Point screenCoordsEnd = converter.pitchToScreenCoords(endLocation);
              Point screenControlPoint = converter.pitchToScreenCoords(controlPoint);

              QuadraticBezierCurve curve = new QuadraticBezierCurve(screenCoordsStart,
                                                            screenControlPoint,
                                                            screenCoordsEnd);

              display.DrawBeziers(mDiscFlightPen, curve.ToCubic());

              display.DrawRectangle(mDiscFlightPen,
                            screenControlPoint.X - 1,
                            screenControlPoint.Y - 1,
                            2, 2);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Repaints the form with cool background and stuff
        /// </summary>
        /// <param name="graph">The graphics object to paint to, the element will be drawn to 0, 0</param>
        public override void Paint(Graphics graph)
        {
            //Draws Rectangular Shapes
            if (Shape == ModelShape.Arrow)
            {
                _arrowPath = new GraphicsPath();

                //Draws the basic shape
                Pen arrowPen;
                if (Highlight < 1)
                    arrowPen = new Pen(Color.Cyan, 3F);
                else
                    arrowPen = new Pen(Color.Black, 3F);

                //Draws the curved arrow
                Point[] lineArray = new Point[4];
                lineArray[0] = new Point(_startPoint.X, _startPoint.Y);
                lineArray[1] = new Point(_startPoint.X - ((_startPoint.X - _stopPoint.X) / 3), _startPoint.Y);
                lineArray[2] = new Point(_stopPoint.X - ((_stopPoint.X - _startPoint.X) / 3), _stopPoint.Y);
                lineArray[3] = new Point(_stopPoint.X, _stopPoint.Y);
                graph.DrawBeziers(arrowPen, lineArray);
                _arrowPath.AddBeziers(lineArray);
                _arrowPath.Flatten();

                //Draws the arrow head
                Point[] arrowArray = new Point[3];
                arrowArray[0] = _stopPoint;
                arrowArray[1] = new Point(_stopPoint.X - (5 * Math.Sign(_stopPoint.X - _startPoint.X)), _stopPoint.Y - 2);
                arrowArray[2] = new Point(_stopPoint.X - (5 * Math.Sign(_stopPoint.X - _startPoint.X)), _stopPoint.Y + 2);
                graph.DrawPolygon(arrowPen, arrowArray);

                //Garbage collection
                arrowPen.Dispose();
            }
        }
Exemplo n.º 7
0
 public void DrawEllipse(Graphics g, RectangleD worldRect, Rectangle canvasRect,
     BrushesStorage brushStorage, PenStorage penStorage, Font font)
 {
     const int markerSize = 3;
     var pen = penStorage.GetPen(Color, Selected ? 3f : 1f);
     var screenPoints = new List<PointD>();
     foreach (var pt in points)
     {
         screenPoints.Add(Conversion.WorldToScreen(new PointD(pt.X, pt.Y),
                                                     worldRect, canvasRect));
     }
     foreach (var pt in screenPoints)
     {
         g.DrawRectangle(pen, (float)pt.X - markerSize, (float)pt.Y - markerSize,
                         markerSize * 2F, markerSize * 2F);
     }
     if (screenPoints.Count == 2)
     {
         g.DrawLine(pen, screenPoints[0].ToPointF(), screenPoints[1].ToPointF());
     }
     if (screenPoints.Count == 3)
     {
         // нарисовать собственно эллипс
         double newAngle;
         float newCx, newCy, newA, newB;
         correctEllipse = Geometry.GetEllipseParams(screenPoints[0].ToPointF(),
                                                         screenPoints[1].ToPointF(),
                                                         screenPoints[2].ToPointF(),
                                                         out newAngle, out newA, out newB, out newCx, out newCy);
         if (correctEllipse) // можно построить эллипс - рисуем его
         {
             a = newA;
             b = newB;
             angle = newAngle;
             cx = newCx;
             cy = newCy;
             var ellipseBezierPoints = Geometry.GetEllipseBezierPoints(newAngle, newA, newB, newCx, newCy);
             g.DrawBeziers(pen, ellipseBezierPoints);
             if (BrushAlpha > 0)
             {
                 var brush = brushStorage.GetBrush(Color.FromArgb(BrushAlpha, BrushColor));
                 g.FillClosedCurve(brush, ellipseBezierPoints);
             }
             // строить касательную
             if (BuildTangent)
                 DrawTangent(screenPoints, canvasRect, g,
                     penStorage, brushStorage, font);
         }
         else // построить эллипс по указанным координатам невозможно
         {
             g.DrawLine(pen, screenPoints[1].ToPointF(), screenPoints[2].ToPointF());
             g.DrawLine(pen, screenPoints[0].ToPointF(), screenPoints[2].ToPointF());
         }
     }
     // маркеры
     if (Selected)
         DrawComments(g, worldRect, canvasRect, penStorage, brushStorage);
 }
Exemplo n.º 8
0
        public List<double> Spokes { get; set; }    // the angles of the spokes, in radians


        //public double R { get { return TheShape.R; } set { TheShape.R = value; } }
        //public Point Center { get { return TheShape.Center; } set { TheShape.Center = value; } }
        //public List<double> Spokes { get { return TheShape.Spokes; } set { TheShape.Spokes = value; } }    // the angles of the spokes, in radians

        /// <summary>
        /// Draw an arc
        /// </summary>
        /// <param name="dc"></param>
        public override void Draw(Graphics dc)
        {
            if (R == 0 || Spokes == null || Spokes.Count < 2 || ThePen == null)
                return;

            dc.DrawLine(ThePen, Center.ToPointF(), spokep(0));

            for (int i = 1; i < Spokes.Count; i++)
            {
                if (Math.Abs(Spokes[i] - Spokes[i - 1]) > 2 * Math.PI - .001)
                {
                    // Display a circle
                    double ControlPointRatio = (Math.Sqrt(2) - 1) * 4 / 3;

                    var x0 = (float)(Center.X - R);
                    var x1 = (float)(Center.X - R * ControlPointRatio);
                    var x2 = (float)(Center.X);
                    var x3 = (float)(Center.X + R * ControlPointRatio);
                    var x4 = (float)(Center.X + R);

                    var y0 = (float)( Center.Y - R);
                    var y1 = (float)(Center.Y - R * ControlPointRatio);
                    var y2 = (float)(Center.Y);
                    var y3 = (float)(Center.Y + R * ControlPointRatio);
                    var y4 = (float)(Center.Y + R);

                    PointF[] pts = new PointF[] { new PointF(x2, y0), new PointF(x3, y0), new PointF(x4, y1), 
                        new PointF(x4, y2), new PointF(x1, y4), new PointF(x0, y3), new PointF(x0, y2),
                        new PointF(x0, y1), new PointF(x1, y0), new PointF(x2, y0) };

                    dc.DrawBeziers(ThePen, pts);

                    /* context.BeginFigure(new Point(x2, y0), true, true);
                    context.BezierTo(new Point(x3, y0), new Point(x4, y1), new Point(x4, y2), true, true);
                    context.BezierTo(new Point(x4, y3), new Point(x3, y4), new Point(x2, y4), true, true);
                    context.BezierTo(new Point(x1, y4), new Point(x0, y3), new Point(x0, y2), true, true);
                    context.BezierTo(new Point(x0, y1), new Point(x1, y0), new Point(x2, y0), true, true); */

                }
                else
                {
                    bool largearc = Math.Abs(Spokes[i] - Spokes[i - 1]) > Math.PI;
                   /* SweepDirection sd = SweepDirection.Counterclockwise;
                    if (Spokes[i] < Spokes[i - 1])
                        sd = SweepDirection.Clockwise;

                    dc.DrawArc(ThePen, (float)Center.X, (float(Center.Y), (float)R, (float)R, )
                    context.ArcTo(spokep(i), new Size(R, R), 0, largearc, sd, true, false);*/
                    //TODO:support
                }

                dc.DrawLine(ThePen, Center.ToPointF(), spokep(i));

            }
        }
Exemplo n.º 9
0
            public void Draw(Graphics g, System.Drawing.Color color)
            {
                switch (kind) {
                    case SymbolStrokes.Disc:
                        using (Brush b = new SolidBrush(color))
                            g.FillEllipse(b, new RectangleF(points[0].X - radius, points[0].Y - radius, radius * 2, radius * 2));
                        break;

                    case SymbolStrokes.Circle:
                        try {
                            using (Pen p = new Pen(color, thickness))
                                g.DrawEllipse(p, new RectangleF(points[0].X - radius, points[0].Y - radius, radius * 2, radius * 2));
                        }
                        catch (ExternalException) {
                            // Ignore this exeption. Not sure what causes it.
                        }

                        break;

                    case SymbolStrokes.Polyline:
                        using (Pen p = new Pen(color, thickness)) {
                            p.LineJoin = corners;
                            p.StartCap = ends;
                            p.EndCap = ends;
                            g.DrawLines(p, points);
                        }
                        break;

                    case SymbolStrokes.Polygon:
                        using (Pen p = new Pen(color, thickness)) {
                            p.LineJoin = corners;
                            g.DrawPolygon(p, points);
                        }
                        break;

                    case SymbolStrokes.FilledPolygon:
                        using (Brush b = new SolidBrush(color))
                            g.FillPolygon(b, points);
                        break;

                    case SymbolStrokes.PolyBezier:
                        using (Pen p = new Pen(color, thickness)) {
                            p.StartCap = ends;
                            p.EndCap = ends;
                            g.DrawBeziers(p, points);
                        }
                        break;

                    case SymbolStrokes.FilledPolyBezier:
                        using (Brush b = new SolidBrush(color))
                        using (GraphicsPath path = new GraphicsPath()) {
                            path.AddBeziers(points);
                            g.FillPath(b, path);
                        }
                        break;

                    default:
                        Debug.Fail("Bad SymbolStroke kind");
                        break;
                }
            }
Exemplo n.º 10
0
        private void DrawSegmentConnector(Graphics g, int segmentStartIndex, int segmentEndIndex, float weight)
        {
            PointF[] endB = GetBezierPoints(segmentEndIndex, Offset.Bottom);
            PointF[] startB = GetBezierPoints(segmentStartIndex, Offset.Top);
            GraphicsPath gp = new GraphicsPath();

            gp.StartFigure();
            gp.AddLine(startB[0], endB[0]);
            gp.AddBezier(endB[0], endB[1], endB[2], endB[3]);
            gp.AddLine(endB[3], startB[3]);
            gp.AddBezier(startB[3], startB[2], startB[1], startB[0]);
            gp.CloseFigure();

            gp.StartFigure();
            gp.AddRectangle(new RectangleF(startB[3], new SizeF(_overviewRectangle.Width, endB[3].Y - startB[3].Y)));
            gp.CloseFigure();

            Color background = ColorUtilities.Interpolate(Settings.Default.OverviewBackgroundColor, Settings.Default.ConnectorsColor, 0.2f);
            Color color = ColorUtilities.Interpolate(background, Settings.Default.ConnectorsColor, weight);

            g.FillPath( new SolidBrush(color), gp);

            if (Model.Default.SelectedLine != -1 && Model.Default.SelectedLine >= segmentStartIndex && Model.Default.SelectedLine <= segmentEndIndex)
            {
                g.DrawBeziers(_selectedPen, GetBezierPoints(Model.Default.SelectedLine, Offset.Middle));
                int y = TransformToScaled(Model.Default.SelectedLine);
                g.DrawLine(_selectedPen, _overviewRectangle.X, y, this.Width, y);
            }

        }
Exemplo n.º 11
0
        public void DrawSwitches(Graphics g, Pen switchPen, Pen switchOutline, Font f, StringFormat sf, string label, bool drawHandles,
            PointF start, PointF control1, PointF control2, PointF end, PointF labelLoc)
        {
            PointF[] bezier = new [] {start, control1, control2, end};

            g.DrawBeziers(switchOutline, bezier);
            g.DrawBeziers(switchPen, bezier);

            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddString(label, f.FontFamily, (int) f.Style, f.GetHeight(g), labelLoc, sf);

                g.DrawPath(switchOutline, gp);
                g.FillPath(Brushes.Black, gp);
            }

            if (!drawHandles) return;

            DrawBezierHandle(g, start, control1);
            DrawBezierHandle(g, end, control2);
        }
Exemplo n.º 12
0
		// ************ drawing ************

		internal void drawArrowSegments(Graphics g,
			System.Drawing.Pen p, System.Drawing.Brush b,
			System.Drawing.Pen pHeads, bool shadow, bool custom)
		{
			PointCollection pts = points;
			float xoff = shadow ? ShadowOffsetX : 0;
			float yoff = shadow ? ShadowOffsetY : 0;

			// offset if drawing shadow
			if (shadow)
			{
				pts = new PointCollection(points.Count);
				for (int i = 0; i < pts.Count; ++i)
				{
					pts[i] = new PointF(
						points[i].X + xoff, points[i].Y + yoff);
				}
			}

			if (custom && (customDraw == CustomDraw.Full ||
				(customDraw == CustomDraw.ShadowOnly && shadow)))
			{
				// call the custom draw function
				flowChart.drawArrow(g, this, shadow, pts);
			}
			else
			{
				// draw the arrow's line
				if (style == ArrowStyle.Bezier)
				{
					g.DrawBeziers(p, pts.getArray());
				}
				else
				{
					float mm = Constants.getMillimeter(flowChart.MeasureUnit);
					float pathThresh = mm / 3;
					if (!drawCrossings || flowChart.ArrowCrossings ==
						MindFusion.FlowChartX.ArrowCrossings.Straight)
					{
						if (flowChart.RoundedArrows)
						{
							DrawRoundedPolyline(g, p, pts.getArray(),
								flowChart.RoundedArrowsRadius, true, pathThresh, null);
						}
						else
						{
							g.DrawLines(p, pts.getArray());
						}
					}
					else
					{
						float crad = flowChart.CrossingRadius;

						ArrowCrossings crossings = getCrossings();
						object startPoint = null;

						GraphicsPath gpath = pen.Width > pathThresh ?
							new GraphicsPath() : null;

						for (int i = 0; i < segmentCount; ++i)
						{
							PointCollection pc = crossings.segmentCrossings[i] as PointCollection;
							if (pc.Count > 0)
							{
								for (int j = 0; j < pc.Count - 1; ++j)
								{
									PointF pt1 = pc[j];
									PointF pt2 = pc[j + 1];
									pt1.X += xoff; pt1.Y += yoff;
									pt2.X += xoff; pt2.Y += yoff;

									if (startPoint != null)
										pt1 = (PointF)startPoint;

									startPoint = null;

									if (j % 2 == 0)
									{
										// The subsegment between two crossings or
										// between a crossing and a segment end-point
										if (flowChart.RoundedArrows)
										{
											// Check if this is the last subsegment
											// in this segment. If that is the case,
											// and this is not the last segment of the
											// arrow, draw rounded arrow
											if (j == pc.Count - 2 && i != segmentCount - 1)
											{
												// The third point in the poly is
												// the second point of the next segment
												// if it does not have crossings, or
												// the second point of the crossings array
												int ni = i + 2;
												PointF next = pts[ni];
												while (Math.Abs(next.X - pt2.X) + Math.Abs(next.Y - pt2.Y) < 0.00001f)
												{
													ni++;
													if (ni == pts.Count)
														break;

													next = pts[ni];
												}

												if (ni == pts.Count)
												{
													if (gpath != null)
														gpath.AddLine(pt1, pt2);
													else
														g.DrawLine(p, pt1, pt2);
												}
												else
												{
													PointCollection nextPc = crossings.segmentCrossings[ni - 1] as PointCollection;
													if (nextPc.Count > 2)
													{
														next = nextPc[1];
														next.X += xoff;
														next.Y += yoff;
													}

													PointF[] triPoints = new PointF[]
												{
													pt1, pt2, next
												};

													startPoint = DrawRoundedPolyline(g, p, triPoints,
														flowChart.RoundedArrowsRadius, false, pathThresh, gpath);
												}
											}
											else
											{
												if (gpath != null)
													gpath.AddLine(pt1, pt2);
												else
													g.DrawLine(p, pt1, pt2);
											}
										}
										else
										{
											if (gpath != null)
												gpath.AddLine(pt1, pt2);
											else
												g.DrawLine(p, pt1, pt2);
										}
									}
									else
									{
										if (flowChart.ArrowCrossings ==
											MindFusion.FlowChartX.ArrowCrossings.Arcs)
										{
											float rad = Utilities.Distance(pt1, pt2) / 2;

											float aa = 0;
											float rr = 0;
											Geometry.Geometry2D.Convert.DekartToPolar(
												pt1, pt2, ref aa, ref rr);

											PointF[] centers = new PointF[] { PointF.Empty, PointF.Empty };
											Geometry.Geometry2D.Convert.PolarToDekart(
												pt1, aa, crad, ref centers[0]);
											Geometry.Geometry2D.Convert.PolarToDekart(
												pt1, aa, 2 * rad - crad, ref centers[1]);

											PointF[] startPts = new PointF[] { pt1, PointF.Empty };
											PointF[] endPts = new PointF[] { PointF.Empty, pt2 };
											Geometry.Geometry2D.Convert.PolarToDekart(
												pt1, aa, 2 * crad, ref endPts[0]);
											Geometry.Geometry2D.Convert.PolarToDekart(
												pt1, aa, 2 * rad - 2 * crad, ref startPts[1]);

											float angle = aa;
											if (angle < 90)
												angle += 180;

											RectangleF rc = RectangleF.FromLTRB(
												centers[0].X - crad,
												centers[0].Y - crad,
												centers[0].X + crad,
												centers[0].Y + crad);

											float ded = 0 * 90;
											if (aa < 90)
												ded = 90 - ded;

											float start = 180 - angle - ded;
											float sweep = -90;
											if (aa < 90)
											{
												start += sweep;
												sweep = -sweep;
											}

											if (gpath != null)
												gpath.AddArc(rc, start, sweep);
											else
												g.DrawArc(p, rc, start, sweep);

											PointF p1 = PointF.Empty;
											PointF p2 = PointF.Empty;
											Geometry.Geometry2D.Convert.PolarToDekart(
												centers[0], angle - 90, crad, ref p1);
											Geometry.Geometry2D.Convert.PolarToDekart(
												centers[1], angle - 90, crad, ref p2);

											if (gpath != null)
												gpath.AddLine(p1, p2);
											else
												g.DrawLine(p, p1, p2);

											rc = RectangleF.FromLTRB(
												centers[1].X - crad,
												centers[1].Y - crad,
												centers[1].X + crad,
												centers[1].Y + crad);

											ded = 1 * 90;
											if (aa < 90)
												ded = 90 - ded;

											start = 180 - angle - ded;
											sweep = -90;
											if (aa < 90)
											{
												start += sweep;
												sweep = -sweep;
											}

											if (gpath != null)
												gpath.AddArc(rc, start, sweep);
											else
												g.DrawArc(p, rc, start, sweep);

										}
										else
										{
											// Start new figure in the graph,
											// thus preventing the graph
											// to automatically connect broken
											// lines and losing break-offs
											if (gpath != null)
												gpath.StartFigure();
										}
									}
								}
							}
							else
							{
								if (gpath != null)
									gpath.AddLine(pts[i], pts[i+1]);
								else
									g.DrawLine(p, pts[i], pts[i+1]);
							}
						}

						if (gpath != null)
						{
							gpath.Flatten(new Matrix(), 0.05f);
							g.DrawPath(p, gpath);
							gpath.Dispose();
						}
					}
				}

				// draw arrowheads, intermediate are skipped for asBezier arrows
				ahBase.draw(g, pHeads, b, xoff, yoff);
				if (style != ArrowStyle.Bezier && arrowInterm != ArrowHead.None)
				{
					for (int i = 0; i < points.Count - 1; i++)
					{
						PointF pt1 = pts[i];
						PointF pt2 = new PointF((pt1.X + pts[i+1].X)/2, (pt1.Y + pts[i+1].Y)/2);
					
						headTemplates[(int)arrowInterm].recalcArrowHead(ahInterm, pt1, pt2);
						ahInterm.draw(g, pHeads, b, 0, 0);
					}
				}
				ahHead.draw(g, pHeads, b, xoff, yoff);

				// additional custom draw type
				if (custom && customDraw == CustomDraw.Additional)
					flowChart.drawArrow(g, this, false, pts);
			}
		}
Exemplo n.º 13
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			PointF[] subLinePoints;
			if (range.LowerBound == 0 && range.UpperBound == allLinePoints.Length)
			{
				// under optimal conditions we can use allLinePoints directly
				subLinePoints = allLinePoints;
			}
			else
			{
				// otherwise, make a new array
				subLinePoints = new PointF[range.Length];
				Array.Copy(allLinePoints, range.LowerBound, subLinePoints, 0, range.Length); // Extract
			}

			int lastIdx = range.Length - 1;
			var layerSize = layer.Size;

			if (connectCircular)
			{
				if (symbolGap != null)
				{
					// convert points to bezier segments
					var bezierSegments = GdiExtensionMethods.ClosedCardinalSplineToBezierSegments(subLinePoints, subLinePoints.Length);
					var subBezierSegments = new PointF[0];
					int subPointLengthM1, subBezierLength;
					for (int i = 0; i < (range.Length); i += skipFrequency)
					{
						subPointLengthM1 = Math.Min(skipFrequency, range.Length - i);
						int originalIndexAtStart = range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound);
						double gapAtStart = symbolGap(originalIndexAtStart);
						int originalIndexAtEnd = ((i + skipFrequency) < range.Length) ? range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound + skipFrequency) : range.OriginalFirstPoint;
						double gapAtEnd = symbolGap(originalIndexAtEnd);
						subBezierLength = 3 * subPointLengthM1 + 1;
						if (subBezierSegments.Length != subBezierLength)
							subBezierSegments = new PointF[subBezierLength];

						Array.Copy(bezierSegments, i * 3, subBezierSegments, 0, subBezierLength);
						var shortenedBezierSegments = GdiExtensionMethods.ShortenBezierCurve(subBezierSegments, gapAtStart / 2, gapAtEnd / 2);

						if (null != shortenedBezierSegments)
						{
							g.DrawBeziers(linePen, shortenedBezierSegments);
						}
					}
				}
				else
				{
					g.DrawClosedCurve(linePen, subLinePoints);
				}
			}
			else
			{
				if (symbolGap != null)
				{
					// convert points to bezier segments
					var bezierSegments = GdiExtensionMethods.OpenCardinalSplineToBezierSegments(subLinePoints, subLinePoints.Length);
					var subBezierSegments = new PointF[0];
					int subPointLengthM1, subBezierLength;
					for (int i = 0; i < (range.Length - 1); i += skipFrequency)
					{
						subPointLengthM1 = Math.Min(skipFrequency, range.Length - 1 - i);
						int originalIndex = range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound);
						double gapAtStart = symbolGap(originalIndex);
						double gapAtEnd = subPointLengthM1 == skipFrequency ? symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound + skipFrequency)) : 0;
						subBezierLength = 3 * subPointLengthM1 + 1;
						if (subBezierSegments.Length != subBezierLength)
							subBezierSegments = new PointF[subBezierLength];

						Array.Copy(bezierSegments, i * 3, subBezierSegments, 0, subBezierLength);
						var shortenedBezierSegments = GdiExtensionMethods.ShortenBezierCurve(subBezierSegments, gapAtStart / 2, gapAtEnd / 2);

						if (null != shortenedBezierSegments)
						{
							g.DrawBeziers(linePen, shortenedBezierSegments);
						}
					}
				}
				else
				{
					g.DrawCurve(linePen, subLinePoints);
				}
			}
		}
Exemplo n.º 14
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			// Bezier is only supported with point numbers n=4+3*k
			// so trim the range appropriately
			if (range.Length < 4)
				return; // then too less points are in this range

			if (connectCircular)
			{
				var circularLinePointsLengthM1 = 2 + TrimToValidBezierLength(range.Length);
				var circularLinePoints = new PointF[circularLinePointsLengthM1 + 1];
				Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length); // Extract
				circularLinePoints[circularLinePointsLengthM1] = circularLinePoints[0];

				// amend missing control points
				if (circularLinePointsLengthM1 - range.Length >= 1)
					circularLinePoints[circularLinePointsLengthM1 - 1] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Last Control point should be halfway between
				if (circularLinePointsLengthM1 - range.Length >= 2)
					circularLinePoints[circularLinePointsLengthM1 - 2] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Middle Control point should be halfway between previous fixed point and last(=first) fixed point

				if (null != symbolGap) // circular with symbol gap
				{
					var realSkipFrequency = skipFrequency % 3 == 0 ? skipFrequency : skipFrequency * 3; // least common multiple of skipFrequency and 3
					for (int i = 0; i < range.Length; i += realSkipFrequency)
					{
						var skipLinePointsLength = Math.Min(realSkipFrequency + 1, TrimToValidBezierLength(circularLinePoints.Length - i));
						if (skipLinePointsLength >= 4)
						{
							var skipLinePoints = new PointF[skipLinePointsLength];
							Array.Copy(circularLinePoints, i, skipLinePoints, 0, skipLinePointsLength); // Extract

							var gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
							double gapAtEnd;
							if (connectCircular && realSkipFrequency >= (range.Length - 1 - i))
								gapAtEnd = symbolGap(range.OriginalFirstPoint);
							else if (realSkipFrequency <= (range.Length - 1 - i))
								gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + realSkipFrequency));
							else
								gapAtEnd = 0;

							if (gapAtStart != 0 || gapAtEnd != 0)
							{
								skipLinePoints = GdiExtensionMethods.ShortenBezierCurve(skipLinePoints, gapAtStart / 2, gapAtEnd / 2);
							}

							if (null != skipLinePoints)
							{
								g.DrawBeziers(linePen, skipLinePoints);
							}
						}
					}
				}
				else // circular without symbol gap
				{
					g.DrawBeziers(linePen, circularLinePoints);
				}
			}
			else // not circular
			{
				if (null != symbolGap) // not circular with symbol gap
				{
					var realSkipFrequency = skipFrequency % 3 == 0 ? skipFrequency : skipFrequency * 3; // least common multiple of skipFrequency and 3
					for (int i = 0; i < range.Length; i += realSkipFrequency)
					{
						var skipLinePointsLength = Math.Min(realSkipFrequency + 1, TrimToValidBezierLength(range.Length - i));
						if (skipLinePointsLength >= 4)
						{
							var skipLinePoints = new PointF[skipLinePointsLength];
							Array.Copy(allLinePoints, range.LowerBound + i, skipLinePoints, 0, skipLinePointsLength); // Extract

							var gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
							var gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + skipLinePointsLength - 1));

							if (gapAtStart != 0 || gapAtEnd != 0)
							{
								skipLinePoints = GdiExtensionMethods.ShortenBezierCurve(skipLinePoints, gapAtStart / 2, gapAtEnd / 2);
							}

							if (null != skipLinePoints)
							{
								g.DrawBeziers(linePen, skipLinePoints);
							}
						}
					}
				}
				else // not circular without symbol gap
				{
					var trimmedLength = TrimToValidBezierLength(range.Length);
					var subLinePoints = new PointF[trimmedLength];
					Array.Copy(allLinePoints, range.LowerBound, subLinePoints, 0, trimmedLength); // Extract
					g.DrawBeziers(linePen, subLinePoints);
				}
			}
		}