I want to increase the height of the curve but its left and right position should remain same. Just want to lift up from center to give it a shape like curve as height changes.
Pen blackPen = new Pen(Color.Black, 3);
// Create coordinates of rectangle to bound ellipse.
int x = 93;
int y = 136;
int width = 320;
int height = 50;
// Create start and sweep angles on ellipse.
int startAngle = 0;
int sweepAngle = -180;
// Draw arc to screen.
e.Graphics.DrawArc(blackPen, x, y, width, height, startAngle, sweepAngle);
In the most direct way your problem can be solved like this:
int change = 0;
e.Graphics.DrawArc(blackPen, x, y-change, width, height+change, startAngle, sweepAngle);
By increasing the variable change the ellipse will curve up more and more:
private void button1_Click(object sender, EventArgs e)
{
change += 10;
panel1.Invalidate();
}
But maybe you want more control over the shape? Let's have a look at the options:
Here are examples of the three 'curve' drawing methods:
Curves, Beziers & Ellipses
And here is the code to draw that image.
Please ignore the Graphics.xxxTransform calls! They only are meant to shift the curves a little bit upwards so they don't overlap too much to see them properly.
Also note that the curves in the first image are not completely convex. See the last part of the answer to see a DrawCurve call that avoids the concave segments!
The important part are the Points! And just as the comments suggest, in the third part the ellipses are being changed by making the height larger and moving the top of the Rectangle up by the same amount.
The complexity DrawArc of and DrawCurve is pretty much equal; both are controlled by four integers with a rather clear meaning: They either make one rectangle or the corners of a symmetrical triangle. (Plus one counterpoint for the convex call.)
DrawBezier is more complex, especially since the controls point(s) are not actually on the resulting curve. They can be thought of force vectors that pull the line into a curved shape and are harder to calculate.
private void panel1_Paint(object sender, PaintEventArgs e)
{
Point a = new Point(0, 200);
Point c = new Point(200, 200);
for (int i = 0; i< 10; i++)
{
e.Graphics.TranslateTransform(0, -5);
Point b = new Point(100, 50 + i * 10);
e.Graphics.DrawCurve(Pens.Maroon, new[] { a, b, c }, 0.7f);
}
e.Graphics.ResetTransform();
Point pa = new Point(250, 200);
Point pb = new Point(450, 200);
for (int i = 0; i < 10; i++)
{
e.Graphics.TranslateTransform(0, -5);
Point pc = new Point(350, 200 - i * 10);
e.Graphics.DrawBezier(Pens.ForestGreen, pa, pc, pc, pb);
}
e.Graphics.ResetTransform();
int x = 500;
int y0 = 200;
int w = 200;
for (int i = 0; i < 10; i++)
{
e.Graphics.TranslateTransform(0, -5);
Rectangle rect = new Rectangle(x, y0 - i * 10, w, 10 + i * 10);
e.Graphics.DrawArc(Pens.DarkBlue, rect, -0, -180);
}
e.Graphics.ResetTransform();
}
Notes:
The Curve (1st image) can be further controlled by the Tension parameter. The lower the tension the more pointed it gets, approaching 1f it makes the curve broader..
The Bezier curve (2nd image) is using only one control point. (Twice.) The curve gets a little pointed this way. You can make it broader and broader by using two different points the move apart little by little..
The Ellipse can't be controlled; it will always fill the bounding Rectangle.
Here is an example of varying the Curves and the Beziers:
The Curves are drawn with varying Tensions. Also I have used an overload that helps to get rid of the concave part at the start and end of the curve. The trick is to add a suitable extra point to the start and end and to tell the DrawCurve to leave out these 1st and last segments.
The simplest point to use (for both ends actually) is the counterpoint of the one at the top.
The Beziers are drawn using two control points, moving out and up a little.
Here is the code for the variations:
Point a = new Point(0, 200);
Point c = new Point(200, 200);
for (int i = 1; i < 10; i++)
{
e.Graphics.TranslateTransform(0, -5);
Point b = new Point(100, 50);
Point b0 = new Point(b.X, a.Y + (a.Y - b.Y));
e.Graphics.DrawCurve(Pens.Maroon, new[] { b0, a, b, c, b0 }, 1, 2, 0.1f * i);
}
e.Graphics.ResetTransform();
Point pa = new Point(250, 200);
Point pb = new Point(450, 200);
for (int i = 0; i < 10; i++)
{
e.Graphics.TranslateTransform(0, -5);
Point ca = new Point(350 - i * 9, 100 - i * 5);
Point cb = new Point(350 + i * 9, 100 - i * 5);
e.Graphics.DrawBezier(Pens.ForestGreen, pa, ca, cb, pb);
}
e.Graphics.ResetTransform();
here was the solution just increase value of y0 as u increase the value of
y0-i here i=20
int x = 96;
int y0 = 260;
int w = 320;
e.Graphics.TranslateTransform(0, -5);
Rectangle rect = new Rectangle(x, y0 - 20 * 10, w, 10 + 20 * 10);
e.Graphics.DrawArc(Pens.DarkBlue, rect, -0, -180);
e.Graphics.ResetTransform();
Related
I would like to draw a thick, transparent arrow with an arrowhead:
Here's the code that draws the arrow shaft. Notice that I have to offset the rectangle so the calculations are done from the midpoint of the rectangle.
private void DrawMovementArrow(bool color, double StartX, double StartY, double EndX, double EndY)
{
SolidColorBrush partiallyTransparentSolidColorBrush;
Rectangle myRectangle = new Rectangle();
// This will be replaced by piece size
int width = 35;
myRectangle.Width = width;
// Apparently necessary to offset the drawing of the path so that the point is in the center of the path; not the edge.
StartX -= width / 2;
EndX -= width / 2;
myRectangle.Height = Map.EuclideanDistance(StartX, StartY, EndX, EndY) ;
int angle = CalculateAngle(StartX , StartY , EndX , EndY );
// This selects the midpoint of edge of the rectangle to rotate around (weird system)
myRectangle.RenderTransformOrigin = new Point(0.5, 0);
angle = angle - 180;
RotateTransform rotateTransform1 = new RotateTransform(angle, 0 , 0 );
myRectangle.RenderTransform = rotateTransform1;
if (color)
partiallyTransparentSolidColorBrush = new SolidColorBrush(Colors.Blue);
else
partiallyTransparentSolidColorBrush = new SolidColorBrush(Colors.Red);
partiallyTransparentSolidColorBrush.Opacity = 0.4;
myRectangle.Fill = partiallyTransparentSolidColorBrush;
MovementCanvas1.Children.Clear();
MovementCanvas1.Children.Add(myRectangle);
Canvas.SetTop(myRectangle, StartY);
Canvas.SetLeft(myRectangle, StartX);
DrawArrowhead(color, EndX, EndY, angle + 90, width);
ShowUnitCenter(MovementArrowList[0]);
}
Note that this code selects a point in the middle of the edge to rotate the rectangle:
// This selects the midpoint of edge of the rectangle to rotate around (weird system)
myRectangle.RenderTransformOrigin = new Point(0.5, 0);
The problem is that I can't find that point with the arrowhead (triangle). Here's the code that draws the arrowhead:
public void DrawArrowhead(bool color, double x, double y, int angle, int width)
{
x += width /2 ;
width = width + (width / 2);
//Add the Polygon Element
Polygon myPolygon = new Polygon();
myPolygon.Opacity = 0.4;
if (color)
{
myPolygon.Fill = new SolidColorBrush(Colors.Blue);
myPolygon.Stroke = System.Windows.Media.Brushes.Blue;
}
else
{
myPolygon.Fill = new SolidColorBrush(Colors.Red);
myPolygon.Stroke = System.Windows.Media.Brushes.Red;
}
myPolygon.StrokeThickness = 0;
RotateTransform rotateTransform1 = new RotateTransform(angle, 0, 0);
myPolygon.RenderTransform = rotateTransform1;
// This selects the midpoint of edge of the triangle to rotate around (weird system)
myPolygon.RenderTransformOrigin = new Point(0.0, 0.5);
System.Windows.Point Point1 = new System.Windows.Point(0, 0);
System.Windows.Point Point2 = new System.Windows.Point(width / 2, width / 2);
System.Windows.Point Point3 = new System.Windows.Point(0,width);
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(Point1);
myPointCollection.Add(Point2);
myPointCollection.Add(Point3);
myPolygon.Points = myPointCollection;
MovementCanvas1.Children.Add(myPolygon);
Canvas.SetTop(myPolygon, y );
Canvas.SetLeft(myPolygon, x );
}
Note the myPointCollection that creates the triangle. The problem is that I've tried almost every conceivable combination of values in RenderTransformOrigin to find the point that (center bottom of triangle) to use for the rotation point. Nothing seems to be working out.
Can anybody suggest the correct value?
Edit Solved
I solved it by changing the points of the triangle. That was easier than trying to figure out the rotation point.
Changing the points that made up the triangle solved the problem. This was easier than trying to find the rotation point.
Basically i have a windows form that user will be able to draw different shapes(e.g square, circle and triangle), user will be able to highlight any of these shapes after drawing and then control that highlighted shape by moving or rotating it, i don't know how to rotate the shape. any one can help, this is my code (only to draw a square)
PS: user need to click twice on the form to draw the shape between those 2 points as shown below also i know i should be using onPaint method but this is the requirements of the task
Thanks
public Square(Point keyPt, Point oppPt) // constructor
{
this.keyPt = keyPt;
this.oppPt = oppPt;
}
// You will need a different draw method for each kind of shape. Note the square is drawn
// from first principles. All other shapes should similarly be drawn from first principles.
// Ideally no C# standard library class or method should be used to create, draw or transform a shape
// and instead should utilse user-developed code.
public void draw(Graphics g, Pen blackPen)
{
// This method draws the square by calculating the positions of the other 2 corners
double xDiff, yDiff, xMid, yMid; // range and mid points of x & y
// calculate ranges and mid points
xDiff = oppPt.X - keyPt.X;
yDiff = oppPt.Y - keyPt.Y;
xMid = (oppPt.X + keyPt.X) / 2;
yMid = (oppPt.Y + keyPt.Y) / 2;
// draw square
g.DrawLine(blackPen, (int)keyPt.X, (int)keyPt.Y, (int)(xMid + yDiff / 2), (int)(yMid - xDiff / 2));
g.DrawLine(blackPen, (int)(xMid + yDiff / 2), (int)(yMid - xDiff / 2), (int)oppPt.X, (int)oppPt.Y);
g.DrawLine(blackPen, (int)oppPt.X, (int)oppPt.Y, (int)(xMid - yDiff / 2), (int)(yMid + xDiff / 2));
g.DrawLine(blackPen, (int)(xMid - yDiff / 2), (int)(yMid + xDiff / 2), (int)keyPt.X, (int)keyPt.Y);
}
public void fillSquare(Graphics g, Brush redBrush)
{
float xDiff = oppPt.X - keyPt.X;
float yDiff = oppPt.Y - keyPt.Y;
float xMid = (oppPt.X + keyPt.X) / 2;
float yMid = (oppPt.Y + keyPt.Y) / 2;
var path = new GraphicsPath();
path.AddLines(new PointF[] {
keyPt,
new PointF(xMid + yDiff/2, yMid-xDiff/2),
oppPt
});
path.AddLines(new PointF[] {
keyPt,
new PointF(xMid - yDiff/2, yMid + xDiff/2),
oppPt
});
path.CloseFigure();
// Fill Triangle
g.FillPath(redBrush, path);
}
}
}
i have tried this method but something is missing i don't know what is it
private void itemRotation(PaintEventArgs e)
{
Pen blackpen = new Pen(Color.Black);
Graphics g = e.Graphics;
Font myFont = new System.Drawing.Font("Helvetica", 9);
Brush blackwriter = new SolidBrush(System.Drawing.Color.Black);
if (rotateItem)
{
for (int i = 0; i < shapes.Count; i++)
{
if (shapes[i].Selected)
{
if (shapes[i].ShapeType == (int)ShapeTypes.Square)
{
PointF center = new PointF(shapes[i].keyPt.X + (shapes[i].oppPt.X / 2.0F), shapes[i].keyPt.Y + (shapes[i].oppPt.Y / 2.0F));
shapes[i].keyPt = new Point(shapes[i].keyPt.X, shapes[i].keyPt.Y);
shapes[i].oppPt = new Point(shapes[i].oppPt.X, shapes[i].oppPt.Y);
Matrix myMatrix = new Matrix();
myMatrix.Rotate(30);
g.Transform = myMatrix;
((Square)shapes[i]).draw(g, blackpen);
g.DrawString("2nd pos", myFont, blackwriter, shapes[i].keyPt.X, shapes[i].oppPt.X);
}
}
}
}
}
Below is an example of how to draw the same shape (a GraphicsPath) into various locations and rotations.
The key here is the following two commands
e.Graphics.TranslateTransform(x, y);
e.Graphics.RotateTransform(-angle);
See results below:
and the code used to generate it:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// This code defines a graphics shape using a GraphicsPath
// and draws multiple copies along a grid and with various
// rotation angle angles.
e.Graphics.SmoothingMode=SmoothingMode.AntiAlias;
var target = sender as PictureBox;
// Step 1 - Define a rectangle 20 by 12 pixels, center at origin.
var gp = new GraphicsPath();
gp.AddLines(new PointF[] {
new PointF(-10, -6),
new PointF( 10, -6),
new PointF( 10, 6),
new PointF(-10, 6) });
gp.CloseFigure();
// Step 2 - Define a 10×9 grid with two loops
float angle = 0;
for (int i = 0; i<9; i++)
{
// divide the control height into 10 divisions
float y = (i+1)*target.Height/10;
for (int j = 0; j<10; j++)
{
// divide the control width into 11 divisions
float x = (j+1)*target.Width/11;
// Save the default transformation state
var state = e.Graphics.Save();
// Traslate the origin to (x,y), each grid point
e.Graphics.TranslateTransform(x, y);
// Rotate shape by an angle (negative = CCW)
e.Graphics.RotateTransform(-angle);
// Draw the shape
e.Graphics.FillPath(Brushes.LightSeaGreen, gp);
e.Graphics.DrawPath(Pens.Black, gp);
// Restore the default transformation state
e.Graphics.Restore(state);
// Increment the angle by one degree.
// The idea is to show all 90 degrees of rotation in a 10×9 grid.
angle++;
}
}
}
How can i draw a polygon according to the input coordinates which are given in C#.
You didn't show any code because based on those coordinate, you are applying some form of scaling to the image.
Using the Paint event of a PictureBox, here is an example using those coordinates on the screen. It fills in the polygon, then draws the border, then it loops through all the points to draw the red circle:
void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(Color.White);
// draw the shading background:
List<Point> shadePoints = new List<Point>();
shadePoints.Add(new Point(0, pictureBox1.ClientSize.Height));
shadePoints.Add(new Point(pictureBox1.ClientSize.Width, 0));
shadePoints.Add(new Point(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height));
e.Graphics.FillPolygon(Brushes.LightGray, shadePoints.ToArray());
// scale the drawing larger:
using (Matrix m = new Matrix()) {
m.Scale(4, 4);
e.Graphics.Transform = m;
List<Point> polyPoints = new List<Point>();
polyPoints.Add(new Point(10, 10));
polyPoints.Add(new Point(12, 35));
polyPoints.Add(new Point(22, 35));
polyPoints.Add(new Point(24, 22));
// use a semi-transparent background brush:
using (SolidBrush br = new SolidBrush(Color.FromArgb(100, Color.Yellow))) {
e.Graphics.FillPolygon(br, polyPoints.ToArray());
}
e.Graphics.DrawPolygon(Pens.DarkBlue, polyPoints.ToArray());
foreach (Point p in polyPoints) {
e.Graphics.FillEllipse(Brushes.Red,
new Rectangle(p.X - 2, p.Y - 2, 4, 4));
}
}
}
You may use Graphics.DrawPolygon. You can store the coordinates in an array of Point and then you can pass that to DrawPolygon method. You may wanna see:
Drawing with Graphics in WinForms using C#
private System.Drawing.Graphics g;
System.Drawing.Point[] p = new System.Drawing.Point[6];
p[0].X = 0;
p[0].Y = 0;
p[1].X = 53;
p[1].Y = 111;
p[2].X = 114;
p[2].Y = 86;
p[3].X = 34;
p[3].Y = 34;
p[4].X = 165;
p[4].Y = 7;
g = PictureBox1.CreateGraphics();
g.DrawPolygon(pen1, p);
This simple function is able to generate an array of PointF equal to the vertices of the regular polygon to be drawn, where "center" is the center of the polygon, "sides" is its number of sides, "sideLength" is the size of each side in pixels and "offset" is its slope.
public PointF[] GetRegularPolygonScreenVertex(Point center, int sides, int sideLength, float offset)
{
var points = new PointF[sides];
for (int i = 0; i < sides; i++)
{
points[i] = new PointF(
(float)(center.X + sideLength * Math.Cos((i * 360 / sides + offset) * Math.PI / 180f)),
(float)(center.Y + sideLength * Math.Sin((i * 360 / sides + offset) * Math.PI / 180f))
);
}
return points;
}
The result obtained can be used to draw a polygon, e.g. with the function:
GraphicsObject.DrawPolygon(new Pen(Brushes.Black, GetRegularPolygonScreenVertex(new Point(X, Y), 6, 30, 60f));
Which will generate a regular hexagon with a side of 30 pixels inclined by 30°.
hex
I need to draw sin(x)/x graphic into PictureBox in animation mode by timer component. I have axes already on my picBox and graphic draws from 0;0. Also I have some code from this forum, but there my graphic draws FROM RIGHT TO THE LEFT, and I need to draw it FROM LEFT TO THE RIGHT. And I need to draw it in animation mode by timer. Could anybody help me?
Here's my drawing function:
private void drawStream()
{
const int scaleX = 35;
const int scaleY = 35;
Point picBoxTopLeft = new Point(0, 0);
Point picBoxTopLeftm1 = new Point(-1, 0);
int halfX = picBox.Width / 2;
int halfY = picBox.Height / 2;
Size size = new Size(halfX + 20, picBox.Height);
Graphics gr = picBox.CreateGraphics();
gr.TranslateTransform(halfX, halfY);
gr.ScaleTransform(scaleX, scaleY);
gr.ResetClip();
float lastY = (float)Math.Sin(0);
float y = lastY;
Pen p = new Pen(Color.Red, 0.015F);
float stepX = 1F / scaleX;
for (float x = 0; x < 15; x += stepX)
{
gr.CopyFromScreen(picBox.PointToScreen(picBoxTopLeft), picBoxTopLeftm1, size, CopyPixelOperation.SourceCopy);
y = (float)Math.Sin(x);
gr.DrawLine(p, -stepX, lastY, 0, y);
lastY = y;
}
}
Thanx a lot.
P.S. Sorry for my English, I'm Ukrainian.
It looks like the line:
gr.DrawLine(p, -stepX, lastY, 0, y);
Will always draw a line from (-stepX, lastY) to (0, y). Only the Y coordinates of these points change during your loop which doesn't look like what you want.
Moreover, you're stepping in the X direction by stepX which is defined as being 1 / 35.0f. This means you're stepping 35 times per whole pixel; a bit excessive. Get rid of your ScaleTransform and instead scale your independent variable (x) to get a more sensible frequency. You should probably also increase your amplitude to get a good looking curve as well.
I think your drawing loop should look more like:
for (int x = 1; x < halfX; x += 1)
{
y = (float) amplitude * Math.Sin(x * stepX);
gr.DrawLine(p, x - 1, lastY, x, y);
lastY = y;
}
This will draw from the origin (0,0) to the right side of the picture box at once. To animate this you're going to need to take this code and instead of looping all the way to halfX you want to loop only part of the way and keep track of where you the next time your Timer fires it's event.
edit:
Every time you create a Pen object you take a handle from Windows through GDI. These handles are only returned to be reused when you Dispose() the Pen object. If you create a new Pen every time you draw and don't dispose them you'll run out of handles eventually!
To be safe when using these types of objects (Pen, Brush, Font, and more need to be disposed) wrap them in a using statement:
using (Pen pen = new Pen(Color.Red, 0.015f)) {
// ... use the pen here
}
// After here it is Disposed and cannot be accessed
Ok, spent 20 minutes to try it myself.
public Form1()
{
InitializeComponent();
_bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = _bitmap;
Timer timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 10;
timer.Start();
}
private int x = 0;
void timer_Tick(object sender, EventArgs e)
{
if(++x < _bitmap.Width)
{
int y = _bitmap.Height/2
- ((int)(Math.Sin(x * (Math.PI * 2) / _bitmap.Width) * (_bitmap.Height / 2)));
//Small rounding error
if (y > _bitmap.Height - 1)
y = _bitmap.Height - 1;
_bitmap.SetPixel(x, y, Color.Black);
}
pictureBox1.Image = _bitmap;
}
Tested and working.
You should really add Points to a GraphicsPath and just paint that.
Also: You should not create a Graphics object like that. Get one from the Bitmap or use the one supplied by the Paint event.
1) Right to left. Just change your for loop.
for (float x = 0; x < 15; x += stepX)
becomes
for (float x = size.Width; x >= 0; x
-= stepX)
2) A timer.
Simple solution is to just add a sleep.
for (float x = 0; x < 15; x += stepX)
Thread.Sleep(500); //draw...
Any suggestions on how to draw a directed line in .Net? I'm currently using Graphics.DrawLine with a Pen with dashes. But the dashes point in both directions. I want them to all point in a single direction.
using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
{
p.StartCap = LineCap.Round;
p.EndCap = LineCap.ArrowAnchor;
p.CustomEndCap = new AdjustableArrowCap(3, 3);
p.DashStyle = DashStyle.Dash;
p.DashCap = DashCap.Triangle;
e.Graphics.DrawLine(p, startPt, pt);
}
This might not be very helpful, but the way that we accomplished this type of thing on other projects that I have been involved with is to implement a custom "pen" that accepts the line to be drawn, calculates the actual dashes, and then draws each dash as an individual line with a "real" Pen. If you were to do something like this, then you could actually apply a "pen" level StartCap and/or EndCap to each dash.
The custom "pen" would have to accept an array or sequence of dash/gap lengths (or maybe an enumeration of standard pen styles that would be interpreted internally as specific dash/gap lengths).
We did this many years ago with a GDI-based drawing system where we had to support more line styles than the built in line styles that GDI supported.
It is an interesting exercise, but it is also probably more trouble than it is worth unless you REALLY have to have the dashes drawn as you describe.
[EDIT]
Here is some sample code for how you might do this, if you are so inclined.
First is an extension method on the Graphics object. It takes a pen, dash length, gap length, start point, and end point. It interpolates along the line p1->p2, drawing a "dash" length segment and then skipping a "gap" length segment. The passed-in pen should be solid with an arrow endcap (to achieve the effect you were asking for).
The code is pretty rough, but the behavior is, more or less, like this:
If the input line is shorter then the total dash+gap length, then the line is drawn as-is using the input pen.
If the input line is longer than the total dash+gap length, then "dash" length lines are drawn until the "remainder" of the line is less than the dash+gap length, at which point the remainder is drawn as-is with the input pen.
If you wanted to implement Path drawing, then you would have to interpolate around the intermediate vertices (unless you wanted to cheap out and just compute dashes for each segment indepdently).
public static void DrawDashedLine(this Graphics g, Pen p, float dash, float gap, PointF s, PointF e)
{
float dx = e.X - s.X;
float dy = e.Y - s.Y;
float len = (float)Math.Sqrt(dx * dx + dy * dy);
float remainder = len;
float vx = dx / len;
float vy = dy / len;
if (len <= dash + gap)
{
g.DrawLine(p, s, e);
return;
}
PointF last = s;
while (remainder > dash + gap)
{
PointF p1 = new PointF(last.X, last.Y);
PointF p2 = new PointF(p1.X + vx*dash, p1.Y + vy*dash);
g.DrawLine(p, p1, p2);
last = new PointF(p2.X + vx*gap, p2.X + vy*gap);
remainder = remainder - dash - gap;
}
if (remainder > 0)
{
g.DrawLine(p, last, e);
}
}
}
Here is how you would call it:
private void button1_Click(object sender, EventArgs e)
{
using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
{
p.StartCap = LineCap.Round;
p.EndCap = LineCap.ArrowAnchor;
p.CustomEndCap = new AdjustableArrowCap(3, 3);
p.DashStyle = DashStyle.Solid;
var graph = this.CreateGraphics();
graph.DrawDashedLine(p, 20, 10, new PointF(20, 20), new PointF(500, 500));
}
}
I don't claim that the code is great (or even necessarily good ;-), but it should give you a good starting point if you are really interested in drawing your directed line.
Good luck!
Hmm... maybe I am missing something, but when I use this (almost) exact same code, I get a directed arrow with only one point.
Here is my code:
private void button2_Click(object sender, EventArgs e)
{
using (var p = new Pen(Color.FromArgb(190, Color.Green), 5))
{
p.StartCap = LineCap.Round;
p.EndCap = LineCap.ArrowAnchor;
p.CustomEndCap = new AdjustableArrowCap(3, 3);
p.DashStyle = DashStyle.Dash;
p.DashCap = DashCap.Triangle;
var graph = this.CreateGraphics();
graph.DrawLine(p, new Point(20, 20), new Point(150, 150));
}
}
And the output: