/// <summary> /// Calculates whether this object is colliding with another one or not. /// </summary> /// <param name="otherObject">The other object to look for a collision with.</param> /// <returns>True if colliding, false if not.</returns> protected bool IsCollidingWith(DEEPKinectObjectBaseClass otherObject) { /* First, we calculate the positions of the objects on the screen. * Note that because of the way things are shown on-screen, we have * to calculate the center location in a bit of a strange way. */ DenseVector thisPosition = this.GetPosition() + this.velocity * internalRefreshRate; DenseVector otherPosition = otherObject.GetPosition() + otherObject.velocity * internalRefreshRate; /* Calculate the Cartesian distance between the two points. */ double distance = (otherPosition - thisPosition).L2Norm(); /* Here we add the velocity to the distance as well. This is a bit of a hack, * but it will prevent two shapes from passing through each other if they are moving really fast. */ //distance -= this.velocity.L2Norm() + otherObject.velocity.L2Norm(); /* Calculate the sum of the radii. Assume that height is equal to width here. */ double radiiSum = (this.onScreenShape.Height + otherObject.onScreenShape.Width) / 2d; /* Check to see if they are close enough to collide. Since we've * restricted objects to be round, we can do a simple check: * there is a collision if the distance between the two objects is * less than the sum of their radii. */ if (distance < radiiSum) { return true; } else { return false; } }
/// <summary> /// Calculates whether this object is colliding with another one or not. /// </summary> /// <param name="otherObject">The other object to look for a collision with.</param> /// <returns>True if colliding, false if not.</returns> protected bool IsCollidingWith(DEEPKinectObjectBaseClass otherObject) { /* First, we calculate the positions of the objects on the screen. * Note that because of the way things are shown on-screen, we have * to calculate the center location in a bit of a strange way. */ DenseVector thisPosition = this.GetPosition() + this.velocity * internalRefreshRate; DenseVector otherPosition = otherObject.GetPosition() + otherObject.velocity * internalRefreshRate; /* Calculate the Cartesian distance between the two points. */ double distance = (otherPosition - thisPosition).L2Norm(); /* Here we add the velocity to the distance as well. This is a bit of a hack, * but it will prevent two shapes from passing through each other if they are moving really fast. */ //distance -= this.velocity.L2Norm() + otherObject.velocity.L2Norm(); /* Calculate the sum of the radii. Assume that height is equal to width here. */ double radiiSum = (this.onScreenShape.Height + otherObject.onScreenShape.Width) / 2d; /* Check to see if they are close enough to collide. Since we've * restricted objects to be round, we can do a simple check: * there is a collision if the distance between the two objects is * less than the sum of their radii. */ if (distance < radiiSum) { return(true); } else { return(false); } }
/// <summary> /// Calculates the resulting velocities when colliding in a perfectly /// elastic manner with another object. /// </summary> /// <param name="otherObject">The other object that this one is colliding with.</param> protected void ProcessElasticCollisionWith(DEEPKinectObjectBaseClass otherObject) { /* We use the definition from Wikipedia for how to handle the collision of * two moving objects in vector form. See: en.wikipedia.org/wiki/Elastic_collision * * To be specific, we use instructions from www.vobarian.com/collisions/2dcollisions2.pdf */ /* Here are the known quanitities of the situation. */ DenseVector p1 = this.GetPosition(); DenseVector p2 = otherObject.GetPosition(); DenseVector v1 = this.velocity; DenseVector v2 = otherObject.velocity; double m1 = this.mass; double m2 = otherObject.mass; /* First we create a unit normal and tangent vector. */ DenseVector n = p2 - p1; DenseVector un = n / n.Norm(2d); DenseVector ut = new DenseVector(new double[] { -un[1], un[0] }); /* Here we find the normal and tangential components of the velocities. */ double v1n = un.DotProduct(v1); double v1t = ut.DotProduct(v1); double v2n = un.DotProduct(v2); double v2t = ut.DotProduct(v2); /* We then apply 1-D elastic collision dynamics in the normal direction to the * line of collision. * Note that there is NO CHANGE in the tangential components of the velocity. */ double post_v1n = (v1n * (m1 - m2) + 2 * m2 * v2n) / (m1 + m2); double post_v2n = (v2n * (m2 - m1) + 2 * m1 * v1n) / (m1 + m2); /* Now we convert the scalar normal/tangential velocities into vectors pointing * in the appropriate directions. */ DenseVector vPost_v1n = post_v1n * un; DenseVector vPost_v1t = v1t * ut; DenseVector vPost_v2n = post_v2n * un; DenseVector vPost_v2t = v2t * ut; /* Calculate the post-collision velocity by adding the normal/tangential velocities * together. */ DenseVector v1FinalVelocity = vPost_v1n + vPost_v1t; DenseVector v2FinalVelocity = vPost_v2n + vPost_v2t; /* Set the object's velocity to the post-collision velocity. */ this.velocity = v1FinalVelocity; otherObject.velocity = v2FinalVelocity; }
public override void InteractWith(DEEPKinectObjectBaseClass otherObject) { /* The only interaction that a Kinematic object has with other objects * is collision with other kinematic objects. So we will first check * if the other object is also kinematic. */ if (otherObject.DEEPObjectType == DEEPKinectObjectTypes.Kinematic) { if (this.IsCollidingWith(otherObject) ) { /* A collision affects both objects that collide. So this interaction * will adjust the velocities of both of the involved objects. */ ProcessElasticCollisionWith((DEEPKinematicObject)otherObject); } } }
public override void InteractWith(DEEPKinectObjectBaseClass otherObject) { /* The only interaction that a Kinematic object has with other objects * is collision with other kinematic objects. So we will first check * if the other object is also kinematic. */ if (otherObject.DEEPObjectType == DEEPKinectObjectTypes.Kinematic) { if (this.IsCollidingWith(otherObject)) { /* A collision affects both objects that collide. So this interaction * will adjust the velocities of both of the involved objects. */ ProcessElasticCollisionWith((DEEPKinematicObject)otherObject); } } }
/// <summary> /// This method implements all interactions with other objects. It gets /// called often. For example, if you wanted to handle collisions, this /// would be the place to do it. /// </summary> /// <param name="otherObject"></param> public override void InteractWith(DEEPKinectObjectBaseClass otherObject) { /* We only interact with other Gravitational objects. */ if (otherObject.DEEPObjectType == DEEPKinectObjectTypes.Gravitational) { /* Check for collisions. */ if (this.IsCollidingWith(otherObject)) { /* If collided, we do so inelastically. */ this.ProcessInelasticCollisionWith(otherObject); } else { /* Otherwise, apply gravity. */ this.ProcessGravitationalInteraction((DEEPGravitationalObject)otherObject); } } }
/// <summary> /// This method implements all interactions with other objects. It gets /// called often. For example, if you wanted to handle collisions, this /// would be the place to do it. /// </summary> /// <param name="anotherObject"></param> public override void InteractWith(DEEPKinectObjectBaseClass otherObject) { /* We only interact with other Electrical objects. */ if (otherObject.DEEPObjectType == DEEPKinectObjectTypes.Electrical) { /* Check for collisions. */ if (this.IsCollidingWith(otherObject)) { /* If collided, we do so inelastically. */ this.ProcessInelasticCollisionWith(otherObject); } else { /* Otherwise, apply electrostatics. */ this.ProcessElectricalInteraction((DEEPElectricalObject)otherObject); } } }
/// <summary> /// Calculates the resulting velocities of both objects when undergoing a perfectly /// inelastic collision with another object. /// </summary> /// <param name="otherObject"></param> protected void ProcessInelasticCollisionWith(DEEPKinectObjectBaseClass otherObject) { /* Here are the known quanitities of the situation. */ DenseVector p1 = this.GetPosition(); DenseVector p2 = otherObject.GetPosition(); DenseVector v1 = this.velocity; DenseVector v2 = otherObject.velocity; double m1 = this.mass; double m2 = otherObject.mass; DenseVector vFinal = new DenseVector(2); vFinal[0] = (m1 * v1[0] + m2 * v2[0]) / (m1 + m2); vFinal[1] = (m1 * v2[1] + m2 * v2[1]) / (m1 + m2); this.velocity = vFinal; otherObject.velocity = vFinal; }
/// <summary> /// This method implements all interactions with other objects. It gets /// called often. For example, if you wanted to handle collisions, this /// would be the place to do it. /// </summary> /// <param name="anotherObject"></param> public override void InteractWith(DEEPKinectObjectBaseClass otherObject) { /* We only interact with other Gravitational objects. */ if (otherObject.DEEPObjectType == DEEPKinectObjectTypes.Thermal) { /* Check for collisions. */ if (this.IsCollidingWith(otherObject)) { /* Since the objects are touching, there is heat transfer * happening. We model that here. */ this.ProcessHeatTransfer((DEEPThermalObject)otherObject); /* Apply friction to slow parts down here. */ this.velocity *= 0.95; otherObject.velocity *= 0.95; } else { /* If the objects aren't touching, we assume that they are * not interacting. */ } } }
/// <summary> /// This method implements all interactions with other objects. It gets /// called often. For example, if you wanted to handle collisions, this /// would be the place to do it. /// </summary> /// <param name="anotherObject"></param> public override void InteractWith(DEEPKinectObjectBaseClass anotherObject) { /* No interactions! It's a button! */ }
/// <summary> /// This template governs how this object interacts with another object. In particular, /// it governs how this object's internal states are modified by the presence of another /// object. For example, if this object has mass and is placed in the presence of another /// object with mass, it will be attracted to the other object. /// /// Note that this interaction is one-way only: the interaction shows how this object is /// changed by the presence of the other, but not the other way around. To also change /// the other object, it is necessary to call its' InteractWith() method. /// </summary> /// <param name="anotherObject">The other object that this object is being exposed to.</param> public abstract void InteractWith(DEEPKinectObjectBaseClass anotherObject);