I'm working on improving an open source rasterization library called Gudni that I started a few years ago. It's source repository and the branch I'm currently working on are here: https://github.com/ianmbloom/gudni/tree/texturetransformation.

I'm trying to implement a function that maps a quadratic bezier curve onto another curve (see illustration below). This is important for the library because it will not only allow one to describe things like dotted lines as just a series of rectangles projected onto a bezier path, but the same mechanism can (hopefully) be used to make text that follows a path or to make arrowheads etc and many other useful things. Using unified operation to do all of these things will hopefully make the library really easy to use and make a lot of useful figures very easy to describe.

But I've run into a bit of an impasse and I'm looking for some help.

The function I need has this description:

Given two quadratic bezier curves, a source and a target curve, transform the target curve such that the targets x-axis corresponds to the arc-distance along the source curve and the targets y-axis corresponds to the distance from the curve. In other words given a point (x,y) in the target curves coordinate space find a point and a normal vector that is x units along the arc-length of the source curve then take that point and add it to the normal vector * y.

This works great for points but it doesn't work for quadratic bezier curves because the control point must be transformed such that each point on the resulting curve approximates a projected point. I'm trying to find method of calculating a control point such that the resulting curve is consistent, well behaved, doesn't require excessive computation, and is visually pleasing (though not necessarily precisely accurate) and can be applied to arbitrary target curves. Probably the most important requirement for the result is that two consecutive bezier segments that share the same tangent, share the same tangent in the projected curves.

Since the control point of a quadratic bezier is always the intersection of the tangent lines through its start and end point, my solution so far is to take the tangent vectors from the original target curve, transform them relative to the source normal vectors and then calculate the intersection of the lines defined by these transformed tangent vectors. Unfortunately this appears to work well for horizontal target curves but somehow it is often wrong for diagonal curves. I think this is because of the arc-length transformation but I haven't figured it out yet.

I'm curious if anyone has any thoughts on how to approach this problem. The current (incorrect) implementation of the function in question can be found here: https://github.com/ianmbloom/gudni/blob/c65daed3e74a24c47db9d0488159104dbd1b8b62/src/Graphics/Gudni/Figure/Projection.hs#L243

Let me know if reading haskell is a problem and I can find a way to walk you through it.

Upon request, here is a link to a formalization of the problem: https://medium.com/@ianbloom/-6e88ea8e8888

Kind regards, Ian Bloom

Projection of one quadratic bezier onto another.

  • $\begingroup$ Could you rewrite this formally as a mathematical problem? It seems you have problems with the math, in which case the rest is irrelevant and honestly (at least for me) confusing. $\endgroup$ – lightxbulb Jan 18 '20 at 22:18
  • $\begingroup$ Sure, I actually wrote a Maple worksheet describing the problem in an effort to find a way to solve for the control point. But the math for quadratic beziers gets very complicated very quickly and so I'm looking first and foremost for a conceptual approach. In other words, I don't think the right solution is mathematically perfect, that may be impossible, but instead just a "well behaved" solution that looks good. $\endgroup$ – Ian Bloom Jan 18 '20 at 23:39
  • $\begingroup$ In any case let me look into a better way to describe this. But basically if you understand the case of "stroking" a bezier curve as just mapping a long rectangle of the appropriate length onto a source curve, this is just a generalization of that to any shape that you can make out of bezier curves and might want to map onto another curve path. Let me know if that makes any sense. $\endgroup$ – Ian Bloom Jan 18 '20 at 23:54
  • $\begingroup$ "mapping a long rectangle of the appropriate length onto a source curve" - there are infinitely many ways to do this, that is why I believe a formalization will help. $\endgroup$ – lightxbulb Jan 19 '20 at 7:09
  • 1
    $\begingroup$ Why dont you formulate the exact curve and then fit to it. Its not like this has a analytical solution in arbitrary cases. $\endgroup$ – joojaa Jan 20 '20 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.