How do you draw like a Crayon? - graphics

Crayon Physics Deluxe is a commercial game that came out recently. Watch the video on the main link to get an idea of what I'm talking about.
It allows you to draw shapes and have them react with proper physics. The goal is to move a ball to a star across the screen using contraptions and shapes you build.
While the game is basically a wrapper for the popular Box2D Physics Engine, it does have one feature that I'm curious about how it is implemented.
Its drawing looks very much like a Crayon. You can see the texture of the crayon and as it draws it varies in thickness and darkness just like an actual crayon drawing would look like.
(source: kloonigames.com)
(source: kloonigames.com)
The background texture is freely available here.
What kind of algorithm would be used to render those lines in a way that looks like a Crayon? Is it a simple texture applied with a random thickness and darkness or is there something more going on?

I remember reading (a long time ago) a short description of an algorithm to do so:
for the general form of the line, you split the segment in two at a random point, and move this point slightly away from it's position (the variation depending on the distance of the point to the extremity). Repeat recursively/randomly. In this way, you lines are not "perfect" (straight line)
for a given segment you can "overshoot" a little bit, by extending one extremity or the other (or both). In this way, you don't have perfect joints. If i remember well, the best was to extends the original extremities, but you can do this for the sub-segment if you want to visibly split them.
draw the lines with pattern/stamp
there was also the (already mentioned) possibility to drawn with different starting and ending opacity (to mimic the tendency to release the pen at the end of drawing)
You can use a different size for the stamp on the beginning and the end of the line (also to mimic the tendency to release the pen at the end of drawing). For the same effect, you can also draw the line twice, with a small variation for one of the extremity (be careful with the alpha in this case, as the line will be drawn twice)
Last, for a given line, you can do the previous modifications several times (ie draw the line twice, with different variations) : human tend to repeat a line if they make some mistakes.
Regards

If you blow the image up you can see a repeating stamp-pattern .. there's probably a small assortment that it uses as it moves from a to b - might even rotate them ..
The wavering of the line can't be all that difficult to do. Divide into a bunch of random segments, pick positions slightly away from the direct route and draw splines.

Here's a paper that uses a lot of math to simulate the deposition of wax on paper using a model of friction. But I think your best bet is to just use a repeating pattern, as another reader mentioned, and vary the opacity according to pressure.
For the imperfect line drawing parts, I have a blog entry describing how to do it using bezier curves.

You can base darkness on speed. That's just measuring the distance traveled by the cursor between this frame and the last frame (remember Pythagorean theorem) and then when you go to draw that line segment on screen, adjust the alpha (opacity) according to the distance you measured.

There is a paper available called Mimicking Hand Drawn Pencil Lines which covers a bit of what you are after. Although it doesn't present a very detailed view of the algorithm, the authors do cover the basics of the steps that they used.
This paper includes high level descriptions of how they generated the lines, as well as how they generated the textures for the lines, and they get results which are similar to what you want.

This article on rendering chart series to look like XKCD comics has an algorithm for perturbing lines which may be relevant. It doesn't cover calculating the texture of a crayon drawn line, but it does offer an approach to making a straight line look imperfect in a human-like way.
Example output:

I believe the easiest way would simply be to use a texture with random darkness (some gradients, maybe) throughout, and set size randomly.

Related

fast 2D texture line sample

Imagine you have a chessboard textured triangle shown in front of you.
Then imagine you move the camera so that you can see the triangle from one side, when it nearly looks as a line.
You will provably see the line as grey, because this is the average color of the texels shown in a straight line from the camera to the end of the triangle. The GPU does this all the time.
Now, how is this implemented? Should I sample every texel in a straight line and average the result to get the same output? Or is there another more efficient way to do this? Maybe using mipmaps?
It does not matter if you look at the object from the side, front, or back; the implementation remains exactly the same.
The exact implementation depends on the required results. A typical graphics API such as Direct3D has many different texture sample techniques, which all have different properties. Have a look at the documentation for some common sampling techniques and an explanation.
If you start looking at objects from an oblique angle, the texture on the triangle might look distorted with most sampling techniques, and Anisotropic Filtering is often used in these scenario's.

OpenGL in iOS: lines drawn are very not smooth

I am working on a graphic application in which the user draws lines.
The lines are not smooth. I see the problem especially when drawing the lines slowly.
What would be the correct way to smoothen the lines?
I read the following great article: http://www.merowing.info/2012/04/drawing-smooth-lines-with-cocos2d-ios-inspired-by-paper/
It fixed some of the problem, but not all of it. Still, when drawing lines slowly, they look jagged:
The problem is actually that you have too many sample points.
This is why the problem is exacerbated when the user inputs points slowly, rather than quickly. One possible solution is to use some sort of best-fitting line equation (e.g. Least Squares) to reduce the number of points and simplify it to an approximation.
There are more sophisticated approaches to smoothing user input, but in this simple case all you really need to do is reduce the sample size.

How does computer draw a line??

