Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drawing a circle produes a path and not a circle. #121

Open
human154 opened this issue Nov 16, 2023 · 3 comments
Open

Drawing a circle produes a path and not a circle. #121

human154 opened this issue Nov 16, 2023 · 3 comments

Comments

@human154
Copy link

human154 commented Nov 16, 2023

I'm doing the tutorial and the first example of drawing a circle produces an svg file which represents a circle as a path, instead of representing a circle as a circle element.

I would like to be leveraging the compactness of svg, and drawing a path for a circle seems to negate the inherent efficiency of the svg format.

(Viewing the circle in the browser the path of the circle is noticeably imperfect.)

@byorgey
Copy link
Member

byorgey commented Nov 17, 2023

I agree this would be nice!

Currently, the circle function calls arcT, which calls bezierFromSweep, which constructs an approximation to a circle using four Bézier segments:

https://hackage.haskell.org/package/diagrams-lib-1.4.6/docs/src/Diagrams.TwoD.Ellipse.html#circle
https://hackage.haskell.org/package/diagrams-lib-1.4.6/docs/src/Diagrams.TwoD.Arc.html#bezierFromSweep

This works for any backend that supports drawing Bézier segments, whether or not it supports drawing circles as a primitive.

However, for backends that do support circles as primitive, such as SVG, it would be very nice to somehow remember the fact that the path is supposed to be a circle and be able to output it as such (or approximate it with Béziers at the last minute for backends which do not support primitive circles).

This is something we have thought about before but it is not so simple. It's been a while since I've thought about it, but off the top of my head the needed changes would be something like this:

  • Add a new constructor to the Trail' type ( https://hackage.haskell.org/package/diagrams-lib-1.4.6/docs/src/Diagrams.Trail.html#Trail%27 ) for a primitive circle. Even just this step would be a lot of work because you would have to update all the functions that work on trails, and decide when to convert the primitive circle into Beziers (e.g. some operations on trails would not preserve circle-ness).
    • However, you'd probably want to leave the withTrail and withTrail' functions with the same type, and just make them convert any primitive circles to beziers on the fly: these are the functions that most backends will use to process trails.
    • Then add a new function withCircleTrail which is like withTrail but adds an extra callback for circle primitives.
  • Now update the SVG backend to use the new withCircleTrail function and output circle elements appropriately.

@human154
Copy link
Author

Ok. Thanks for responding. Sounds like the high cost of implementing direct support for circles wouldn't be justified. Such is life.

@byorgey
Copy link
Member

byorgey commented Nov 19, 2023

Well, I think it could be justified, in the sense that I would happily merge a PR which implemented this. It would just be quite a bit of work and I don't have time to do it myself. But I posted my thoughts on the needed changes in case anyone else seeing this issue wants to take a shot at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants