Check for overlapping shapes in WPF - wpf

I have a set of shapes which need to be drawn on top of each other. I need to re-order them such that the smallest shape gets drawn last (i.e. it will be closest to the user). Is there any way to check whether a shape overlappes (encloses and/or intersects) another shape. I know there is a method in Rect structure called Contains which checks whether there is an object within it. Is there a similar method or a way to simulate it on Shapes in WPF? Thanks in advance for any help.
Cheers,
Nilu

You could probably use the Geometry.FillContainsWithDetail method. Its name is ill-chosen IMHO, but the description is clear :
Returns a value that describes the intersection between the current geometry and the specified geometry.
I have successfully used it for collision testing before, so it should work for you too...

Related

Ordering 2d/3d object behind other element

As you can see in the link, I have two elements: first is image element which is taken from camera (using EmguCV) and the other one is viewport3d which renders 3d object. I also include 2d object (see the rectangle).
When I run my program I see this.
Yes indeed, the object (hand) will be ordered in front of the image.
The question is how to order 2d/3d object behind the hand object? Is it possible to do it using single camera? Just like this one.
Thanks in advance for your answers.
There are two ways of doing it.
Use kinect depth map to find the distance of hand from camera.
Do image processing to detect hand and it's distance.
I think it will be difficult to directly blend WPF UI with camera image.
Try RenderTargetBitmap
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap.aspx

Getting the true visual bounding box of a WPF element?

