How to order shapes on a canvas - JavaScript - javascript

I want to make a shape (an XP bar) to always be ordered at the top of all shapes drawn.
How would this be possible, (I also use p5.js too, if that helps.) other than drawing it last (which I cannot do in my situation).

You've got two main options:
Option one: Draw it last. This is the easiest way to do it. If you "cannot" do it this way for some reason, that sounds like you need to refactor your code then.
Option two: Use 3D coordinates to draw it with a Z coordinate that's closer to the user. Most drawing functions can take 3D coordinates instead of 2D coordinates. This should work, but it's more complicated than just drawing it last.

Related

Finding coordinates of polygon in a canvas

I have draw several polygons in a canvas. I am now interested in how to find the coordinates (vertices) of the selected polygon. I can find the selected polygon (region) using mouse coordinates, but I need to redraw it if it is selected, which is why I need its coordinates to do that.
A similar answer that I found so far is this one https://help.geogebra.org/topic/-solved-how-do-i-get-a-list-of-coordinates-from-a-polygon- using GeoGebra, but I am using HTML5 and JavaScript!
Once you draw something on a canvas, you can not get the coordinates of the object you drew unless you have some image processing algorithm.
Instead, you need need to keep the polygon object you drew on the canvas in memory and you need to define it's boundaries on the canvas.
This way, when the user clicks on the canvas, you simply get the mouse coordinates on the canvas and you calculate which polygon was clicked by checking where you drew your polygon and checking if the mouse clicks enters the boundaries of this polygon.
Sounds like you are trying to solve a couple different problems:
1) Figure out which polygon the user clicked. As was mentioned, if you are keeping an array of your polygons in memory, and can implement an isPointInPath method, then you can loop through your in-memory polygons and check if any of them were clicked. Don't forget that to get an accurate check, you may need to take your given "mouse x" and "mouse y" coordinates (from a click event, for example) and subtract the canvas's page X and Y coordinate.
(See the SO answer How do I get the coordinates of a mouse click on a canvas element? for more detail.)
2) Once you've determined the user has clicked polygon P, you want to redraw it. You should be able to redraw it no problem, by simply redrawing the same polygon using the same coordinates as before (for example, you could change your strokeStyle or fillStyle to a different color to represent the selection).
If you want to make the polygon larger and in the same position, that's a different question - basically, you need to translate the canvas to the center of the polygon, then scale the canvas, then draw your polygon. If this is new to you, there's a tutorial available at http://codetheory.in/canvas-rotating-and-scaling-images-around-a-particular-point/ (uses images instead of polygons, but same concept).
Note that if your polygon is complex, even determining the right point to scale around may be difficult. The question "what is the center of a complex polygon" has several different answers; a simple answer is to average all of the polygon's point's X and Y values (Center X = avg(X), Center Y = avg(Y)). If that doesn't look right, there are more complicated approaches available in another SO question, What is the fastest way to find the "visual" center of an irregularly shaped polygon? .
Hope this points you in the right direction!

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.

Enclose multiple separate sets of points using polygons which stack next to each other

I am working on a data set of coordinate points(many dots in area) either (x,y) or (lat,lon) which fall into multiple categories. What I am trying to do is get polygons of areas from those points which are called concave or non-convex as far as I know, but also those polygons have to be next to each other with no gaps between them.
These are the initial points(example)
This is the approximate result I am aiming for
Real life example would be European geopolitical map, if you had all of the addresses of all countries and wanted to get area of each country as a polygon and end up with a map.
I have come across many questions related to getting polygons from set of points, but were unable to use it in my scenario. If you need any more information please let me know. Thank you for your help.
You could use a Voronoi tesselation of the input space. Instead of having point you have sets of points though. Basically, you take each point in space, and look at the closest point to it. It then gets the same "class" as that point. For smoother outputs you could look at a k majority out of N nearest points. It would mean working with a bitmap image rather than 2D coordinates, but you'd get something workable. You could then use simpler image manipulation tricks (edge detection, binary set operations etc to get just the edges, and then perhaps superimpose those on the image).
As an alternative, you could run a convex hull algorithm on each data set, and then try to fix the overlap areas.

Transform bitmap characters into triangles

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.

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