petabridge / DrawTogether.NET

Apache License 2.0
53 stars 10 forks source link

Smooth lines instead of circles #12

Closed KristofferStrube closed 3 years ago

KristofferStrube commented 3 years ago

A suggestion that can make the drawing look nicer when using SVG anyway would be to use a Smooth Bezier curve path. A SVG path is a connected set of instructions. A single path could contain the path that a user has moved from when they started mouseDown till they trigger mouseUp. When using a Smooth Bezier curve you can achieve a line that is connected instead of having holes between each point that is registered as it is currently. You would need the underlying structure of the stroke data to change a tiny bit. Instead of being a List<StrokeData> it would need to be a List<List<StrokeData>> where each List in the List would hold connected strokes. The data (SVG attribute called d in SVG path) for each of these connected strokes could be constructed as so:

protected string PathData(List<StrokeData> ConnectedStroke) {
    var result = "";
    if (ConnectedStroke.Count >= 2)
    {
        result = $"M {ConnectedStroke[0].cX} {ConnectedStroke[0].cY} ";
        for (int i = 1; i < ConnectedStroke.Count -1; i++)
        {
            result += $"S {ConnectedStroke[i - 1].cX / 8 + ConnectedStroke[i].cX - ConnectedStroke[i+1].cX / 8} {ConnectedStroke[i - 1].cY / 8 + ConnectedStroke[i].cY - ConnectedStroke[i+1].cY / 8} {ConnectedStroke[i].cX} {ConnectedStroke[i].cY} ";
        }
        result += $"S {ConnectedStroke[^2].cX /  4 + ConnectedStroke[^1].cX * 3 / 4} {ConnectedStroke[^2].cY / 4 + ConnectedStroke[^1].cY * 3 / 4} {ConnectedStroke[^1].cX} {ConnectedStroke[^1].cY} ";
    }
    return result;
}

Another nice feature of this would be that you would never change the color or width midway through some connected strokes. So you could change the data structure, even more, to be a List<ConnectedStrokes> Where ConnectedStrokes would be:

public class ConnectedStrokes
{
    public List<StrokeData> Strokes { get; set; }
    public int CursorSize { get; set; }
    public string Color { get; set; }
}

This would also mean that you would not need to have a Color and Width for every single point.

A potential drawback is that you would need to update these ConnectedStrokes while drawing them. So they would probably need some GUID that can identify them so that when you add a Stroke to some ConnectedStrokes then the server (and other clients) would know what to add them to as well.

Feel free to ask questions if something about this idea is unclear.

This is just me brainstorming ideas., so sorry if this is not really the way you want to go with the project. :)

Aaronontheweb commented 3 years ago

I think this is a good idea - I was hoping to add a line tool of some kind to the UI