Transform bitmap characters into triangles - javascript

I am attempting to use an html canvas element to draw each character available in a font file to a canvas. To make this question as simple as possible, pretend only one character is drawn to a canvas. From there, I want to use Javascript to analyze the canvas and create triangle regions of the canvas that make up the entire character. The reason I need it in triangles is so that the data can later be sent to WebGL so text can be rendered and data will not be lost be scaling the text size up or down.
I am looking for some sort of algorithm to accomplish this or at least some knowledge to get me going in the right direction. If you believe I should use a different approach please tell me why, but I figured this would be the best to provide a way to modify text in many ways as well as make it possible to create 3d block text.

Here's an article on how to draw resolution independent curves with shaders
http://research.microsoft.com/en-us/um/people/cloop/loopblinn05.pdf
My understanding is instead of breaking the shapes into triangles you break them into quads with enough info sorted in the vertices to draw a portion of the curve inside each quad. In other words, as the shader draws each quad there's a formula that for each pixel can compute if that pixel is inside the curve or outside the curve.

I suggest you to start with the keyword Polygon Triangulation.
Using this methods, you can split n-Polygons into triangles like this:
These methods may only apply to figures with real (and not rounded) edges.

So, you are trying to convert a raster image into vector data?
When zoomed in, that will result in very jagged looking geometry.
Since each pixel is being treated as a square edged part of the geometry.
Couldn't you get your hands on the original vector (bezier curve) geometry for each glyph you are drawing?
Transforming that into triangle strips and fans would look smoother.

Related

Creating lines with thickness and shadows in three.js for visualising 3D printing layers

I have been trying to figure out a way of adding thickness to lines that can receive shadows and look like solid objects using Three.js but the best result I managed to get so far is just thicker lines that do not look like 3D geometry.
The application is for an online 3D printing platform so I am trying to visualise the sliced geometry that is comprised of lines, similar to how other slicing software handles this, such as cura, as shown in the image below.
Generating mesh geometry from these lines would be most probably problematic as in some cases there are thousands of a lines in a single model so it will be too heavy.
Any suggestions on how to achieve the desired result in either three.js or another javascript library would be greatly appreciated!
So the idea is to render primitive covering your thick line area and in fragment decide if fragment is inside or outside the thick line compute 3D position and normal and render or discard; if not.
The idea is to pass polyline geometry for rendering to OpenGL that would produce just thin lines and use shaders to do the rest.
Vertex shader
will just pass stuff into geometry shader
Geometry shader
will take in 2 vertexes (line) and output 2 triangles (quad) covering line BBOX (line enlarged by line half thickness). This is relatively easy. Simply shift the line endpoints by perpendicular vector to the line of size equal to the half thickness. This must be done in plane parallel with camera screen plane (using basis vectors extracted from direct camera matrix). Do not forget to pass both vertexes in world and camera coordinates.
Fragment shader
simply from world coordinates test if point is inside your thick line:
so simply compute P' and compute distance between P,P'. That is called perpendicular distance between point and line. Its doable exploiting dot product IIRC:
t = dot(P-P0,P1-P0)
P' = P0 + t*(P1-P0)
d = |P'-P0|
from that you just compute the 3D coordinate (depth of the fragment), normal and either render with some directional light or discard;...
Take a look at full example of this technique for 2D cubic curves:
rendering thick 2D Cubics in GLSL

Create line segment in Three.js with 2D shapes

I am using Three.js to render the graphical representation of a gerber file.
The specification allows you to render lines with either a circular or rectangular "aperture".
The result with a circular aperture should have round endings. The result with a rectangle is dependent on the orientation of the aperture as described in the specification.
The specification gives the following example images to illustrate.
What would be the best way to achieve this in Three.js?
The gerber specification further limits arcs to only being drawn with circular apertures, but assuming someone wanted to draw line segments in any arbitrary 2D shape what would be the best approach?
I know in 3D to perform a union it would probably be best to use Constructive Solid Geometry. I assume I could do the same in 2D by simply using an extruded form of the shape, but I would prefer to remain in 2D if possible.
The gerber format is basically just a binary rendering with Dark and Clear draw operations which either draw (Dark) or erase (Clear) what is being stroked. I figure the easiest way to achieve this would be to pick two colors (BG color and Shape color) and just draw primitives one after another with the most recent drawn on top. I figured this would be easier to manage restricting to 2D only. If someone has a better suggestion I would be interested to hear that as well.

How to generate 3D shape/plane from 2d pixel points/map?

