How to draw a bezier with two colors? like the picture below?
I already have drawn the bezier, I can fill it with any color, however I cant the gradient working.
this is what im doing, im using a Path to create the bezier by the way.
private void test()
{
System.Windows.Media.GradientStop GradientStop1 = new System.Windows.Media.GradientStop();
System.Windows.Media.GradientStop GradientStop2 = new System.Windows.Media.GradientStop();
System.Windows.Media.LinearGradientBrush p_Fill; p_Fill = new System.Windows.Media.LinearGradientBrush(Colors.Blue, Colors.Red, new Point(0, 0.5), new Point(1, 0.5));
p_Fill.GradientStops.Add(GradientStop1);
p_Fill.GradientStops.Add(GradientStop2);
Bez.Fill = p_Fill;
}
This is how it should be
This is what I get
If you need a sharp cut between the 2 colored halves, you have to need more GradientStops:
var grad3 = new System.Windows.Media.GradientStop()
{Offset = 0.5, Color=Colors.Blue};
var grad4 = new System.Windows.Media.GradientStop()
{Offset = 0.5, Color=Colors.Red};
GradientStop2.Offset = 1;
p_Fill.GradientStops.Add(GradientStop1);
p_Fill.GradientStops.Add(grad3);
p_Fill.GradientStops.Add(grad4);
p_Fill.GradientStops.Add(GradientStop2);
Addtionally, you have to set the Brush for the Stroke, not the Fill. The StrokeThickness determines the thickness of the curve:
Bez.Stroke = p_Fill;
Bez.StrokeThickness = new Thickness(10);
Related
I've stumbled upon converting Ellipse to PathGeometry.
I've tried to use ArcSegment to present Ellipse, but still don't know how to convert Ellipse size to ArcSegment size. I'm trying to segment Ellipse into two part, but there are other approaches, i.e. Bezier curves.
Need clues how to convert Ellipse to ArcSegment collection.
The whole process could be looking like that:
public static PathFigure ToFigures(this Ellipse ellipse)
{
var pathFigure = new PathFigure {IsClosed = true};
var arcSegment1 = new ArcSegment();
var arcSegment2 = new ArcSegment();
pathFigure.Segments.Add(arcSegment1);
pathFigure.Segments.Add(arcSegment2);
return pathFigure;
}
You could directly use an EllipseGeometry for the Path Data:
path = new Path
{
Data = new EllipseGeometry { RadiusX = 100, RadiusY = 50 }
};
Using the size of the Ellipse it would look like this:
path = new Path
{
Data = new EllipseGeometry
{
RadiusX = ellipse.ActualWidth / 2,
RadiusY = ellipse.ActualHeight / 2
}
};
Basically I have a form and am trying to "dim" areas of it to draw focus to a certain part of the form. To do this I'm using a Form with no border and 50% opacity, aligned with the actual form. The area I am trying to mask is the dark gray area, roughly, as pictured:
To get the "U"-shaped form, I'm using a GraphicsPath with AddPolygon, calculating the points of each vertex:
var p = new GraphicsPath();
var origin = new Point(Top, Left);
var maxExtentPt = new Point(origin.X + Width, origin.Y + Height);
Point[] points = {
origin,
new Point(origin.X + leftPanel.Width, origin.Y),
new Point(origin.X + leftPanel.Width, maxExtentPt.Y - bottomPanel.Height),
new Point(maxExtentPt.X - rightPanel.Width, maxExtentPt.Y- bottomPanel.Height),
new Point(maxExtentPt.X - rightPanel.Width, origin.Y),
new Point(maxExtentPt.X, origin.Y),
maxExtentPt,
new Point(origin.X, maxExtentPt.Y),
origin
};
p.AddPolygon(points);
overlayForm.Region = new Region(p);
overlayForm.Location = PointToScreen(Point.Empty);
The three panels in the code are what I am masking, so I am using their dimensions to calculate the points. Instead of getting my expected result, the mask looks like this, with its size changing as I resize the main form (I recalculate the region on Move and Resize):
Is there some limitation of GraphicsPath.AddPolygon that I'm not aware of? I double-checked (quadruple-checked, really) the results of my calculations, including taking the coordinates for each point and plugging them into Ipe to see if the shape was actually correct... It was. But not in my program!
Edit: Here are the values of each point, when I hit a breakpoint at p.AddPolygon(points); I'm starting in the upper left-hand corner and going around clockwise:
Looks like your points are wrong after all.
Everything ought to be in the coordinates of the ClientRectangle, so
Origin should not be new Point(Top, Left) which is the Location of the Form. It should be Point.Empty or (0,0). Or you could use the leftPanel.Location.
And
maxExtentPt = new Point(origin.X + Width, origin.Y + Height);
should read:
var maxExtentPt = new Point(origin.X + ClientSize.Width, origin.Y + ClientSize.Height);
(The difference is the size of border+title..)
Let me know if that works better!
You could also try doing it this way, basing everything off the Panels:
Form overlayForm = new Form();
overlayForm.Opacity = .5;
overlayForm.BackColor = Color.DarkGray;
overlayForm.StartPosition = FormStartPosition.Manual;
overlayForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
var p = new GraphicsPath();
var origin = new Point(0, 0);
var maxExtentPt = new Point(this.Width, this.Height);
Point[] points = {
origin,
new Point(leftPanel.Right, origin.Y),
new Point(leftPanel.Right, bottomPanel.Top),
new Point(rightPanel.Left, bottomPanel.Top),
new Point(rightPanel.Left, origin.Y),
new Point(rightPanel.Right, origin.Y),
maxExtentPt,
new Point(origin.X, maxExtentPt.Y),
origin
};
p.AddPolygon(points);
overlayForm.Region = new Region(p);
overlayForm.Location = this.PointToScreen(new Point(0, 0));
overlayForm.Show();
I would like to dynamically add a Triangle to my canvas. I can do this but only in one very specific way that does not work for my application. What I would like to do is supply a point and a size and get back a triangle.
var poly = shape as Polygon;
Polygon p = new Polygon
{
//Width = size,
//Height = size,
Fill = new SolidColorBrush(Colors.Red),
ManipulationMode = ManipulationModes.All,
RenderTransform = new CompositeTransform()
};
int w = 200;
int h = 200;
Point start = new Point(400, 200);
var right = new Point(start.X + w, start.Y);
var top = new Point(start.X + (w / 2), start.Y - (h));
poly.Points.Add(point);
poly.Points.Add(right);
poly.Points.Add(top);
poly.Points.Add(point);
Then I add the shape to my canvas child controls and and set the X Y on the shapes RenderTransform. Nothing appears. If however I just do this:
Polygon p = new Polygon
{
//Width = size,
//Height = size,
Fill = new SolidColorBrush(Colors.Red),
ManipulationMode = ManipulationModes.All,
RenderTransform = new CompositeTransform()
};
p.Points.Add(new Point(300, 200));
p.Points.Add(new Point(400, 125));
p.Points.Add(new Point(400, 275));
p.Points.Add(new Point(300, 200));
It renders a Triangle just fine. However if you supply a width and height to the above code it will stop rendering.
Can I just create a triangle of a certain size, without having to set actual points on the canvas at first, much like you do an Ellipse or a Rectangle?
Am using the below code to create polygon. i just want to fill this polygon surface with black dots, how i can do that, then i want to convert this polygon to bitmap or in memory stream, how to do this??
// Create a blue and a black Brush
SolidColorBrush yellowBrush = new SolidColorBrush();
yellowBrush.Color = Colors.Transparent;
SolidColorBrush blackBrush = new SolidColorBrush();
blackBrush.Color = Colors.Black;
// Create a Polygon
Polygon yellowPolygon = new Polygon();
yellowPolygon.Stroke = blackBrush;
yellowPolygon.Fill = yellowBrush;
yellowPolygon.StrokeThickness = 4;
// Create a collection of points for a polygon
System.Windows.Point Point1 = new System.Windows.Point(50, 100);
System.Windows.Point Point2 = new System.Windows.Point(200, 100);
System.Windows.Point Point3 = new System.Windows.Point(200, 200);
System.Windows.Point Point4 = new System.Windows.Point(300, 30);
PointCollection polygonPoints = new PointCollection();
polygonPoints.Add(Point1);
polygonPoints.Add(Point2);
polygonPoints.Add(Point3);
polygonPoints.Add(Point4);
// Set Polygon.Points properties
yellowPolygon.Points = polygonPoints;
// Add Polygon to the page
mygrid.Children.Add(yellowPolygon);
Do the dots have to be positioned in a particular order or do you just want to have a dotted pattern in your polygon without specific order?
If you don't need a special order you could use a Brush, a DrawingBrush for instance. Check out this link: http://msdn.microsoft.com/en-us/library/aa970904.aspx
You can then set this Brush as the Fill-Property of your Polygon instead of the SolidColorBrush.
This is the DrawingBrush example from the msdn link, but modified to display dots:
// Create a DrawingBrush and use it to
// paint the rectangle.
DrawingBrush myBrush = new DrawingBrush();
GeometryDrawing backgroundSquare =
new GeometryDrawing(
Brushes.Yellow,
null,
new RectangleGeometry(new Rect(0, 0, 100, 100)));
GeometryGroup aGeometryGroup = new GeometryGroup();
aGeometryGroup.Children.Add(new EllipseGeometry(new Rect(0, 0, 20, 20)));
SolidColorBrush checkerBrush = new SolidColorBrush(Colors.Black);
GeometryDrawing checkers = new GeometryDrawing(checkerBrush, null, aGeometryGroup);
DrawingGroup checkersDrawingGroup = new DrawingGroup();
checkersDrawingGroup.Children.Add(backgroundSquare);
checkersDrawingGroup.Children.Add(checkers);
myBrush.Drawing = checkersDrawingGroup;
myBrush.Viewport = new Rect(0, 0, 0.05, 0.05);
myBrush.TileMode = TileMode.Tile;
yellowPolygon.Fill = myBrush;
I have created a c# windows application and written 75% of the code. The program allows the user to create a flow chart, and will shade the flow chart shapes according to their status. I wanted them to become 3d buttons such as from the website Webdesign.org
Rather than create a PNG for each button, I wanted to create them in C# using brushes or other technique, such as:
// Create solid brush.
SolidBrush blueBrush = new SolidBrush(Color.Blue);
// Create points that define polygon.
PointF point1 = new PointF(50.0F, 50.0F);
PointF point2 = new PointF(100.0F, 25.0F);
PointF point3 = new PointF(200.0F, 5.0F);
PointF point4 = new PointF(250.0F, 50.0F);
PointF point5 = new PointF(300.0F, 100.0F);
PointF point6 = new PointF(350.0F, 200.0F);
PointF point7 = new PointF(250.0F, 250.0F);
PointF[] curvePoints = {point1, point2, point3, point4, point5, point6, point7};
// Define fill mode.
FillMode newFillMode = FillMode.Winding;
// Fill polygon to screen.
e.Graphics.FillPolygon(blueBrush, curvePoints, newFillMode);
I know WPF has radial gradients, but can I do something simular in CGI?
Unlike WPF, GDI+/WinForms does not have a RadialGradientBrush. However you can achieve the same effect using a PathGradientBrush.
Here's an example:
Rectangle bounds = ...;
using (var ellipsePath = new GraphicsPath())
{
ellipsePath.AddEllipse(bounds);
using (var brush = new PathGradientBrush(ellipsePath))
{
brush.CenterPoint = new PointF(bounds.Width/2f, bounds.Height/2f);
brush.CenterColor = Color.White;
brush.SurroundColors = new[] { Color.Red };
brush.FocusScales = new PointF(0, 0);
e.Graphics.FillRectangle(brush, bounds);
}
}
The PathGradientBrush has lots of properties to experiment with to ensure you get the effect you're after.
Take a look at this Codeproject article, and then at the Path gradient.