Drawing a line with hidden parts in cocos2d for ios - ios

Say you have an array of points and an array of rects, and you want to do the following:
Draw a line that connects all the points in the point array, such that the parts of the line that are contained in at least one of the rects are not visible.
What is the best practice way to accomplish such a task in cocos2d ios?

This may sound like a hack, but if you are drawing the rectangles as well then you can draw them with a higher zOrder with respect to the line and the rectangles would could cover the parts of the lines they contain making those parts invisible.
Hope it helps!

Related

Draw text along a path on a map (like f.e. a street-name)

I am currently trying to label lines that I draw in my Map (in my iOS app, but I guess it applies to all maps).
So what I currently am doing, I simplify my path so that I get rid of most small curves and then just draw my glyphs along that line. Currently that looks like this:
On some parts of the line that's already ok. If the line is quite straight and the corners aren't too spiky.
But in some parts you can just not read anything... So what are strategies to make that look nicer?
Does anybody know an algorithm or a strategy on how to make my path look like the red line here:
I am happy about any ideas on how to improve my drawing :)
I do it, in my commercial map rendering system, by finding a portion of the line without sharp corners. There is no way to make the label look good if it turns corners of a right angle or greater. If there's no section long enough I abbreviate the label (e.g., Link Road becomes Link Rd), or split it on to two lines. If there's still nowhere to draw the label I don't draw it.
Another thing that's important is to adjust the spacing so that ascenders and descenders don't clash, so you need to look at the bounding box of each adjacent pair of letters as you draw the text and add small amounts of space as necessary.
I don't bother to smooth my lines, as you suggest with your red line. It really doesn't seem to matter, at least with street labelling.

Two UIViews overlaped

I have two UIViews, each one has draw a car(vectorgraph), now if a car(A) behind another car(B), then I want the overlaps in A be dashed.
the car was drawn by UIBezierPath, I want the overlaps in A's path become dashed, how can I do this?
Thank you for your helping!
I don't think there is any way to do this automatically. You would need to calculate the bounding rectangle of the intersection of the 2 views, and then manually parse the path of car A into 2 parts, the part that's covered and the part that's not, and draw the covered part using dashed lines.
This is original development that you would have to do yourself.
Erica Sadun's outstanding "iOS Developer's Cookbook" series has a recipe that shows how to parse a bezier path segment by segment. Figuring out the portion of the path that is inside the intersection range will involve some tricky programming.

How can I draw an image with many tiny modifications?

I am drawing many audio meters on a view and finding that drawRect can not keep up with the speed of the audio change. In practice only a very small part of the image changes at a time so I really only want to draw the incremental changes.
I have created a CGLayer and when the data changes I use CGContextBeginPath, CGContextMoveToPoint, CGContextAddLineToPoint and CGContextStrokePath to draw in the CGLayer.
In drawRect in the view I use CGContextDrawLayerAtPoint to display the layer.
When the data changes I draw just the difference by drawing a line over the top in the CGLayer. I had assumed it was like photoshop and the new data just draws over the old but I now believe that all the lines I have ever drawn remain present in the layer. Is that correct?
If so is there a way to remove lines from a CGLayer?
What exactly do you mean by 'audio meter' show some snapshots of your intended designs. Shows us some code...
These are my suggestions-
1) Yes the new data just draws on top of CGLayer unless you release it CGLayerRelease(layer)
2) CGContextStrokePath is an expensive operation. You may want to create a generic line stroke and store them in UIImage. Then reuse the UIImage everytime your datachanges.
3) Simplest solution: use UIProgressView if you just want to show audio levels.
I now believe that all the lines I have ever drawn remain present in the layer. Is that correct?
Yes.
If so is there a way to remove lines from a CGLayer?
No. There is not. You would create a new layer. Generally, you create a layer for what is drawn repeatedly.
Your drawing may be able to be simplified by drawing rects rather than paths.
For some audio meters, dividing the meter into multiple pieces may help (you could use a CGLayer here). Similarly, you may be able to just draw rectangles selectively and/or clip drawing, images, and/or layers.

Drawing a non rectangular part of a picture in delphi canvas