For a simplified version of my problem, I would like to calculate the bounding box of a layout-transformed (possibly even render-transformed) shape, so that I can always fit a rectangle perfectly around the shape, no matter what its rotation or scale may be. If you can solve this, I will be happy.
The more complex problem is that of calculating the visual bounding box of any framework element. By 'visual bounding box' I mean the top-most visible pixel within the framework element determines the top-bound, the right-most visible pixel determines the right-bound, etc. If you can solve this, I will be even more happy.
I have tried playing with LayoutInformation.GetLayoutSlot(), but this did not work in the expected manner. The 'layout slot' was actually MUCH larger than the actual bounds. I also tried using VisualTreeHelper.GetDescendantBounds(), but because of the VisualParent of my test shape being protected I could not manage to access this property, and decided to check here before I go any further into it.
I hope that somebody can provide an easy way of getting the true visual bounding box of an element in WPF, that is calculated AFTER all transforms. If I have not made something clear in my question, please let me know.
private Rect GetRectOfObject(FrameworkElement _element)
{
Rect rectangleBounds = _element.RenderTransform.TransformBounds(
new Rect(_element.RenderSize);
return rectangleBounds;
}
Maybe this will help out.
You will get good results with VisualTreeHelper.GetDescendantBounds() and you can use VisualTreeHelper.GetParent() to gain access to the otherwise protected VisualParent property. However what you probably want to do is call GetDescendantBounds on the shape itself, not its parent, because in spite of its name, the method returns the bounds of the parent and all of its decendants.
The problem is not easy, as a control may draw outside its bounds.
But if you assume this doesn't happen you can solve the problem by using parent.TranslatePoint(point_in_child_coord_system, child) to transform (0,0), (child.ActualWidth,0), (child.ActualWidth, child.ActualHeight) and (0,child.ActualHeight) to the parent coord system. Then sort the x and y coordinates of all points and use minimum and maximum values to find the bounding box.
Note: sorting is necessary because of possible child rotation.

WPF Line, path ..etc custom drawing style

In WPF is there a way that you can modify the way any path is drawn APART from Dash-Dot sequences? Say I want draw a triple line for any path I am drawing or small triangles,waves..etc on the drawing path itself. I have tried Brushes but it will not follow the Path. Please help
thx
WPF's Geometry classes have all the primitives you need to accomplish this easily, but you will need to do it in code. When I need to do custom lines I usually construct a Drawing based on the Geometry, but in your case you can simply build a Geometry that has three lines in parallel and stroke that.
Start with PathGeometry.CreateFromGeometry() to get a PathGeometry for the input path
Use GetWidenedPathGeometry(), passing in the desired spacing, to get a new geometry whose edges correspond to the side lines
(optional) Remove segments at the end of the widened geometry, if desired
Combine the side line geomerty with original geometry using a CombinedGeometry
Stroke the combined geometry to get a triple line
More explanation on step 3: The widened geometry has line segments at the end of the original line. This causes a line to be drawn across the end of your line, which actually looks aesthetically pleasing in many situations. If your situation would look better without it, remove it by iterating the side line geometry and removing all line segments that pass through the endpoints of the original path.
The above takes about 8 lines of code if you don't strike off the ends, or 15 if you do.
A trick to make this convenient is to create an attached property which effectively coerces the Data property of the Path control it is attached to. With such an attached property, all you need to write is:
<Path TripleStroke.Enable="true" Data="..." />
If you know how to implement attached properties and register handlers in them, this is a piece of cake. If not, plan on spending several hours learning how to code attached properties to simulate value coercion before implementing the attached property approach.
Update
The basic technique I describe above can also be extended to allow an arbitrary pattern to be applied along a path. For an example, see custom brushes in the Expression Design tool. There is nothing built into WPF to do this for you, however, so you'll need to create it yourself, and I can tell you from experience that it is a lot of work. Here are the basic steps:
First create a method that takes a Geometry an existing Drawing, and some parameters for end caps, etc and creates a new Drawing that repeats the given Drawing along the path given by the Geometry. Then it is easy to draw a stroked path: Create a Drawing to describe the custom stroke, then display the stroke using a DrawingVisual that contains a Binding with a converter that calls your conversion method.
To actually implement the conversion method:
Convert the source drawing into a set of GeometryDrawing objects (I also supported ImageDrawing but that is more complicated since you need to use the 3D system to stretch the images). This is done by recursing through DrawingGroup objects, keeping track of transforms as you go, and constructing GeometryDrawings with appropriate transform.
Remove portions of geometry in the "end cap" areas of the original drawing and set them aside.
Iterate along the path, duplicating the GeometryDrawing objects repeatedly with appropriate coordinate transformations applied to all coordinates in the geometry.
Process the "end cap" sections of the geometry using the same procedure.
Also note in step 1 that any GlyphRunDrawings are handled using FormattedText.BuildGeometry to create an equivalent GeometryDrawing.
There is no supported method for doing this in WPF. The solution is going to involve either composite Path objects or fancy code-behind gymnastics. Are you specificly looking for a triple-line path implementation?

Best way to write a custom gauge control in WPF?

I need to write a gauge control in WPF for a project at work. By gauge control, I mean something akin to a traditional car speedometer: a circular face with numbers and ticks around the circumference, and a needle pointing to the current value. Although I could get my employer to purchase a third-party control, or even find a free one somewhere, I’d still like to write it myself, for curiosity’s sake more than anything else.
My first thought was to ‘skin’ an existing control using a template, something like a ProgressBar for example as it has Minimum, Maximum and Value properties. However, I don’t think this will offer me the flexibility that I need.
I’d like to animate the needle that points to the current value, so that when the gauge’s value changes the needle moves from the old value to the new value. I figured the easiest way to do this would be to have some kind of shape or geometry representing the needle, and then apply a RotateTransform of the relevant number of degrees to get the needle to point to the correct value. The animation’s To property would be set to the ‘value degrees’ property via binding.
It seems to me that there are three basic approaches I could take:
Use one custom FrameworkElement to represent the entire gauge
I could derive from FrameworkElement, override its OnRender method, then use the DrawingContext to draw both the gauge face and the needle. This would mean that I could no longer animate the needle directly using a RotateTransform, but would instead have to redraw the entire gauge every time the value changes. This seems inefficient to me, as the gauge face represents the bulk of the drawing code but would change very rarely. However, this approach is the most lightweight in terms of the number of elements used.
Use two custom FrameworkElements, one for the face and one for the needle
I’m currently leaning towards this approach. One element would represent the face, the other the needle. This would allow me to target the needle element with the RotateTransform. The gauge control would then consist of three elements: the face, the needle, and a Panel container to hold both of them (ie. Canvas, Grid, whatever). So three elements instead of one, hence not as lightweight as the first approach.
Use DrawingVisuals to draw the face and needle
I’ve also read about the DrawingVisual class, but I’m a bit confused as to why anyone would use this as opposed to deriving from FrameworkElement and overriding OnRender, given that DrawingVisual must be hosted in a custom FrameworkElement anyway. It would seem that this approach doesn’t offer any advantages over the second approach, and would require more code, but maybe I’m missing something.
Any thoughts or advice regarding which approach people think is best and why would be most welcome!
Personally I'd recommend making a CustomControl using the second approach. Unless you are going to be showing more than 1000 of the gauges in view at the same time you aren't going to notice the extra element in your visual tree and I think you'll find it's much easier to make and maintain.
You could just style a slider control and feed values into it. You should be able to make a slider look like any kind of gauge you need.

How can i check if 2 controls overlap eachother on a canvas in WPF?

I am writing a designer that enables the user to drag controls around the screen.
What would be the best way of detecting if a control is overlapping another control while i am dragging the one control around?
Should i just get the dimensions of the FrameworkElement and keep on checking the dimensions of the other elements?
Thanks.
Eli
You can use the Rect.IntersectsWith method
The dimension (FrameworkElement.ActualWidth FrameworkElement.ActualHeight) and postion (Canvas.Top, Canvas.Bottom,Canvas.Left, Canvas.Right) of your elements would suffice if they are always rectangular. In that case you can easily calculate if two rectangles overlap. If you elements can be of more complex shapes it gets hairy. I have no idea if I can test for intersection of two Visual instances in WPF.
Maybe we can use hittesting? With this approach you could at least test if a certain point or geometry intersect with a certian visual. So you would have to define a geometry or a list of points that more or less closely match the bounds of your 2nd visual.

Resources