A while ago, a friend asked me the following question: “Is it possible for the horizontal component of the baseball’s velocity to increase in magnitude and not be negated when the batter hits the ball?” That is, can the batter hit the ball in such as way as to make the ball continue traveling toward the catcher, yet increase the horizontal velocity of the ball? He posted this question on some forums and received some varied responses. Half the respondents said no and half said yes. He asked me, so I figured I’d test it out in sage.

The first thing to point out is that this is still a very unrealistic calculation. I did my best to quickly account for properties the ball may have (size, weight, elasticity, etc.) and made a quick graphical representation of the ball and bat, with vectors representing their velocities. Here’s the code, and then I’ll discuss some of the findings.

def mph_to_mps(num): return 0.44704*num   def mps_to_mph(num): return 2.23693*num   def deg_to_rad(ang): return ang*pi/180   def rad_to_deg(ang): return ang*180/pi   def oz_to_g(mass): return 28.34952*mass   def get_velocity(speed,angle): # speed must be in meters per second # angle is measured from horizon in radians return vector([speed*cos(angle),speed*sin(angle)])   def get_momentum(mass,velocity): # mass must be in grams # velocity must be a vector return mass*velocity   @interact def _(ball=['Baseball', '11Softball', '12Softball'], ball_angle=slider(0,90,0.05,default=20,label='Ball Angle (degrees from horizontal)'),\ ball_speed=slider(10,90,0.1,default=70,label='Ball Speed (mph)'),\ swing_angle=slider(-45,45,0.1,default=10,label='Swing Angle (degrees from horizontal)'),\ bat_speed=slider(10,55,0.1,default=30,label='Bat Speed (mph)'),\ bat_mass=slider(17,42,1,default=30,label='Bat Weight (in ounces)'),\ impact_angle=slider(-90,90,0.05,default=10,label='Impact Angle (relative to swing)'),\ efficiency=slider(80,99.5,0.5,default=96,label='efficiency factor (%)'),\ elasticity=slider(0,1,0.05,default=0.15,label='elasticity factor of ball')): if ball is 'Baseball': ball_rad = 0.03692394#meters ball_mass = 145#grams if ball is '11Softball': ball_rad = 0.04446789#meters ball_mass = 174#grams if ball is '12Softball': ball_rad = 0.04851019#meters ball_mass = 206#grams ball_angle = deg_to_rad(-ball_angle) print "Pitched Ball Speed (x-coord): %s mph" % n(cos(ball_angle)*ball_speed,digits=5) print "Pitched Ball Speed (y-coord): %s mph" % n(sin(ball_angle)*ball_speed,digits=5) ball_speed = mph_to_mps(ball_speed) ball_velocity = get_velocity(ball_speed,ball_angle) ball_momentum = get_momentum(ball_mass,ball_velocity) DBallMV = (1/ball_momentum.norm())*5*ball_momentum swing_angle = pi-deg_to_rad(swing_angle) bat_speed = mph_to_mps(bat_speed) bat_velocity = get_velocity(bat_speed,swing_angle) bat_mass = oz_to_g(bat_mass) bat_momentum = get_momentum(bat_mass*efficiency/100,bat_velocity) DBatMV = (1/bat_momentum.norm())*5*bat_momentum impact_angle=swing_angle-deg_to_rad(impact_angle) # find bat_momentum projection vector parallel to impact_angle moment_hit = vector([cos(impact_angle),sin(impact_angle)]) moment_hit = moment_hit.dot_product(bat_momentum) moment_hit = moment_hit*vector([cos(impact_angle),sin(impact_angle)]) # find approximate force of ball acceleration moment moment_ball = vector([cos(impact_angle),sin(impact_angle)]) moment_ball = moment_ball.dot_product(ball_momentum)*elasticity moment_ball = -moment_ball*vector([cos(impact_angle),sin(impact_angle)]) # add momentum components new_moment = moment_hit + ball_momentum + moment_ball DBallMV2 = (1/new_moment.norm())*5*new_moment ball_velocity = (1/ball_mass)*new_moment print "Hit Ball Speed (x-coord): %s mph" % n(mps_to_mph(ball_velocity[0]),digits=5) print "Hit Ball Speed (y-coord): %s mph" % n(mps_to_mph(ball_velocity[1]),digits=5) ball_speed = ball_velocity.norm() print "Hit Ball Speed (overall): %s mph" % n(mps_to_mph(ball_speed),digits=5) # Draw DBall = circle((0,0),radius=1,rgbcolor=(0,0,0)) BatCoord1 = (-2*cos(impact_angle),2*sin(-impact_angle)) BatCoord2 = (-2*cos(impact_angle)+DBatMV[0],2*sin(-impact_angle)+DBatMV[1]) DBat = circle(BatCoord1,radius=1,rgbcolor='brown',fill=True) DBallM = arrow((0,0),(DBallMV[0],DBallMV[1]),color='red') DBatM = arrow(BatCoord1,BatCoord2,color='blue') DBallM2 = arrow((0,0),(DBallMV2[0],DBallMV2[1]),color='green') show(DBall+DBat+DBallM+DBatM+DBallM2,aspect_ratio=1,axes=False) print "Direction Legend: Red (pitched ball), Blue (bat), Green (hit ball)"