Can anyone share a sample code to draw a non-rectangular part of a picture in delphi canvas?
You're looking for GDI paths. Start here, which explains what paths are in this context, and provides links on the left to explain the functionality available with them.
Google can turn up lots of examples of using paths in Delphi. If you can't find them, post a comment back here and I'll see what I can turn up for you.
Your question is pretty vague. But I suspect what you are looking for is clipping regions. Read up on them. Set the clipping region on the target device to the shape you want, and then draw the image onto the device. Only the part of the image that would be within the clipping region will be drawn.
Canvas.Ellipse(0, 0, 10, 20); // not a rectangle
I use so called runlists for this feature (generalized shapes and blitting them). I've seen them called warplists too. A shape is encoded as a runlist by defining it as a set of horizontal lines, and each line is two integer values (skip n pixels,copy n pixels).
This means you can draw entire lines, leaving you with only "height" draw operations.
So a rectangle is defined (the first "skip" pixels from top level corner to the left corner (xorg,yorg). The rectangle is width_rect wide, and width_pixels goes a line further. width_pixels can be wider than the width of the picture (alignment bytes)
(yorg*width_pixels+xorg , width_rect),
(width_pixels-width_rect , width_rect),
(width_pixels-width_rect , width_rect),
(width_pixels-width_rect , width_rect),
..
..
This way you can make your drawing routines pretty generic, and for simple, regular shapes (rects, circles) it takes only minor math to precalculate these lists. It simplified my shape handling enormously.
However I draw directly to bitmaps, not to canvasses, so I can't help with that part. A primitive that efficiently draws a row, and a way to extract a row from a graphic should be enough.

Drawing dashed borders

Imagine you are drawing a map of county borders. You are given a set of polygons, one for each boundary, and you draw each polygon.
In places where two counties share a border you just end up drawing the border twice. In the absence of partial transparency effects, and with a solid pen, this is no problem.
But, on maps, borders of this kind are customarily shown by dash-dotted lines. In this case, situations like the one depicted below can happen:
Notice how the dash pattern, which normally is dash-dot-dot, gets screwed up where the two areas share a border. In this case, it happened to become a longdash-dot pattern, but in general it could do anything from coincidentally looking normal to creating a solid line.
How does/should map rendering software prevent artifacts of this kind from occuring?
The artifact is due the fact that the piece of border is drawn twice. Instead of trying to supress such artifacts, you could try to not draw border sections twice, by keeping a list of segments already drawn in memory, and if you encounter a stretch that's already drawn, you don't draw it again.
Your brush pattern colors some pixels black and leaves some pixels alone. Instead of leaving the pixel alone, can you set up your brush pattern to color those pixels white (or whatever your background color is)?
Another possibility is to always draw your county borders twice -- once with a solid white pattern, and again with the brush pattern of your choice.
I suppose they break their border lines into segments, then remove the overlaps.
This is mostly a geometric problem, not a drawing problem.
Instead of going with a dashed line, you could do it Zip-a-tone style, like this:
Zip-a-tone was this graphic art stuff that was basically a sticky sheet of plastic with a regular (printable) pattern of dots on it. To use it, you would lay a big sheet of it over your drawing and cut it around the areas on your drawing that you wanted zip-a-toned, and then peel off the parts you didn't want.
For this image, I just went with an alternating checkerboard pattern, with the lines two pixels wide. Because all the lines are drawn from one big (virtual) block of this checkerboard pattern, you never have to worry about weird artifacts at the joints or any overlap effects.
Angled lines are a bit tricky, but basically you imagine the edges of the line sort of cutting through pixels, and thus you draw them at the appropriate shade of grade instead of full black (in the case of the 45 degree line here, the pixels are drawn with RGB(170, 170, 170), but any angle could be rendered with appropriate shades).
I'm not sure if GDI+ could do this easily using the textured brushes, but maybe. Otherwise you'd have to custom-code it. The advantage of this method over just solid gray lines would be that this would allow some of the background to show through.
This is an interesting question that I never really thought about. I think the only real solution is to render the entire complex figure as a series of lines or paths that do not overlap anywhere. I'm not surprised that GDI+ doesn't handle this situation in any automatic way.

Resources