I have a bunch of identical CALayers that I want to reuse. Often, a few of them should disappear, and then get reused in another position within the same superlayer (half a second or so later).
What is the best way (performance-wise) to keep them while they have disappeared from the screen? setHidden:YES, or setOpacity:0, or removeFromSuperLayer ? Or something else I am not thinking of?
(There are about 12 identical circle shaped CALayers with contents from a UIImage, and about 30 CAShapeLayers each one holding just a line segment -though usually in different orientations-)
You should use an nsset or nsarray to maintain a queue of unused calayers. The process would be similar to what you do when using tablecells.
As each calayer is removeFromSuperLayer'd, put it into your set and pull one out from the set when you need one.
The three you mentioned seem like all reasonable things to try. You really should test each one and see which gives your application the best performance, the results might surprise you.
Related
I am doing a project on face recognition. I have a dataset containing image of 21 actors(each 150). Now I want to increase the no. of image of each actor to 300+ for the training purpose. How can I do it using MATLAB. Some solutions can be we can vary the contrast/brightness level of each image. But what are some other factors through which I can increase the no. of images.
One option is for you to flip the images: If a person is looking to the right, after the flip he will be looking to the left.
Further more, depending on your possible toolkit and set of skills, you could do some more advanced technique. If you can find some interesting characteristic from the pictures, like: eyes, nose, mouth, background. With those, you could make some intelligent transformations - swap peoples eyes, change the background, switch noses.
There are some particular objects of the faces which you could also distort - like the eyes and nose - stretch them. Maybe for bold guys you could built some synthetic hair, and so on...
You could do the contrast/brightness level change, but usually it doesn't do so well, as your features probably doesn't have (almost) anything to do with it, so it will just be a duplication of your data.
Anyway, as it's not a very large data set, if you don't have the set of skills to pull the more advances options I proposed, or the time to deal with it, you can make some of those stuff manually. It won't take you as much as you think. And usually, with that amount of data, this will give a good boost to your results.
What you are looking for is called "data augmentation". Common transformations are mirroring (flipping left / right side of the image) and rotation of the image. You might also be able to zoom (crop) a part of the image.
Maybe scaled versions with the rotated ones may help. If your features are not robust to the changes such as lightning contras etc you can modfy the images accordingly.
I want to draw many spheres.They are all the same but the position.When the number of spheres increase to 10,000, it become very slow. I would if there is any method to draw same things quickly?
I did some experiments to find the problem.
At first I instantiate a simple object with 224 verts 10,000 times with dynamic batching. the result is like this:
Then I add two faces to the object and instantiate it 10,000 again. There is no batching but become quicker:
Third time I increase the verts 100 times and instantiate it 100 times. It become much quicker:
I wonder where is the different between them. Maybe I should use static batching to increase the speed?
What you are looking for is called instances. Here is a starting ressource for you:
http://docs.unity3d.com/ScriptReference/Object.Instantiate.html
Depending on what it is that you want to instantiate a thousand times, you can also checkout the concept of a billboard. It is basically a planar object with a fixed texture that will always face the camera no matter from what perspective you look at it. It is mainly used for things that are far away or should not use too much performance (e.g. grass).
Another thing that you need to watch out for is how many times you make draw calls. Try to use draw call batching, when possible.
I need to create an algorithm to layout some hierarchical data but have never done this kind of thing before and need some broad tips.
Basically I need to recreate this diagram (with dynamic data):
diagram http://dl.dropbox.com/u/15126868/diagram.png
bigger
I don't have a problem with most of it but need help with two things:
How do I approach writing a layout algorithm?
Should I use UIView subclasses for all discs or use quartz (I do need interaction)
Any suggestions most welcome. I don't need too much detail.
A bit more detail:
I'm currently thinking I should use UIView subclasses and layoutSubviews. Trouble is I need to know the size (at least roughly) of all nodes before I can start to position them. Then, as the positioning involves rotation, I may need to adjust child positioning again - and I can't add labels until after any rotation.
Other considerations seem to be: that the presentation area is rectangular, not square; that I can't spill off the page; and that I will need to animate changes to the sizes of the discs.
Any pointers would be great, thanks.
This sort of thing is very difficult.
Interestingly the perhaps main actual initial constraint here is the size of the typography.
In the example given: Observe they could have chosen a different SCPT** somewhat larger (perhaps, 10%-15% larger) or somewhat smaller and it would have still worked. They made an aesthetic decision on the SCPT.
White space is critical to design. Their particular graphic designer happened to like the particular feel of white space which you see. But it would have by no means been "wrong" with a smaller SCTP. Further, observe they could have used an even larger SCPT ... IF ... they used a smaller point size on the typography.
Note that in any event you simply won't be able to display that much type that small on an iPad (or Fone4).
So straight away you have to make decisions about how the type will appear, popup, audio or whatever. Even the white type ("on the discs" type) will give you trouble.
You will have to do lots of tests with photoshop first on to your iPad before even proceeding with an algorithm. So purely for what it's worth...
Here's how I personally would do this sort of thing. In general plan: I would try to do a squishy algorithm that retries itself until it finds a result it is happy with.
IMHO, based on previously doing this type of thing: this problem is too hard to get it done in one go with some particularly smart-ass heuristic. Since there is no one smart-ass heuristic that will save the day, I'd do this:
1) calculate the total trillions to display. (it looks like about 2.5 is the total in the example image)
2) guess a SCPT value to begin with. what about for example "18" based on the actual image at the screen size we see above as posted inside your question.
3) put the big one (sun) in the dead center, and for the middle ones (planets) -- just choose a very easy heuristic, what about from biggest to smallest going anticlockwise srtaing at the top left (don't try to get clever than that with that part of the problem - which indeed could be a huge research project purely on it's own) .. and do the same with the small ones (moons).
4) for the sticks between planets and moons - adopt a trivial solution (like "always 0.5 cm"!!) and that's that. with AI you gotta cut your losses .. everywhere! :) Fix the moons to the planets and forget about them.
5) Now a hard part .. run some sort of heuristic over them that evenly balances what you have so far. treat color as mass and no color as no mass and move the "sun" until it is balancedish. (to be clear, as an example that would be likely downwards if you followed the "planet" layout mentioned in 3.) maybe also move all the planet/moon systems in-out to try to balance it.
6) next the iteration. look at that result and decide if you like it! go back to (2) and pick a new value. (maybe "16!" for example)
(7) there are two possible outcomes here. it might be that during development, there is one magic value for SCPT that always works. perhaps "14.3" or "18.2" or whatever. if you find such a value, never tell anyone. keep it as your own secret information!!!! milk it for everything it is worth with clients. conversely and more difficultly, you might find you need a different value each time. in that case: your AI will have to on it's own iterate through values until it finds one it likes. (for example, by determining whether all your labels fit or not .. and obvious things like "are they touching" "all on screen" etc.)
Anyway FWIW (perhaps nothing) that is what I would do - an iterative approach based on a first guess for the SCPT.
Incidentally: you may well want to buy and study the classic and brilliant book on this sort of display of information!!! Everyone should have a copy.
Tufte's The visual display of Quantatative Information
by Edward R. Tufte
ISBN 0961392142
Regarding the mechanics of laying out the image. You should use quartz or any other low-level drawing - forget about UIViews and the like. You should surely completely separate the logic from the drawing layer, so (even if you do want to change to UIViews, OpenGLES, or whatever) it's only changing a few lines of code.
Hope it helps somehow.
Notes...
** SCPT .. square centimeters per trillion
Followup...
"To keep the logic separate would you use a manager-type pattern?"
To be honest: if I was doing it, I would just start a whole new app purely for the "research" of getting this part, this challenge, working right. In that app (to be honest!) I would make bugger all effort to do anything in any tidy manner whatsoever! :-/ Globals everywhere! :) Unfortunately for me I can only think of the one thing at a time, so at that stage I would only be thinking about the algorithm, per se.
I believe, once you cracked the problem per se, once you came to implement it in a bigger project ... really, FWIW, if it was me, I'd simply make it a class (let's say AmazingClass) nothing more complicated than that. Personally I would set the data somewhere separately (whether in a DB or just an array or whatever) and I would just let the AmazingClass take care of getting the data, even. (My thinking - you never know how the hell you're going to need the data and when, at what point in the process of AmazingClass. So, just give up and let AmazingClass take it as and when it wants it.)
If you are familiar with these awesome-sounding manager-patterns of which you speak - yeah, why not! In short I would heavily separate it out as much as possible. I'm not good enough to speak on the best way to do that - but just completely separate it out somewhere. Sorry I can't help on that one.
Shark complains about a big performance hit with this line, which takes like 80% of CPU time. I have a counter that is updated very frequently and performance seriously sucks.
It's an custom UILabel subclass with -drawRect: implemented. Every time the counter value changes, this is used to draw the new text:
[self.text drawInRect:textRect withFont:correctedFont lineBreakMode:self.lineBreakMode alignment:self.textAlignment];
When I comment this line out, performance rocks. Its smooth and fast. So Shark isn't wrong about this. But what could I do to improve this? Maybe go a level deeper? Does that make any sense?
Probably drawing text is really so incredible heavy...?
There's no reason the drawing of a single label should cause such a massive performance hit. If you're updating it more than 30-60 times per second, though, the system may have trouble keeping up. In that case, you could use an NSTimer to only perform the drawing at fixed intervals. There's no doubt that drawing text is expensive, but you've pretty much found the optimal way of doing the drawing itself, unless the label is only a single line, in which case you can use the slightly cheaper drawAtPoint:withAttributes:
Underneath, the text is being drawn with Quartz2D. You might see some improvement if you use it directly.
Simple Painting:
Fingering the iPhone screen paints temporary graphics to a UIView. These temporary graphics are erased after a touch ends, and are then stored into an underlying UIView.
The process is simple:
1) Touch Starts & Moves >>
2) Paint Temporary Graphics on top UIView>>
3) Touch Ends >>
4) Pass Temporary Graphics To underlying UIView >>
5) Underlying UIView adds Temporary Graphics to Stored Graphics >>
6) Underlying UIView Re-Draws all Stored Graphics >>
7) Delete Temporary Graphics on top UIView.
In this manner, I can accumulate graphics on the underlying UIView while maintaining responsive painting of the temporary graphics on the top UIView.
(Sidenote: Each "Drawing" is simply an NSArray of custom "Point" Objects which are just NSObject containers for CGPoints. And the underlying UIView has a seperate NSArray, where it stores these NSArrays of CGPoints)
The Problem Is:
When a great deal of graphics has accumulated on the underlying UIView, it takes time to draw it all out on the screen. And any new drawings on the top UIView will not be displayed until the drawing of the underlying stored graphics is complete. Thus, there is a noticeable lag when many graphics are on the screen.
Question:
Can anyone think of a good way to improve performance here, so that there is no noticable lag between drawings when there are a lot of graphics on the screen?
An NSArray of CGPoints? You mean an NSArray of NSValues holding CGPoints? That's an incredibly time-expensive way to hold what has to be a huge number of values that you access constantly. You could store this information in many better ways. A 2-dimensional C-array representing the entire screen is the most obvious. You may also want to look into bitmap image representations, and draw directly into a CGImage rather than maintaining a bunch of CGPoints. Take a look at the Quartz 2D Programming Guide.
EDIT:
Your object (below) is the equivalent of an NSValue, just a little more specialized. There's a lot of overhead going on here when you have many, many objects (~100,000 I'm guessing when the screen is nearly full; more if you're not removing duplicates; run Instruments to profile it). Old-style C data structures are likely to be much faster for this, because you can avoid all the retains/releases, allocations, etc. There are other options, though. Duplicate point checking would be much faster with an NSMutableSet if you pixel-align your CGPoints, and overload -isEqual on your Point object.
Do make sure you're pixel-aligning your data. Drawing on fractional pixels (and storing them all), could dramatically increase the number of objects involved and the amount of drawing you're doing. Even if you want the anti-aliasing, at least round the pixels to .5 (or .25 or something). A CGPoint is made up of two doubles. You don't need that kind of precision to draw to the screen.
Why not just draw everything onto a CGBitmapContextRef buffer so the drawing operations will accumulate, and then draw that to the screen in your drawRect:? You will be able to perform arbitrary graphics operations without slowing down as the total number of operations increases.
If undo support is necessary, one could always keep a copy for each change made and invalidate the oldest copies when a memory warning is received. (or for an even fancier solution, store the operations as you do now, but keep a cached copy every dozen user operations or so)