diff --git a/physics/collisions.py b/physics/collisions.py new file mode 100644 index 000000000000..24137aa12a95 --- /dev/null +++ b/physics/collisions.py @@ -0,0 +1,142 @@ +""" +Collision types and final velocities are central to physics. +This module computes final velocities for inelastic and elastic collisions. +It also classifies the collision type from initial and final velocities. + +Description: Collisions happen when two masses interact head-on. +There are two types: inelastic and elastic. In inelastic collisions, the +masses stick together and share one final velocity. In elastic collisions, +momentum and kinetic energy are conserved, and masses rebound. +Momentum is mass times velocity; kinetic energy is 1/2 mv^2. +The collision type comes from comparing initial and final momentum and +kinetic energy of the system. + +Reference: https://en.wikipedia.org/wiki/Collision +""" + + +def inelastic_collisions( + mass1: float, mass2: float, velocity1: float, velocity2: float +) -> float: + """Calculate final velocity after a perfectly inelastic collision. + + The two objects stick together and share a common final velocity. + + Parameters: + mass1: Mass of the first object. + mass2: Mass of the second object. + velocity1: Initial velocity of the first object. + velocity2: Initial velocity of the second object. + + Returns: + The final combined velocity of the two objects. + + Complexity: + Time Complexity: O(1) - Constant execution time for basic arithmetic. + Space Complexity: O(1) - Constant memory allocation. + + Examples: + >>> inelastic_collisions(2.0, 3.0, 5.0, 6.0) + 5.6 + >>> inelastic_collisions(9.0, 8.1, -3.2, 3.1) + -0.22 + """ + initial_momentum = (mass1 * velocity1) + (mass2 * velocity2) + total_mass = mass2 + mass1 + final_velocity = round((initial_momentum / total_mass), 2) + + return final_velocity + + +def elastic_collisions( + mass1: float, mass2: float, velocity1: float, velocity2: float +) -> str: + """Calculate final velocities after a perfectly elastic collision. + + The collision is head-on and conserves both momentum and kinetic energy. + + Parameters: + mass1: Mass of the first object. + mass2: Mass of the second object. + velocity1: Initial velocity of the first object. + velocity2: Initial velocity of the second object. + + Returns: + A formatted string containing the final velocities of both objects. + + Complexity: + Time Complexity: O(1) - Constant execution time for basic math loops. + Space Complexity: O(1) - Constant memory allocation for fixed-size lists. + + Examples: + >>> elastic_collisions(1.0, 2.0, -3.0, -1.0) + '-0.34 ; -2.34' + >>> elastic_collisions(9.0, 8.1, -3.2, 3.1) + '2.76 ; -3.54' + """ + com_velocity = inelastic_collisions(mass1, mass2, velocity1, velocity2) + initial_velocities = [velocity1, velocity2] + final_velocities = [] + + for vel in initial_velocities: + new_vel = -1 * (vel - com_velocity) + final_vel = com_velocity + new_vel + final_velocities.append(round(final_vel, 2)) + + return f"{final_velocities[0]} ; {final_velocities[1]}" + + +def type_collision( + mass1: float, + mass2: float, + velocity_initial1: float, + velocity_initial2: float, + velocity_final1: float, + velocity_final2: float, +) -> str: + """Determine the collision type from initial and final velocities. + + Compares initial and final momentum and kinetic energy to classify the collision. + + Parameters: + mass1: Mass of the first object. + mass2: Mass of the second object. + velocity_initial1: Initial velocity of the first object. + velocity_initial2: Initial velocity of the second object. + velocity_final1: Final velocity of the first object. + velocity_final2: Final velocity of the second object. + + Returns: + A string describing the collision type. + + Complexity: + Time Complexity: O(1) - Constant execution time for evaluation logic. + Space Complexity: O(1) - Constant memory allocation. + + Examples: + >>> type_collision(1.0, 1.0, 2.0, 3.0, 2.0, 3.0) + 'Perfectly Elastic Collision' + >>> type_collision(1.0, 1.0, 2.0, 3.0, 2.5, 2.5) + 'Perfectly Inelastic Collision' + >>> type_collision(1.0, 1.0, 2.0, 3.0, 0.0, 0.0) + 'Inelastic Collision' + """ + momentum_initial = (mass1 * velocity_initial1) + (mass2 * velocity_initial2) + momentum_final = (mass1 * velocity_final1) + (mass2 * velocity_final2) + kinetic_initial = 0.5 * ( + (mass1 * velocity_initial1**2) + (mass2 * velocity_initial2**2) + ) + kinetic_final = 0.5 * ((mass1 * velocity_final1**2) + (mass2 * velocity_final2**2)) + + if kinetic_final == kinetic_initial and momentum_initial == momentum_final: + return "Perfectly Elastic Collision" + elif kinetic_final != kinetic_initial and momentum_initial == momentum_final: + return "Perfectly Inelastic Collision" + else: + return "Inelastic Collision" + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/physics/potential_energy.py b/physics/potential_energy.py index c6544f6f76d8..2047d9bdd208 100644 --- a/physics/potential_energy.py +++ b/physics/potential_energy.py @@ -2,49 +2,64 @@ """ Finding the gravitational potential energy of an object with reference -to the earth,by taking its mass and height above the ground as input +to the earth,by taking its mass and height above the ground as input. +Description : Potential energy is stored energy that depends on the +position or configuration of objects within a force field. It can be +released as kinetic energy when the objects move under that force. -Description : Gravitational energy or gravitational potential energy -is the potential energy a massive object has in relation to another -massive object due to gravity. It is the potential energy associated -with the gravitational field, which is released (converted into -kinetic energy) when the objects fall towards each other. -Gravitational potential energy increases when two objects -are brought further apart. +Gravitational potential energy is the energy an object has because of +its position in a gravitational field. It is the potential energy a +massive object has in relation to another massive object due to gravity. +This energy is associated with the gravitational field and is released +when the objects fall toward each other. Near the Earth's surface this +potential energy is approximately proportional to mass, gravity, and +height, so it is often written as U = mgh for a body close to Earth. -For two pairwise interacting point particles, the gravitational -potential energy U is given by +Spring potential energy is the stored energy in an elastic spring when +it is compressed or stretched from its rest length. For small deformations, +it is proportional to the square of the displacement from equilibrium. + +For two point particles interacting pairwise, the gravitational potential +energy U is given by U=-GMm/R where M and m are the masses of the two particles, R is the distance between them, and G is the gravitational constant. -Close to the Earth's surface, the gravitational field is approximately -constant, and the gravitational potential energy of an object reduces to -U=mgh -where m is the object's mass, g=GM/R² is the gravity of Earth, and h is -the height of the object's center of mass above a chosen reference level. Reference : "https://en.m.wikipedia.org/wiki/Gravitational_energy" """ -def potential_energy(mass: float, height: float) -> float: - # function will accept mass and height as parameters and return potential energy +def gravitational_potential_energy(mass: float, height: float) -> float: """ - >>> potential_energy(10,10) - 980.665 - >>> potential_energy(0,5) - 0.0 - >>> potential_energy(8,0) - 0.0 - >>> potential_energy(10,5) - 490.3325 - >>> potential_energy(0,0) - 0.0 - >>> potential_energy(2,8) - 156.9064 - >>> potential_energy(20,100) - 19613.3 + Function calculates the gravitational potential energy of an object. + + Parameters: + mass: Mass of the object + height: Height the object is at + + Returns: + The value of energy in Joules + + Complexity: + Time Complexity: O(1) - Constant execution time for evaluation logic. + Space Complexity: O(1) - Constant memory allocation. + + Examples: + >>> gravitational_potential_energy(10,10) + 980.665 + >>> gravitational_potential_energy(0,5) + 0.0 + >>> gravitational_potential_energy(8,0) + 0.0 + >>> gravitational_potential_energy(10,5) + 490.3325 + >>> gravitational_potential_energy(0,0) + 0.0 + >>> gravitational_potential_energy(2,8) + 156.9064 + >>> gravitational_potential_energy(20,100) + 19613.3 """ if mass < 0: # handling of negative values of mass @@ -52,10 +67,45 @@ def potential_energy(mass: float, height: float) -> float: if height < 0: # handling of negative values of height raise ValueError("The height above the ground cannot be negative") + return mass * g * height +def spring_potential_energy(spr_con: float, dspl: float) -> float: + """ + Function calculates the spring potential energy of an object. + + Parameters: + spr_con: The spring constant of a spring + dspl: The length of the displacement of the spring + + Returns: + The value of energy in Joules + + Complexity: + Time Complexity: O(1) - Constant execution time for evaluation logic. + Space Complexity: O(1) - Constant memory allocation. + + Examples: + >>> spring_potential_energy(100,2) + 200.0 + >>> spring_potential_energy(10,0.5) + 1.25 + >>> spring_potential_energy(8,0) + 0.0 + >>> spring_potential_energy(14.6,8) + 467.2 + >>> spring_potential_energy(17,4.5) + 172.125 + """ + if spr_con < 0: + raise ValueError("The values for spring_constant cannot be negative") + + return 0.5 * spr_con * (dspl**2) + + if __name__ == "__main__": from doctest import testmod - testmod(name="potential_energy") + print(spring_potential_energy(17, 4.5)) + testmod(name="gravitational_potential_energy")