Windows GDI has these functions:
MoveTo();
LineTo();
They accept coordinates where to start drawing and where to stop drawing.
But how are these functions implemented?? (especially LineTo)
Do they need to calculate all points between point A and point B??
How is this line drawn exactly??
Yes, they calculate each individual point between A and B.
The most common way to do this efficiently is known as Bresenham's Line Algorithm.
Note that Windows LineTo does not draw the last point. When line segments are drawn one after another, this prevents the endpoints from being double drawn.
nobody who never saw the Windows source code can answer this in-depth...
BUT Windows is just as any other software: it needs some algorithm to draw a line... one such algorithm you can see here http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
The Moveto is "easier" in that it just updates the current coordinates the system know of...
It doesn't need to calculate all points between A and B (which are infinite) but only the discrete pixels between A and B. That's usually a standard line rasterization algorithm. See Wikipedia for Bresenham's line rasterization algorithm, which is the standard school book example and usually the base for more flexible rasterization algorithms.
I suspect there is more going on that just (a form of) Bresenham as there is also (optional) anti-aliasing. see this article for what might be the implemented algoritm (Xiaolin Wu's line algorithm)

How do I arbitrarily distort a textured polygon?

I'd like to write a program that lets me arbitrarily distort a textured polygon by dragging its vertices. I want the texture to distort fluidly and without overlap, assuming the new polygon doesn't intersect itself. I should also be able to repeat the process with the new shape, and with a minimum amount of loss.
Are there any algorithms for doing this?
It sounds like you might want a variation on the Schwarz-Christoffel mapping. This is a type of conformal mapping that can be used to warp a polygon to and from a simpler region, like a disk; although I have not implemented it, apparently it is computationally tractable.
For your application, you would set up a map from the original polygon to the simpler region, and compute the inverse map to the modified polygon; combining the two should give you a nice conformal mapping from the original to the modified polygon.
Conformal mappings are nice and smooth, but they can sometimes behave in unintuitive ways; I can imagine that an animated version might yield some entertaining "slidy" effects. The conformal mapping will preserve local angles in the interior of the polygon; this means that the size distortion very near a modified vertex can be severe.
People have been working on solutions to this problem for the past decade or two, and the state of the art keeps on getting better and better (but the math gets harder as well). A good place to start (and sort of where I stopped following it) is the work http://www.cs.technion.ac.il/~weber/Publications/Complex-Coordinates/
Read the paper there, and look up the papers in the references. One of them should give you an algorithm that you're willing to implement.
The simplest method I can think of is to triangulate the input polygon (using an ear clipping method, or something similarly good) and then move the points. Then you can use a barycentric mapping from the original polygon to the new space.
If you're looking for something more robust, you might look at mean value coordinates.

Antialiased composition by coverage?

Does anyone know of a graphics system which handles composition of multiple anti-aliased lines well?
I'm showing a dependency diagram and have a bunch of curves emanating from a point. These are drawn anti-aliased in the usual way, of blending partially covered pixels. So if two lines would occupy the same half of a pixel, the antialiasing blends it to 75% filled rather than 50% filled. With enough lines drawn on top of each other, the pixel blend clamps and you end up with aliased lines.
I know anti-grain geometry has algorithms for calculating blends which cater for lines which abut, and that oversampling might work, but are there any other approaches?
Handling this form of line composition well is going to be slow (you have to consider all the lines that impinge upon each pixel using a deferred rendering approach). I doubt that there are many (if any) libraries out there that will do it for you.
The quickest and easiest method (and possibly the only realistic and cost effective solution for your case), which will work with virtually any drawing library would be to supersample it - draw to an offscreen bitmap at much higher resolution (e.g. 4 times wider and higher, with lines of 4 pixels width. Disable antialiasing when drawing this as it'll only slow it down) and then scale the result down with bilinear filtering. The main down-side is that it uses a lot of memory for the offscreen bitmap.
If you need an existing system that gets antialiased lines "visually correct", you might try using one of several existing RenderMan-compliant 3D renderers. The REYES algorithm, which many of these renderers use, works by breaking up primitives into micropolygons, then sampling them at several random point locations within each pixel. So even if you have a million lines collectively obscuring 50% of a pixel, the resulting image value will show roughly 50% coverage. (This is, for example, how the millions of antialiased hairs are drawn on characters in many animated movies.)
Of course, using a full-blown 3D renderer to draw 2D lines is like driving nails with a sledgehammer. You'd need a fairly pathological scenario for the 3D renderer to be any more efficient than simply supersampling with a traditional 2D renderer.
It sounds like you want a premade drawing library, which I do not know of.
However, to answer your question of knowing any approach that would work, you can consider a pixel to be a square. You can then approximate any shape that you draw as a polygon that intersects the pixel box. By clipping these polygons against the box of the pixel and against each other, you can get a very good estimate of the areas associated with each color that intersects the pixel for accurate antialiasing. This is, of course, very slow to calculate and is not suitable for interactive drawing.

Resources