When executed in the sage notebook, this creates an interactive slider-based tool that allows me to change all the relevant variables (at least the ones that I’ve accounted for). By default, certain reasonable values are used to construct the situation. Here’s what we get.

I’m considering this in mile per hour because that what all the statistics in American baseball are given in. The white circle is the ball, the red circle is the bat. The arrows represent vectors: red is the velocity vector of the pitched baseball at the instant just before striking the bat, blue is the velocity vector of the bat at the instant just before striking the ball, and green is the velocity of the hit baseball.

There are many factors to consider here. The ball and bat are traveling at different angles relative to the ground. The ball may not hit the bat squarely in the center (the hit ball may be tipped back). We can simulate that situation by setting the impact angle higher on the bat. The impact angle in this bit of code is the angle where the ball hits the bat relative to the swinging velocity of the bat.

Notice that in this example, the x-coordinate velocity of the ball is lower after hitting the bat. That is, the ball has slowed down its horizontal speed. I basically used the sliders to find a combination of variable values that would permit precisely the situation that my friend was looking for, making the x-coordinate velocity of the ball increase after striking the bat. Here’s an example.

Notice that the ball increases in its horizontal speed from 65.685 to 67.331 miles per hour. If the swing angle and impact angle are great enough, this situation occurs much more frequently than one might expect.

Hit Fastballs Don’t Fly Farther

This is something that is accepted as common knowledge in baseball and has never sat well with me. What most any baseball fan will tell you is that a fastball, if hit, will travel farther than a ball thrown at a slower speed and hit by the same batter. Is this true?

The justification for such an idea can be seen in the following experiment. Imagine a pitcher throws a ball at a brick wall. The harder the pitcher throws, the farther the ball will bounce back due to the ball’s elasticity. It stands to reason that the same effect occurs when a batter hits a fastball.

The only problem with this reasoning is that it doesn’t account for the momentum or movement of the wall or bat. The wall doesn’t budge when hit by the baseball, and the baseball’s energy gets transferred through elasticity and pushes the ball backwards. On the other hand, the bat is much, much lighter and isn’t in a fixed location. The momentum of a fastball will exert more force on a bat than that of a slowly thrown ball, slowing the bat and making it have less of an impact on the distance the ball carries.

Not convinced? Imagine what would happen if we were to take this to an extreme. Imagine the ball starts to travel at 1,000,000 miles per hour and, somehow, the batter swings and connects. At that point, even though the ball is very light, it has an incredible amount of momentum due to its velocity. Upon hitting the bat, the ball would demolish the bat and probably just keep going toward a catcher who is about to have a very bad day. Consider the following two situations.

Notice that the ball is pitched at 75 mph and the ball ends up traveling 102.39 mph after striking the bat. Now, we’ll change the pitched velocity to 85.79 mph and watch what happens to the final speed of the ball. It goes down to 92.93 mph.