0

NOTE: Please be sure to read the Let us continue this discussion in chat for background notes


I have seen a few posts on here and tutorials for checking to see if controls overlap but what is the best method for checking this during an animation?

I'm making a simulation software which involves having some UIElements animate along a path. At the moment I have 20 items following this path and it works fine.

To do this I just create a loop of 20 and inside the loop, I am creating the UIElement, storyboard etc and then starting. I wait for about 100ms then repeat. This gives a nice gap between the elements.

Anyway, the above works as it should. Now the next bit. At any point of the sim, a UIElement can stop where it is. Now when this happens, I want the other UIElements to keep going until they hit the stopped element, and 1 by 1 they stack up behind it.

So knowing how to check for overlap/intersection/collision, how do I check during an animation of elements.

Bizhan
  • 16,157
  • 9
  • 63
  • 101
Gaz83
  • 2,293
  • 4
  • 32
  • 57
  • 1
    _"Is it just a simple case of creating a timer that goes off say every 100ms and then loop all the UIelements to see if they overlap?"_ - perhaps. Did you try that? Any code to show? [ask]. Good luck –  Aug 15 '18 at 08:53
  • @MickyD No, I am trying that now. But even if it works, Im trying to get an understanding on what is the best way to do it. If a timer is the best way then someone can say yeah thats the only way to do it, which is fine, but someone else might come along and say "No No you don't want to do do that because accuracy will be bad, you should do this". – Gaz83 Aug 15 '18 at 09:13
  • you will need to check for collision against all moving elements when an element is stopped which I think is out of the animation scope. – Bizhan Aug 15 '18 at 09:16
  • @Bijan ok, so I guess its looking more and more like a timer to constantly check? – Gaz83 Aug 15 '18 at 09:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178068/discussion-between-bijan-and-gaz83). – Bizhan Aug 15 '18 at 09:20
  • @MickyD updated to make it more of a question looking for an answer. – Gaz83 Aug 15 '18 at 09:44
  • 1
    @MickyD I don't think asking for the best way is necessarily off-topic. asking a solely opinion based question is. – Bizhan Aug 15 '18 at 09:44
  • Perhaps. There are always better ways but generally you just want what works best for you. Sometimes a simple solution is adequate. Sure it might not be terribly efficient if you are animating 1000s of shapes but unless you intend to do such a thing, such solutions are overkill. Open-ended questions such as yours tend to attract the latter and are really just an excersice in people demonstrating their cleverness when all that is needed is a humble timer. However, you will never know because you didn't try. Why not give it a go and let us know how you go –  Aug 15 '18 at 12:19
  • Also how complex are your _shapes_ and how _accurate_ does the overlap detection need to be. e.g. if testing by bounding rectangles though that works fine for shapes resembling say a _brick_; does it matter that it is _inaccurate_ for shapes such as the letter "A" –  Aug 15 '18 at 12:22
  • 1
    @MickyD, collision detection alone was a duplicate question and collision detection with constantly moving objects seemed like a duplicate which needed more clarifications. after asking OP a couple of questions the problem became pretty clear to me. For Unity developers such as myself, this is a very common thing to think about and has no straight-forward solution but tips and tricks. If OP wanted a complex shaped element he would have asked it right away, but we do consider it is a simple shape otherwise. I personally think the question and the answer can help future readers. – Bizhan Aug 15 '18 at 12:38

1 Answers1

0

The collision detection, by its nature, needs a constantly checking timer. because there are no collision events in WPF.

You can check for the collision of two Rect objects with rect1.IntersectsWith(rect2)

taken from here

You can find the Rect of an element relative to its parent using

public static Rect BoundsRelativeTo(this FrameworkElement element,
                                         Visual relativeTo)
{
  return
    element.TransformToVisual(relativeTo)
           .TransformBounds(LayoutInformation.GetLayoutSlot(element));
}

taken from here

The question is how many elements are being dropped into the bottleneck of the timer at a time, if the collision detection ALWAYS involves a stopped element, then that element is responsible for collision detection. Otherwise, you will need to check n^2 collisions (which is bad). You can work on the efficiency of this bottleneck by reducing the number of comparisons as much as possible. For example, since the objects are moving along a common path you can compare the stopped element against its previous element only. You can ensure a sorted collection of elements to achieve that.

Since all elements are following a common path (one collision occurs at a time):

  • start the timer when the first element is stopped. and set it as the reference element
  • compare all required elements against the reference element
    • change the reference element when a collision occurs to the collided element
Bizhan
  • 16,157
  • 9
  • 63
  • 101
  • This has answerd my question, thank you Bijan for the help. – Gaz83 Aug 15 '18 at 09:51
  • @MickyD, I specifically said not to check all elements for a collision during a single update in my answer. – Bizhan Aug 15 '18 at 12:41
  • @MickyD, You are right, I forgot to include some important comments from the chat into my answer. tried to keep it simple. – Bizhan Aug 15 '18 at 12:46
  • Not a problem good sir. I will upvote in advance. Wishing you well and happy Unity'ing :) –  Aug 15 '18 at 12:47
  • @MickyD, thanks for the feedback and upvote. happy SO'ing :) – Bizhan Aug 15 '18 at 12:50
  • I don't see how "stolen from here" is compatible with [attribution requirements](https://stackoverflow.blog/2009/06/25/attribution-required/). In fact, it is rude. Do you want *your* contributions to be stolen?? – ASh Aug 16 '18 at 08:40
  • 1
    @ASh - "Stolen from" was a self-deprecating joke. No wording was copied without attribution, and they provided a proper citation for where they drew the code in their answer from. I deal with (and delete) a lot of plagiarism, but this doesn't qualify. – Brad Larson Aug 16 '18 at 14:54
  • @Bizhan How to detect the collision with a Path? – Eftekhari Apr 04 '21 at 17:09
  • @Eftekhari please describe your problem properly in a different question. – Bizhan Apr 04 '21 at 19:08
  • @Bizhan Thanks for the reply. If I couldn't find the solution from the provided answers I'll. – Eftekhari Apr 04 '21 at 20:01