For a 2d grey image, I want to extract each pixel's grey/brightness value as depth/z-index to generate a smooth 3d plane, something like a brightness level depth map.
My simple idea is that loop add each pixel as a point in the scene, and set z-index with grey value.
But, first how to add points(a very small one to represent a pixel) with Three.js?
And, is this a good way? is this a smooth plane? what if a large image(e.g. 2000*4800, I don't think memory can hold that much points)?

Algorithm for Image Sampling for Polygonal Representation using Canvas and JavaScript?

First off I'm not used to dealing with images, so if my wording is off please excuse me.
I am looking to take an image that is dropped onto a HTML5 canvas, sample it, do a reduction of the sampling, then create a polygonal representation of the image using mostly triangles with a few other polygons and draw that image to the canvas.
But I do not know where to start with an algorithm to do so. What sort of pseudocode do I need for this kind of algorithm?
This image may offer a better understanding of the end result:
I would do the following:
Create a field of randomly-placed dots.
Create a Voronoi diagram from the dots.
Here's a good JavaScript library that I've used in the past for this: https://github.com/gorhill/Javascript-Voronoi
Color each cell based on sampling the colors.
Do you just pick the color at the dot? Sample all the colors within the cell and average them? Weight the average by the center of the cell? Each would produce different but possibly interesting results.
If the result needs to be triangles and not polygons, then instead of a Voronoi diagram create a Delaunay triangulation. GitHub has 15 JavaScript libraries for this, but I've not tried any to be able to specifically recommend one.
Ok, it's a bit indirect, but here goes.....!
This is a plugin for SVG that turns images into pointilized art: https://github.com/gsmith85/SeuratJS/blob/master/seurat.js
Here's the interesting part. Under the hood, it uses canvas to do the processing!
The examples show images composed of "dots" and "squares".
Perhaps you can modify the code to produce your triangles -- even just cut the squares diagonally to create triangles.

Wraparound for HTML5 Canvas: How to Get (Static) Shapes to Continue around Edges of Canvas

I'm trying to draw a tiled background using Javascript on an HTML5 canvas, but it's not working because shapes that intersect the edges of the canvas don't wrap around to the other side. (Just to be clear: these are static shapes--no motion in time is involved.) How can I get objects interrupted by one side of the canvas to wrap around to the other side?
Basically I'm looking for the "wraparound" effect that many video games use--most famously Asteroids; I just want that effect for a static purpose here. This page seems to be an example that shows it is possible. Note how an asteroid, say, on the right edge of the screen (whether moving or not) continues over to the left edge. Or for that matter, an object in the corner is split between all four corners. Again, no motion is necessarily involved.
Anyone have any clues how I might be able to draw, say, a square or a line that wraps around the edges? Is there perhaps some sort of option for canvas or Javascript? My google searches using obvious keywords have come up empty.
Edit
To give a little more context, I'm basing my work off the example here: Canvas as Background Image. (Also linked from here: Use <canvas> as a CSS background.) Repeating the image is no problem. The problem is getting the truncated parts of shapes to wrap around to the other side.
I'm not sure how you have the tiles set-up, however, if they are all part of a single 'wrapper' slide which has it's own x,x at say 0,0, then you could actually just draw it twice, or generate a new slide as needed. Hopefully this code will better illustrate the concept.
// Here, the 'tilegroup' is the same size of the canvas
function renderbg() {
tiles.draw(tiles.posx, tiles.posy);
if(tiles.posx < 0)
tiles.draw(canvas.width + tiles.posx, tiles.posy);
if(tiles.posx > 0)
tiles.draw(-canvas.width + tiles.posx, tiles.posy);
}
So basically, the idea here is to draw the groupings of tiles twice. Once in it's actual position, and again to fill in the gap. You still need to calculate when the entire group leaves the canvas completely, and then reset it, but hopefully this leads you in the correct direction!
You could always create your tillable image in canvas, generate a toDataUrl(), and then assign that data url as a background to something and let CSS do the tiling.. just a thought.
Edit: If you're having trouble drawing a tillable image, you could create a 3*widthx3*width canvas, draw on it as regular (assuming you grab data from the center square of data as the final result), and then see if you can't draw from subsets of the canvas to itself. Looks like you'd have to use:
var myImageData = context.getImageData(left, top, width, height);
context.putImageData(myImageData, dx, dy);
(with appropriate measurements)
https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas/
Edit II: The idea was that you'd have a canvas big enough that has a center area of interest, and buffer areas around it big enough to account for any of the shapes you may draw, like so:
XXX
XCX
XXX
You could draw the shapes once to this big canvas and then just blindly draw each of the areas X around that center area to the center area (and then clear those areas out for the next drawing). So, if K is the number of shapes instead of 4*K draws, you have K + 8 draws (and then 8 clears). Obviously the practical applicability of this depends on the number of shapes and overlapping concerns, although I bet it could be tweaked. Depending upon the complexity of your shapes it may make sense to draw a shape 4 times as you originally thought, or to draw to some buffer or buffer area and then draw it's pixel data 4 times or something. I'll admit, this is some idea that just popped into my head so I might be missing something.
Edit III: And really, you could be smart about it. If you know how a set of objects are going to overlap, you should only have to draw from the buffer once. Say you got a bunch of shapes in a row that only draw to the north overlapping region. All you should need to do is draw those shapes, and then draw the north overlapping region to the south side. The hairy regions would be the corners, but I don't think they really get hairy unless the shapes are large.... sigh.. at this point I probably need to quiet down and see if there's any existing implementations of what I speak out there because I'm not sure my writing off-the-cuff is helping anybody.

Categories