Exemplo n.º 1
0
        // helper
        static SpatialVectorDouble calcImpulse(SpatialVectorDouble relativeVelocity, double mass)
        {
            // e = 1/2 * m * v²
            double velocityMagnitude = relativeVelocity.length;

            if (velocityMagnitude < double.Epsilon)
            {
                return(new SpatialVectorDouble(new double[] { 0, 0, 0 }));
            }
            else
            {
                return(relativeVelocity.normalized().scale(0.5 * mass * velocityMagnitude * velocityMagnitude));
            }
        }
Exemplo n.º 2
0
        // useful for acceleration with radiation or a shockwave
        public static void accelerateByRadialPressure(SpatialVectorDouble energySourcePosition, double energyInJoules, IList <FracturedParticle> particles)
        {
            foreach (FracturedParticle iParticle in particles)
            {
                SpatialVectorDouble diff = iParticle.relativePosition - energySourcePosition;
                double distance          = diff.length;

                if (distance > 0.0)
                {
                    double surfaceAreaOfRadiationSphereAtDistance = Area.ofSphere(distance);

                    double surfaceAreaOfProjectedSphere = ProjectedArea.ofSphere(iParticle.radius);

                    double absorbedEnergyRatio    = System.Math.Min(surfaceAreaOfProjectedSphere / surfaceAreaOfRadiationSphereAtDistance, 1.0);
                    double absolvedEnergyInJoules = absorbedEnergyRatio * energyInJoules;
                    iParticle.accelerateByEnergyInJoules(diff.normalized(), absolvedEnergyInJoules);
                }
            }
        }
        // generalized way to rotate in a specific direction
        public void controlSolve(PhysicsComponent @object, float roll, float pitch, float yaw)
        {
            IList <ThrusterResponsibility.ThrusterBinding> thrusterBindings;

            if (!thrusterResponsibility.physicsObjectIdToThrusters.TryGetValue(@object.id, out thrusterBindings))
            {
                return;
            }

            SpatialVectorDouble rotationTargetVector = new SpatialVectorDouble(new double[] { roll, yaw, pitch }); // vulkan coordinate system rotation

            double maximalAngularAccelerationMagnitude = 0.0;

            foreach (var iThrusterBinding in thrusterBindings)
            {
                maximalAngularAccelerationMagnitude = System.Math.Max(maximalAngularAccelerationMagnitude, iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject.length);
            }


            foreach (var iThrusterBinding in thrusterBindings)
            {
                SpatialVectorDouble normalizedAngularAccelerationOnObject;
                if (iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject.length < double.Epsilon)
                {
                    normalizedAngularAccelerationOnObject = new SpatialVectorDouble(new double[] { 0, 0, 0 });
                }
                else
                {
                    SpatialVectorDouble cachedAngularAccelerationOnObject = iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject;
                    double normalizedMangitude = cachedAngularAccelerationOnObject.length / maximalAngularAccelerationMagnitude;
                    normalizedAngularAccelerationOnObject = cachedAngularAccelerationOnObject.normalized().scale(normalizedMangitude);
                }

                // calculate the relative thrust by the dot product because we want to rotate the best way in the wished rotation acceleration (given by roll, pitch, yaw)
                double relativeThrust = SpatialVectorDouble.dot(normalizedAngularAccelerationOnObject, rotationTargetVector);
                relativeThrust = System.Math.Max(relativeThrust, 0); // thruster can only thrust positivly

                iThrusterBinding.relative += (float)relativeThrust;  // now we add to not cancel away the effects of the other thrusters
            }
        }
Exemplo n.º 4
0
        // calculates the gravitational forces and coresponding accelerations
        public void calcForcesAndAccelerationsForPhysicsComponents(IEnumerable <PhysicsComponent> physicsComponents)
        {
            foreach (PhysicsComponent iPhysicsComponent in physicsComponents)
            {
                SpatialVectorDouble sumOfForce = new SpatialVectorDouble(new double[] { 0, 0, 0 });

                foreach (CelestialObjectWithPosition iCelestialObject in celestialObjects)
                {
                    SpatialVectorDouble extrapolatedPosition = iPhysicsComponent.rungeKutta4State.x + iPhysicsComponent.rungeKutta4State.v.scale(PhysicsEngine.dt);
                    SpatialVectorDouble difference           = iCelestialObject.position - extrapolatedPosition;
                    SpatialVectorDouble direction            = difference.normalized();
                    double distanceSquared = difference.lengthSquared;

                    double forceMagnitude = Orbit.calculateForceBetweenObjectsByDistance(iPhysicsComponent.mass, iCelestialObject.celestialObject.mass, distanceSquared);

                    sumOfForce += direction.scale(forceMagnitude);
                }

                SpatialVectorDouble acceleration = sumOfForce.scale(iPhysicsComponent.invMass);
                iPhysicsComponent.linearAcceleration += acceleration;
            }
        }
Exemplo n.º 5
0
        static void applyForceToLinearAndAngularVelocity(PhysicsComponent physicsComponent, SpatialVectorDouble localForce, SpatialVectorDouble objectLocalPositionOfForce)
        {
            { // linear part
              // to calculate the linear component we use the dot product
                double scaleOfLinearForce = 0.0;
                if (localForce.length > double.Epsilon)
                {
                    double dotOfForceAndLocalPosition = SpatialVectorDouble.dot(localForce.normalized(), objectLocalPositionOfForce.normalized());
                    scaleOfLinearForce = System.Math.Abs(dotOfForceAndLocalPosition);
                }

                // the linear force (and resulting acceleration) is the force scaled by the dot product

                Matrix rotationMatrix           = physicsComponent.calcLocalToGlobalRotationMatrix();
                Matrix globalForceAsMatrix      = rotationMatrix * SpatialVectorUtilities.toVector4(localForce).asMatrix;
                SpatialVectorDouble globalForce = SpatialVectorUtilities.toVector3(new SpatialVectorDouble(globalForceAsMatrix));

                physicsComponent.linearAcceleration += globalForce.scale(scaleOfLinearForce * physicsComponent.invMass);
            }

            { // angular part
                physicsComponent.eulerAngularAcceleration += physicsComponent.calcAngularAccelerationOfRigidBodyForAppliedForce(objectLocalPositionOfForce, localForce);
            }
        }