private void OnFrameCallback(object sender, EventArgs e) { if (_timeTracker != null) { _timeTracker.Update(); InvalidateVisual(); } }
private void UpdateChildren(object sender, EventArgs e) { //update time delta _timeTracker.Update(); foreach (UIElement child in LogicalTreeHelper.GetChildren(this)) { Vector velocity; if (_childrenVelocities.ContainsKey(child)) { //get the velocity that we previously stored velocity = _childrenVelocities[child]; } else { //setup the initial velocity randomly velocity = new Vector(0, 0); } //compute velocity dampening velocity = velocity * _drag; Point truePosition = GetTruePosition(child); Rect childRect = new Rect(truePosition, child.RenderSize); //accumulate forces Vector forces = new Vector(0, 0); //add wall repulsion forces.X += _borderforce / Math.Max(1, childRect.Left); forces.X -= _borderforce / Math.Max(1, this.RenderSize.Width - childRect.Right); forces.Y += _borderforce / Math.Max(1, childRect.Top); forces.Y -= _borderforce / Math.Max(1, this.RenderSize.Height - childRect.Bottom); //each other child pushes away based on the square distance foreach (UIElement otherchild in LogicalTreeHelper.GetChildren(this)) { //dont push against itself if (otherchild == child) { continue; } Point otherchildtruePosition = GetTruePosition(otherchild); Rect otherchildRect = new Rect(otherchildtruePosition, otherchild.RenderSize); //make sure rects aren't the same if (otherchildRect == childRect) { continue; } //ignore children with a size of 0,0 if (otherchildRect.Width == 0 && otherchildRect.Height == 0 || childRect.Width == 0 && childRect.Height == 0) { continue; } //vector from current other child to current child Vector toChild; double length; //are they overlapping? if so, distance is 0 if (AreRectsOverlapping(childRect, otherchildRect)) { toChild = new Vector(0, 0); } else { toChild = VectorBetweenRects(childRect, otherchildRect); } length = toChild.Length; if (length < 1) { length = 1; Point childCenter = GetCenter(childRect); Point otherchildCenter = GetCenter(otherchildRect); //compute toChild from the center of both rects toChild = childCenter - otherchildCenter; } double childpush = _childforce / length; toChild.Normalize(); forces += toChild * childpush; } //add forces to velocity and store it for next iteration velocity += forces; _childrenVelocities[child] = velocity; //move the object based on it's velocity SetTruePosition(child, truePosition + _timeTracker.DeltaSeconds * velocity); } }
protected void OnFrameCallback(object sender, EventArgs e) { UpdateParticles(_timeTracker.Update()); }