Wanted to know how can I add transparent dots or lines over CGPath or NSBezierPath.
Here are more details about the problem.
I've a solid line say width = 30(drawn using NSBezierPath or CGPath) , now I wanted to draw transparent dots over it or transparent lines(thickness=2 or something smaller than 30).
You can enumerate the elements of an NSBezierPath or CGPath, and do something for each one.
For NSBezierPath, use elementCount, elementAtIndex:associatedPoints:, and a for loop. The elementAtIndex:associatedPoints: requires a C array of up to three NSPoints.
For CGPath, use CGPathApply. This takes a pointer to a C function that you have written. One of the two arguments to the function is a structure that contains the same information returned by elementAtIndex:associatedPoints:, except that it will create the array of points for you.
The element types are mostly the same between them:
A moveto or lineto carries one point.
You might wonder why a lineto doesn't have two points. The point associated with the element is the destination point—the to in lineto—that is the new current point immediately afterward. The other point, the one you're coming from, is implicit; in cases where you want to use it, you will simply have to remember the last current point.
A (cubic) curveto uses all three points.
As with lineto, the source point is implicit, being simply the last current point. The last point in the array is the destination anchor point; the two other points are the control points.
Core Graphics has quadratic curveto elements, which only have two points.
A cubic curveto has two control points and one anchor point; a quadratic one has only one control point and one anchor point.
NSBezierPath does not have quadratic curveto elements. All curveto elements in an NSBezierPath are cubic.
A closepath has no points. It returns to the point of the last moveto.
Either way, for each element, draw whatever anchor-point indicator you want. You could, for example, draw a blue circle at the destination point, and not draw anything for a closepath (since you already drew that when you encountered the matching moveto). For curveto elements, you might also want to draw an indicator for each of the two control points.
Use -bezierPathByFlatteningPath.
Once you have flattened copy of the receiver, compute its length.
Then, iterate through the flattened copy, which is basically an array of points. Keep track of the distance between successive points, so that you can see where you are exactly on the curve.
For example, if you want to draw multiple copies of an object, you have to find on which segment of the flattened copy the object will reside. Once you have found the segment, linear interpolate between the two ends of that segment to find the exact spot.
If this is what you want to achieve, I can elaborate a little and post the category I wrote that does this.
Related
Given a general polyline and an orthogonal grid, I would like to compute a simpler polyline whose vertices lie on the grid edges/vertices. This can look like this:
Left: A dense polyline as input, Right: A coarser polyline whose vertices lie on the intersection of the input polyline with the grid edges/vertices
(Sorry about the link to the image, but stack overflow apparently doesn't allow me to embed pictures before getting 10 credit points).
The grid is always orthogonal but its vertices do not necessarily have integer coordinates as some x or y lines might have coordinates defined by a previous geometric intersection computation. The initial curve can be represented as a polyline (though it would be nice to have also bezier curve support), not necessarily x-monotone, and it might intersect the grid also along whole edges.
My first thought was to call CGAL::compute_subcurves(..) with the grid lines and the curve I'm adding. I was hoping to get back a list of polylines, each composed of maximal multiple segments inside a face of the original grid. In practice even if the input is composed of polylines and the output of monotone polylines, I get back a list of separated segments. These include also the grid segments and also the polyline segments, and these are not ordered by "walking on the curve segments" as needed to compute the ordered interesection points. If they would have been ordered, a solution would be to iteratively go over them and check which one intersects the original grid, and then save the points.
Another option I thought of is to start with an arrangement of the grid lines, incrementally add polyline segements and have a notification mechanism notifying me on new edges that are pairwise disjoint in their interior, but in the case an edge of the intersected polylines is an original edge of the grid I won't get a notification and I'll miss it. Incrementally adding segments and checking for collisions also doesn't seem to be straightforward as the arrangement API do_intersect(..) seems to return at most a single point, while a given segment of the input polyline might easily intersect two grid lines next to a corner or even lie entirely on a grid segment.
I'm probably missing some simple solution. Can someone give me a pointer, or some api call that might help here?
Edit: There might have been a confusion. The grid is orthogonal but not necessarily regular and might have coordinates that could not globally scale to integers such as here.
Use Arrangement_with_history_2 (instead of Arrangement_2); see https://doc.cgal.org/latest/Arrangement_on_surface_2/classCGAL_1_1Arrangement__with__history__2.html. After you compute the arrangement, you can use point location to locate the end points of your polylines in the arrangement. Then, for each one, you can easily follow the original curve. If you are concerned with performance, you can try inserting (at least) the grid lines incrementally. Another option is to extend the halfedge records and insert the grid lines and each polyline separately. With the appropriate observer, you can mark the generated halfedges that correspond to a given polyline uniquely. I think you can even save the extra point location, by locating one of the two end points of a polyline before inserting it, and then provide the resulting location to the (incremental) insertion function.
I want to create a shader to outline 2D geometry. I'm using OpenGL ES2.0. I don't want to use a convolution filter, as the outline is not dependent on the texture, and it is too slow (I tried rendering the textured geometry to another texture, and then drawing that with the convolution shader). I've also tried doing 2 passes, the first being single colorded overscaled geometry to represent an oultine, and then normal drawing on top, but this results in different thicknesses or unaligned outlines. I've looking into how silhouette's in cel-shading are done but they are all calculated using normals and lights, which I don't use at all.
I'm using Box2D for physics, and have "destructable" objects with multiple fixtures. At any point an object can be broken down (fixtures deleted), and I want to the outline to follow the new outter counter.
I'm doing the drawing with a vertex buffer that matches the vertices of the fixtures, preset texture coordinates, and indices to draw triangles. When a fixture is removed, it's associated indices in the index buffer are set to 0, so no triangles are drawn there anymore.
The following image shows what this looks like for one object when it is fully intact.
The red points are the vertex positions (texturing isn't shown), the black lines are the fixtures, and the blue lines show the seperation of how the triangles are drawn. The gray outline is what I would like the outline to look like in any case.
This image shows the same object with a few fixtures removed.
Is this possible to do this in a vertex shader (or in combination with other simple methods)? Any help would be appreciated.
Thanks :)
Assuming you're able to do something about those awkward points that are slightly inset from the corners (eg, if you numbered the points in English-reading order, with the first being '1', point 6 would be one)...
If a point is interior then if you list all the polygon edges connected to it in clockwise order, each pair of edges in sequence will have a polygon in common. If any two edges don't have a polygon in common then it's an exterior point.
Starting from any exterior point you can then get the whole outline by first walking in any direction and subsequently along any edge that connects to an exterior point you haven't visited yet (or, alternatively, that isn't the edge you walked along just now).
Starting from an existing outline and removing some parts, you can obviously start from either exterior point that used to connect to another but no longer does and just walk from there until you get to the other.
You can't handle this stuff in a shader under ES because you don't get connectivity information.
I think the best you could do in a shader is to expand the geometry by pushing vertices outward along their surface normals. Supposing that your data structure is a list of rectangles, each described by, say, a centre, a width and a height, you could achieve the same thing by drawing each with the same centre but with a small amount added to the width and height.
To be completely general you'd need to store normals at vertices, but also to update them as geometry is removed. So there'd be some pushing of new information from the CPU but it'd be relatively limited.
I have an array set of (x,y) values that define a polygon. The polygon is drawn based on the point's position * a pencil size. The thing is that i want to draw the border of such shape, ignoring the inner vertexes. See this example, the BLACK vertex are the ones i'm interested in, i want to get rid of the YELLOW ones.
I'd like to get the X in another array, ordered clockwise. Been thinking about evaluating every point to see if has a neighbor and where (north, south, east, west) but seems like too much crunching to check in every vertex and i believe must be another proven and more elegant algorithm.
Any tip?
Since your "points" are just little squares, it sounds like your inner points (those which don't contribute to the border of the shape) are just those where (x-1,y), (x+1,y), (x,y-1), and (x,y+1) are also all points.
You can do that test quickly by putting all of your points in a hashtable (or one of many other indexed structures).
Ordering clockwise just requires walking the border. You have to decide what you'd like to do about holes, if there are any.
Normally, a polygon is defined by an outline. That's an unfortunate format you have to deal with there.
If they're laid out like that (in rows with the same y coord) then you can just sort the array, first by x and then by y, then take the first point, the two points around any change in y, and the last point to form your outline.
If the real state of things is a little messier, then you might want to look into 'alpha shapes'. Some links: http://biogeometry.duke.edu/software/alphashapes/, http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/belair/alpha.html
Make sprite borders, place it same position every square and sorting oderlayout behind
I have an application where the user can drag their images (.pngs) around on a virtual table.
The images are of shapes - mostly regular polygons, but some jigsaw pieces, tetris blocks, et cetera.
I want the shapes, as they are being dragged, to snap to one another like two jigsaw pieces might.(Like in MS Word "Snap to grid")
How might I accomplish this?
Constraints:
Speed:
This will be either happening as the user drags the image, or at the point of dropping. Therefore the algorithm must be fast (realtime). Any number of images may be being dragged, and there may be any number of stationary images to snap to.
No further user input:
There should be no requirement for the user to do anything beyond opening the image file, and drag the images.
Possibilities:
Use some sort of concave hull algorithm + simplifaction, then match edge lengths.
The issue with this is that the user's edges can't be guaranteed to be that straight/well defined.
Use a laplace transform on the transparency component of the image (To edge-detect), then treat those regions as being positively and negatively charged, and use a physical simulation to find how they snap together. Limitation: Speed, tuning.
I am currently just assuming the images are one of the regular tessellations: Rectangle, triangle or hexagon, and working from there. But i'd prefer something which works with other shapes.
Each shape should have some reference points and a (possibly curved) line between them. If you need to snap two shapes then the easiest would be to match those reference points first, and if they match then you can match the lines between each two pair of points. Lines should be coded in such a way that you don't need some mathemathical processing to match them, just match the parameters of the lines.
Take tetris blocks. Each block has reference points on grid crossings, and each line is a straight line. A square shape would have 8 points and lines, and L shape would have 10 points/lines. First match reference points, and then match if same points on each shape have the lines between them (and take line orientation into regard).
Take jigsaw puzzles. Usually you have 4 points/lines, but lines are some arbitrary curves. You can actually use mathematical curves, but you can also have some jigsaw curve index for each curve. When you try to match two pieces first you match reference points, and then you match curves by simply comparing their indexes, in regard to both their line orientation and their index pairings.
I have a map that is cut up into a number of regions by borders (contours) like countries on a world map. Each region has a certain surface-cover class S (e.g. 0 for water, 0.03 for grass...). The borders are defined by:
what value of S is on either side of it (0.03 on one side, 0.0 on the other, in the example below)
how many points the border is made of (n=7 in example below), and
n coordinate pairs (x, y).
This is one example.
0.0300 0.0000 7
2660607.5 6332685.5 2660565.0 6332690.5 2660541.5 6332794.5
2660621.7 6332860.5 2660673.8 6332770.5 2660669.0 6332709.5
2660607.5 6332685.5
I want to make a raster map in which each pixel has the value of S corresponding to the region in which the center of the pixel falls.
Note that the borders represent step changes in S. The various values of S represent discrete classes (e.g. grass or water), and are not values that can be averaged (i.e. no wet grass!).
Also note that not all borders are closed loops like the example above. This is a bit like country borders: e.g. the US-Canada border isn't a closed loop, but rather a line joining up at each end with two other borders: the Canada-ocean and the US-ocean "borders". (Closed-loop borders do exist nevertheless!)
Can anyone point me to an algorithm that can do this? I don't want to reinvent the wheel!
The general case for processing this sort of geometry in vector form can be quite difficult, especially since nothing about the structure you describe requires the geometry to be consistent. However, since you just want to rasterize it, then treating the problem as a Voronoi diagram of line segments can be more robust.
Approximating the Voronoi diagram can be done graphically in OpenGL by drawing each line segment as a pair of quads making a tent shape. The z-buffer is used to make the closest quad take precedence, and thus color the pixel based on whichever line is closest. The difference here is that you will want to color the polygons based on which side of the line they are on, instead of which line they represent. A good paper discussing a similar algorithm is Hoff et al's Fast Computation of Generalized Voronoi Diagrams Using Graphics Hardware
The 3d geometry will look something like this sketch with 3 red/yellow segments and 1 blue/green segment:
This procedure doesn't require you to convert anything into a closed loop, and doesn't require any fancy geometry libraries. Everything is handled by the z-buffer, and should be fast enough to run in real time on any modern graphics card. A refinement would be to use homogeneous coordinates to make the bases project to infinity.
I implemented this algorithm in a Python script at http://www.pasteall.org/9062/python. One interesting caveat is that using cones to cap the ends of the lines didn't work without distorting the shape of the cone, because the cones representing the end points of the segments were z-fighting. For the sample geometry you provided, the output looks like this:
I'd recommend you to use a geometry algorithm library like CGAL. Especially the second example in the "2D Polygons" page of the reference manual should provide you what you need. You can define each "border" as a polygon and check if certain points are inside the polygons. So basically it would be something like
for every y in raster grid
for every x in raster grid
for each defined polygon p
if point(x,y) is inside polygon p
pixel[X][Y] = inside_color[p]
I'm not so sure about what to do with the outside_color because the outside regions will overlap, won't they? Anyway, looking at your example, every outside region could be water, so you just could do a final
if pixel[X][Y] still undefined then pixel[X][Y] = water_value
(or as an alternative, set pixel[X][Y] to water_value before iterating through the polygon list)
first, convert all your borders into closed loops (possibly including the edges of your map), and indentify the inside colour. this has to be possible, otherwise you have an inconsistency in your data
use bresenham's algorithm to draw all the border lines on your map, in a single unused colour
store a list of all the "border pixels" as you do this
then for each border
triangulate it (delaunay)
iterate through the triangles till you find one whose centre is inside your border (point-in-polygon test)
floodfill your map at that point in the border's interior colour
once you have filled in all the interior regions, iterate through the list of border pixels, seeing which colour each one should be
choose two unused colors as markers "empty" and "border"
fill all area with "empty" color
draw all region borders by "border" color
iterate through points to find first one with "empty" color
determine which region it belongs to (google "point inside polygon", probably you will need to make your borders closed as Martin DeMello suggested)
perform flood-fill algorithm from this point with color of the region
go to next "empty" point (no need to restart search - just continue)
and so on till no "empty" points will remain
The way I've solved this is as follows:
March along each segment; stop at regular intervals L.
At each stop, place a tracer point immediately to the left and to the right of the segment (at a certain small distance d from the segment). The tracer points are attributed the left and right S-value, respectively.
Do a nearest-neighbour interpolation. Each point on the raster grid is attributed the S of the nearest tracer point.
This works even when there are non-closed lines, e.g. at the edge of the map.
This is not a "perfect" analytical algorithm. There are two parameters: L and d. The algorithm works beautifully as long as d << L. Otherwise you can get inaccuracies (usually single-pixel) near segment junctions, especially those with acute angles.