public void Update(double delta)
        {
            float totalAngle       = 0.0f;
            var   totalTranslation = Vector2.Zero;

            for (int i = 0; i < Input.Length; ++i)
            {
                float weight = Input[i].Weight / CubismPhysics.MaximumWeight;

                Input[i].GetNormalizedParameterValue(
                    ref totalTranslation,
                    ref totalAngle,
                    Input[i].Source,
                    Normalization,
                    weight
                    );
            }

            float radAngle = CubismMath.DegreesToRadian(-totalAngle);

            totalTranslation.X = totalTranslation.X * MathF.Cos(radAngle) - totalTranslation.Y * MathF.Sin(radAngle);
            totalTranslation.Y = totalTranslation.X * MathF.Sin(radAngle) + totalTranslation.Y * MathF.Cos(radAngle);

            updateParticles(
                Particles,
                totalTranslation,
                totalAngle,
                Wind,
                CubismPhysics.MovementThreshold * Normalization.Position.Maximum,
                delta
                );

            for (int i = 0; i < Output.Length; ++i)
            {
                int particleIndex = Output[i].ParticleIndex;

                if (particleIndex < 1 || particleIndex >= Particles.Length)
                {
                    break;
                }

                var translation = Particles[particleIndex].Position - Particles[particleIndex - 1].Position;
                var parameter   = Output[i].Destination;

                float outputValue = Output[i].GetValue(
                    translation,
                    parameter,
                    Particles,
                    particleIndex,
                    Gravity
                    );

                updateOutputParameterValue(parameter, outputValue, Output[i]);
            }
        }
        private void updateParticles(
            PhysicsParticle[] strand,
            Vector2 totalTranslation,
            float totalAngle,
            Vector2 wind,
            float thresholdValue,
            double delta
            )
        {
            strand[0].Position = totalTranslation;

            float totalRadian    = CubismMath.DegreesToRadian(totalAngle);
            var   currentGravity = CubismMath.RadianToDirection(totalRadian);

            for (int i = 1; i < strand.Length; ++i)
            {
                strand[i].Force        = (currentGravity * strand[i].Acceleration) + wind;
                strand[i].LastPosition = strand[i].Position;

                // NOTE: This expects 30 FPS. We might want to get the FPS from the drawable clock if things get messy.
                float delay = strand[i].Delay * (float)delta * 30.0f;

                var direction = strand[i].Position - strand[i - 1].Position;

                float radian = CubismMath.DirectionToRadian(strand[i].LastGravity, currentGravity) / CubismPhysics.AirResistance;

                direction.X = (MathF.Cos(radian) * direction.X) - (direction.Y * MathF.Sin(radian));
                direction.Y = (MathF.Sin(radian) * direction.X) + (direction.Y * MathF.Cos(radian));

                strand[i].Position = strand[i - 1].Position + direction;

                var velocity = strand[i].Velocity * delay;
                var force    = strand[i].Force * delay * delay;

                strand[i].Position = strand[i].Position + velocity + force;

                var newDirection = strand[i].Position = strand[i - 1].Position;
                newDirection.Normalize();

                strand[i].Position = strand[i - 1].Position + newDirection * strand[i].Radius;

                if (MathF.Abs(strand[i].Position.X) < thresholdValue)
                {
                    strand[i].Position = new Vector2(0.0f, strand[i].Position.Y);
                }

                if (delay != 0.0f)
                {
                    strand[i].Velocity = ((strand[i].Position = strand[i].LastPosition) / delay) * strand[i].Mobility;
                }

                strand[i].Force       = Vector2.Zero;
                strand[i].LastGravity = currentGravity;
            }
        }