Is there a good way to handle a large number of hotspots on a PictureBox in a WinForm? We're talking potentially hundreds. I know a couple of ways I could do this, but none of them seem to be particularly expedient. I know I can use a MouseMove event and compare the coordinates to see if the mouse is within a given rectangle, but this will likely become inefficient with more than just a few hotspots to check. I could alternatively generate lots of invisible Panels to capture the mouse events, but I'm not sure if this would ultimately be any more efficient than storing and checking against hundreds of Rectangles. I think a k-d-tree of some sort might work, but that may be seriously over-engineering this problem. I'm wondering if there's some sort of already-existing (and optimized) system in WinForms for dealing with this sort of thing?
Firstly, checking whether a point is in a rectangle is pretty quick - and the first thing I'd do is create a control and define 1000 hotspots (or what you might feel the maximum is), and then see what the performance is like.
If it is too slow, you might want to look at implementing a Quadtree. Essentially this will divide your area in to larger areas, which then have sub-areas, which then can have sub, areas, etc.
Depending on where your mouse is, you're only going to have to check a subset of the areas because you know that if the mouse is in one of the larger areas, you don't have to check the rest.
Beware, of course, of rectangles that intersect larger areas, so you might have to end up checking more of the larger areas than you need. But the QuadTree idea should get you started and will give you a performance boost.
Related
In my WPF project, if I open a window, the cpu usage is about 30%-50%, but when I minimize this window, the cpu usage drops to 1%. Does somebody know the reason why? Thanks
do you have a lot of bindings (two way) on your screen? This can cause high cpu.
Or a lot of animations?
Ultimately you could use the WPF performance suite to monitor what is causing this high CPU load: http://msdn.microsoft.com/en-us/library/aa969767.aspx
Good post by Rody, I am just going to add a few things, using an answer instead of a comment because comments have max limit..
I would recommend also to use Ants Profiler, it has 2 week trial period - more than enough to figure out what's going on. Also if you post some of your code, people here can quickly point out a few things.
Like for example, if you have, as Rudy pointed out, ton's of Bindings and Animations, as well as, overly complex controls and control templates. Question the unnecessary compositions of Stack panel within a stack panel, within a border...use TextBlocks instead of Labels, or whether you need TextBoxes, if they are read only, use TextBlocks + Border. Are your ItemControl's items too complex? etc...
Also, Ants Profiler can show you your "zombie" objects. Are you disposing correctly, are you recycling your objects, or creating new complex structures every time (for example, when selecting a new date range for your data to display) then rebind to them. If you have data grid cells, does every single one need an expensive something...a popup and extra border.. If you create a border around every cell for some visual effect, re-factor to only have one, and re-position it on the grid.
And the list can go on.
Long story short - WPF is a hog: so you might have to trim things down, or/and be more inventive to keep things pretty with less overhead.
P.S. don't forget to post some code...
I'm working on an overhead shooter and what happens is, over time, as I move in circles around the arena, the enemies will begin to stack on top of each other until they're one giant stack of units. It ends up looking pretty silly.
The AI is pretty simple and basic: Find the player, move towards him, and attack him if he's in range.
What's the best way to push them away from each other so that they don't all end up on the same spot? I think flocking is a bit overkill (and probably too intensive since I'll have 100-200 enemies on the screen at a time).
Ideas?
Thanks!
Here are a few different approaches you could take to solving this problem:
You could define a potential field for each unit that associates a "height" or "badness" to each location on the map. Each unit moves in a way that tries to minimize its potential, perhaps by taking a step in the direction that moves it to the lowest potential that it can in one step. You could define the potential function so that it slopes toward the player, causing all units to try to move to the player, but also be very high around existing units, causing units to avoid bumping into one another. This is a very powerful framework that is exploited all the time in AI; one famous example is its use in the Berkeley Overmind AI for StarCraft, which ended up winning an AI StarCraft competition. If you do adopt this sort of approach, you could probably then tweak the potential function to get the AI to behave in many other interesting ways, and could easily support flocking. I personally think that this is the best approach to take, as it's the most flexible. It also would be a great starting point for more advanced pathfinding models. For a very good and practical introduction to potential fields for AI, check out this website. For a rigorous mathematical introduction to potential fields and their applications, you might want to check out this paper surveying different AI methods using potential fields.
If you define a bounding circle for each enemy, you could just explicitly disallow the units from stacking on top of each other by preventing any two units from being within two radii's distance of one another. Any time two units got too close, you could either stop one of them from moving, or could have them exert forces on one another to spread them apart. When two units bump into each other, you could just pick a random force vector to apply to each unit to try to spread them apart. This is a much hackier and less elegant solution than potential fields, but if you need to get something up and running it's definitely a viable option.
You could choose a set of points around the player that the units try to move toward, then have each unit randomly choose one of those target points to move to. This would cause the units to spread more thinly in a ring (or whatever shape you'd like) around the player, avoiding the huge masses that you've seen so far. Again, this is way less elegant than using potential fields, but it's another quick hack you could experiment with if your goal is to get something working quickly.
Hope this helps!
I've become rather familiar with the System.Drawing namespace in terms of knowing the basic steps of how to generate an image, draw on it, write text on it, etc. However, it's so darn slow for anything approaching print-quality. I have seen some suggestions using COM to talk to native Windows GDI to do this quicker but I was wondering if there were any optimizations I could make to allow for high speed, high quality image generation. I have tried playing with the anti-aliasing options and such immediately available to the Graphics, Bitmap and Image objects but are there any other techniques I can employ to do this high speed?
Writing this I just had the thought to use the task library in .Net 4 to do MORE work even though each generation task wouldn't be any quicker.
Anyway, thoughts and comments appreciated.
Thanks!
If you want raw speed, the best option is to use DirectX. The next best is probably to use GDI from C++ and provide a managed interface to call it. Then probably to p/invoke to GDI directly from C#, and last to use GDI+ in C#. But depending on what you're doing you may not see a huge difference. Multithreading may not help you if you're limited by the speed at which the graphics card can be driven by GDI+, but could be beneficial if you're processor bound while working out "what to draw". If you're printing many images in sequence, you may gain by running precalculation, rendering, and printing "phases" on separate threads.
However, there are a number of things you can do to optimise redraw speed, both optimisations and compromises, and these approaches will apply to any rendering system you choose. Indeed, most of these stem from the same principles used when optimising code.
How can you minimise the amount that you draw?
Firstly, eliminate unnecessary work. Think about each element you are drawing - is it really necessary? Often a simpler design can actually look better while saving a lot of rendering effort. Consider whether a grad fill can be replaced by a flat fill, or whether a rounded rectangle will look acceptable as a plain rectangle (and test whether doing this even provides any speed benefit on your hardware before throwing it away!)
Challenge your assumptions - e.g. the "high resolution" requirement - often if you're printing on something like a dye-sub printer (which is a process that introduces a bit of colour bleed) or a CMYK printer that uses any form of dithering to mix colours (which has a much lower practical resolution than the dot pitch the printer can resolve), a relatively low resolution anti-aliased image can often produce just as good a result as a super-high-res one. If you're outputting to a 2400dpi black and white printer, you may still find that 1200dpi or even 600dpi is acceptable (you get ever decreasing returns as you increase the resolution, and most people won't notice the difference between 600dpi and 2400dpi). Just print some typical examples out using different source resolutions to see what the results are like. If you can halve the resolution you could potentially render as much as 4x faster.
Generally try to avoid overdrawing the same area - If you want to draw a black frame around a region, you could draw a white rectangle inside a black rectangle, but this means filling all the pixels in the middle twice. You may improve the performance by drawing 4 black rectangles around the outside to draw the frame exactly. Conversely, if you have a lot of drawing primitives, can you reduce the number of primitives you're drawing? e.g. If you are drawing a lot of stripes, you can draw alternating rectangles of different colours (= 2n rectangles), or you can fill the entire background with one colour and then only draw the rectangles for the second colour (= n+1 rectangles). Reducing the number of individual calls to GDI+ methods can often provide significant gains, especially if you have fast graphics hardware.
If you draw any portion of the image more than once, consider caching it (render it into a bitmap and then blitting it to your final image when needed). The more complex this sub-image is, the more likely it is that caching it will pay off. For example, if you have a repeating pattern like a ruler, don't draw every ruler marking as a separate line - render a repeating section of the ruler (e.g. 10 lines or 50) and then blit this prerendered only a few times to draw the final ruler.
Similarly, avoid doing lots of unnecessary work (like many MeasureString calls for values that could be precalculated once or even approximated. Or if you're stepping through a lot of Y values, try to do it by adding an offset on each iteration rather than recaclualting the absolute position using mutliples every time).
Try to "batch" drawing to minimise the number of state changes and/or drawing method calls that are necessary - e.g. draw all the elements that are in one colour/texture/brush before you move on to the next colour. Use "batch" rendering calls (e.g. Draw a polyline primitive once rather than calling DrawLine 100 times).
If you're doing any per-pixel operations, then it's usually a lot faster to grab the raw image buffer and manipulate it directly than to call GetPixel/SetPixel methods.
And as you've already mentioned, you can turn off expensive operations such as anti-aliasing and font smoothing that won't be of any/much benefit in your specific case.
And of course, look at the code you're rendering with - profile it and apply the usual optimisations to help it flow efficiently.
Lastly, there comes a point where you should consider whether a hardware upgrade might be a cheap and effective solution - if you have a slow PC and a low end graphics card there may be a significant gain to be had by just buying a new PC with a better graphics card in it. Or if the images are huge, you may find a couple of GB more RAM eliminates virtual memory paging overheads. It may sound expensive, but there comes a point where the cost/benefit of new hardware is better than ploughing more money into additional work on optimisations (and their ever decreasing returns).
I have a few ideas:
Look at the code in Paint.net. It is an open source paint program written in C#. It could give you some good ideas. You could certainly do this in conjunction with ideas 2 and 3.
If the jobs need to be done in an "immediate" way, you could use something asynchronous to create the images. Depending on the scope of the overall application, you might even use something like NServiceBus to queue an image processing component with the task. Once the task is completed, the sending component would receive a notification via subscribing to the message published upon completion.
The task based solution is good for delayed processing. You could batch the creation of the images and use either the Task approach or something called Quartz.net (http://quartznet.sourceforge.net). It's an open source job scheduler that I use for all my time based jobs.
You can create a new Bitmap image and do LockBits(...), specifying the pixel format you want. Once you have the bits, if you want to use unmanaged code to draw into it, bring in the library, pin the data in memory, and use that library against it. I think you can use GDI+ against raw pixel data, but I was under the impression that System.Drawing is already a thin layer on top of GDI+. Anyways, whether or not I'm wrong about that, with LockBits, you have direct access to pixel data, which can be as fast or slow as you program it.
Once you're done with drawing, you can UnlockBits and viola you have the new image.
I need to manipulate an image such that a sub-rectangle of it is flipped or rotated relative to the rest of the image. Here's an example:
This manipulation needs to happen many times, each time producing a new modified image from the original (rather than applying successive modifications to one image).
The size of the sub-rectangle needs to vary systematically (perhaps in 5% increments from 10% to 75%) and the location of the sub-rectangle needs to vary randomly.
Lastly, this procedure needs to be carried out on a large number of images.
How would I go about this?
My options are PHP, C#, or batching in Gimp. That said, I'm prepared to learn something new if there's a particularly sensible approach.
Id say go with C# and write yourself a little utility.
The Graphics class may have all of the methods that you need.
Id suggest that you look at the DrawImage and the RotateTransform functions.
Is this something that needs to be done programatically or is it a one-time deal?
If programatically, it *can* be done in PHP using the GD library, but its not going to be easy or fast, due to the fact that you'll have to write a routine to manually move pixels.
A summary of "easyness" of your request based on a PHP GD library approach:
Manipulation happens many times, each time producing a new modified image from the original: easy
Size of the sub-rectangle needs to vary systematically, easy
Location of the sub-rectangle needs to very randomly, easy
In-image rotation moderate difficulty, and slow
Performing this on a large number of images, easy
I don't have enough experience in C# of Gimp to give you any definitive answers there; Sorry.
You could take your favourite language, they will all 3 be capable, code it and run it?
I have developed an application that must be presented on exhibition as advertising. I want it to look more sexy! What tricks do you know that enhance the appearance of your applications?
What are the best design effects the developer can use for its application? I am speaking about: glowing, shadows, maybe forms of buttons, beautiful animation of splash screens and so on.
What is YOUR favourite effect?
If you have no feeling for what looks good, then don't try magic tricks like glowing shadows or sparky gradients, it will only look like some awkward app from the late 90s. Like Chris said, effects can ruin an application as quickly as it can make one.
There is no silver bullet for good design, the best tip for someone totally lost is: Less is more. Especially when it comes to colors, avoid using many different colors.
Look on other good looking apps (Photoshop CS4, Adobe Reader 9, OSX Preview, etc etc) they are actually really clean.
If you really want to use some wpf-powers an easy trick is opacity transitions, just keep all animations short (max 0.2 seconds). And for moving animations make sure to use acceleration and deceleration, otherwise the animation will look really weird.
In terms of enhancing your app, here are some things I personally like:
Dropshadow ... Creates the effect of depth on your application, ensure a global lighting direction otherwise, it is difficult to maintain a good general effect.
Scaling ... When transitioning from one state to another, the use of scaling draws attention to the control/screen
Easing ... Whenever there is movement in the screen, the movement should be eased from start to finish.
Shine ... For rollovers, I like a subtle shine to a control, this can be achieved by moving a subtle gradient across the control.
These are just a few effects ... I think it's import to note that effects can ruin an app as quickly as it can make one, so you want to make sure that the effects you use compliment your application.
From a UX perspective, my advice is that any interaction from the user should be exaggerated. For example, rollover effects, highlighting click interactions, etc.
So in conclusion:
Use effects to highlight user interaction
Ensure that effects are used in appropriate places
Keep the effects subtle
Avoid excessive use of effects
Hope that helps!
I found the following examples:
Vista Buttons:
Innerglows:
Glass Buttons:
The only one I really use for the moment is the Bitmap DropShadow and I do not use it that much just a little shadow. The example below is too much for me. I would reduce the ShadowDepth and the opacity.
(source: microsoft.com)
But the trick is too not use them too much and to use them with consistence. Do not change your effect style over and over all around your application. Otherwise, it will be hard to take it seriously.
I prefer my effects to be subtle. Some nice, quick, smooth fade in/fade out/glow effects can add a lot of style. If you're going to do bigger animation style effects, splined animations (rather than linear) usually look a little nicer.
Don't over-do it though. If you add too much, your application is going to become frustrating to the users that just want to get the task done.
Specific effects should be taylored to match the concept of the site. Care should be taken that effects do not get in the way of use, and do not have an overkill such that they have a significant impact on performance.
Try to give your visitors something, rather than hitting them with something.
Tasteful subtle effects can often be more dramatic than glaring bursts of over activity.
A site for an attorney for instance should be clear and more bland than one for say a games site which can get quite expressive and still be acceptable.
On color:
The correct mix of color will go a long way to improve appearance with minimal negative impact on use, just use care in different shades of a color group. Try not to have a tan wording on top of a different shade of light brown background for instance, it might degrade the ability to read the text.
I would try to stay away from a mix of colors from opposite sides of the color wheel or a mix of cool and warm colors on the same page.
Personally, I would reserve the neon colors for entertainment related things or where the time you expect visitors to stay is limited.
Often when you are trying to advertise a product or service, less is more.