1
votes

I'm quite new when it comes to graphical programming, especially in C# which is why I decided to try a project that would teach me a thing or two about graphical programming.

(All of the proceeding refers to 2D) I was wondering if C# or WPF had any way of creating organic shapes. By organic shapes I mean shapes without hard corners, such as ellipses. Although I don't want to be restricted to ellipses. Perhaps there's a better name for it, but I'd like to be able to draw blobs (and I'm not talking sql ba-dum-tsss...)

If anyone can help in any way it would be great whether it's suggesting a native C#/WPF solution or some sort of nuget/Library I should take a look at.

Edit courtesy of Geoff James: What I mean (visually) by "organic shapes" is more akin to this

The next thing I would need help afterwards, if you're still with me is quite the exact opposite.

I would like the ability to create irregular lines. Lines of varying thicknesses (preferably varying thicknesses throughout the span of the line), and of shaky architecture. Such as if you were trying to draw a line in a moving vehicle and your arm jumped all over the place as the car hit bumps and other irregularities in the road.

This second part I believe to be a little simpler. I've looked a the stroke constructor, and I do believe that it wouldnt be too difficult to create an algorithm that made naturally shaky looking lines, however, I'm drawing a blank about the thickness. Perhaps the ink namespace has more of what I need.

If you're still with me, thank you for reading this novel and lending your help, all is very appreciated!

1
I'd really like to +1 your OP simply for the humour; but that's not the principal of SO. On the note of your "ellipses", I would do a simple Google search of how to draw a circle etc. in WPF. e.g. Draw a <border /> and give it height and width (can be same or different) and set the CornerRadius property of it, to give you the rounded edges. The second part I'm sure you can figure out for yourself. Tip: please provide some code of things you've tried already in your OP. See here: stackoverflow.com/help/how-to-askGeoff James
Are beziers "organic" enough? You can do a lot with Paths in WPF.15ee8f99-57ff-4f92-890c-b56153
@GeoffJames I thought i only made one bad pun. Perhaps comedy is my true calling and I should leave this programming thing behind! As for what you've said, circles are not the problem. Ellipses are easy peasy.. What's hard however, and I can't seem to find any information on, is the creating of shapes that have no hard edges but are still closed and polygons by definition such as this for example. However, thank you for your feedback!Cristian C.
@EdPlunkett That seems like it might just work. I'll take a hard look at it. thank you!Cristian C.
@CristianC. That's fair enough - however, I digress - it wasn't all that clear in your OP exactly what you were after. You should have clarified this maybe with the image link you just commented. Also, could you include whether you wish to do this from code-behind, XAML or even both? Good luck with your interesting question :)Geoff James

1 Answers

2
votes

A Shape is a type of UIElement that enables you to draw a shape to the screen. Because they are UI elements, Shape objects can be used inside Panel elements and most controls.

WPF offers several layers of access to graphics and rendering services. At the top layer, Shape objects are easy to use and provide many useful features, such as layout and participation in the WPF event system.

WPF provides a number of ready-to-use Shape objects. All shape objects inherit from the Shape class. Available shape objects include Ellipse, Line, Path, Polygon, Polyline, and Rectangle.

You can use Path to generate a bezier curve.

There are two types of path segment that you can use to draw Bézier curves. These are a special type of smooth curve, calculated mathematically using fixed start and end points, and one or more control points, known as tangent points.

The tangent points determine the path of the curve. If you draw a line with a single tangent point, the direction of travel at the start and end of the curve will point directly towards that point. With more control points, the curve becomes more complex.

WPF can render Bézier curves with one or two control points.

To create a Bézier curve with a single tangent point, you can add a QuadraticBezierSegment to a PathGeometry. As with other segments, the curve starts from the end point of the previous segment, or from the Path's start point if the curve is the first segment. The co-ordinates of the start point are set in the Point1 property and the end point of the curve is held in Point2.

<Window x:Class="BezierSegmentDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Path Demo"
    Height="200" Width="250">
<Canvas>
    <Path Stroke="#C0000000" StrokeThickness="3">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigure StartPoint="20,100" IsClosed="False">
                        <QuadraticBezierSegment Point1="80,150" Point2="200,20"/>
                    </PathFigure>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
    <Ellipse Canvas.Left="75" Canvas.Top="145" Fill="Blue" Height="10" Width="10" />
</Canvas>

To create a curve with two tangent points, you can include a BezierSegment element. These require three properties. Point1 and Point2 define the control points. Point3 determines the co-ordinates of the end of the line.

<Canvas>
    <Path Stroke="#C0000000" StrokeThickness="3">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigure StartPoint="20,20" IsClosed="False">
                        <BezierSegment Point1="70,130" Point2="220,20" Point3="180,160"/>
                    </PathFigure>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
    <Ellipse Canvas.Left="65" Canvas.Top="125" Fill="Blue" Height="10" Width="10" />
    <Ellipse Canvas.Left="215" Canvas.Top="15" Fill="Blue" Height="10" Width="10" />
</Canvas>

To have a line with varying thickness you can actually create two or more lines with a thickness thick enough to overlap more or less at different points along the curve. Imagine if you slightly alter the curve of a second line so that the two lines completely overlap one place so the thickness is the thickness of just one line but where they just touch at another point so that the thickness is twice the stroke width.

You could also create a closed path with fill.