0

So basically I'm making a pool game (sort of) on c++. I'm still thinking about the theory and how exactly to make it before I start coding and I'm a bit stuck. So the ball starting coordinates are given and also an input is given on how much power is going into the shot and the direction of the shot with coordinates.

Example:

> Ball: (280,70)

Input:
> 2(power) 230(x) 110(y)

Output:
> 180(x) 150(y)

The power means that basically it's going to go X * the distance of the given coordinates. So if it's 1 it would just go to 230 110 but if it's more it will go double, triple, quadruple, etc. times that distance. (external factors should be ignored - friction, etc.)

By now I've managed to create an algorithm to find the line that the ball is going to travel on. But I can't figure out on what point of this line the ball will stop at. Any help will be greatly appreciated!

Also one more thing, I also need to calculate where it would go if it hits the wall of the pool table(pool table is a 2:1 rectangle with given coordinates of edges) and I've also managed to find the line where it would travel on but not the exact point where it will stop.

TL;DR I need to find the point of the line of travel that a billiards ball will stop at.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • 1
    In your frictionless world, a pool ball (without spin) will travel until it encounters (hits) another object, such as a bumper, another ball or the pocket. The force (power) that you put into the ball means that it will hit its target in less time. There is no friction, so there is nothing to slow down the ball. Physics, my friend, physics. – Thomas Matthews Dec 10 '21 at 18:21
  • Yeah that is true. But in this case it's like the ball goes to the given coordinates by traveling on the line and if the power is 1 it stops but if it's more it continues on the same line the same distance X(power) times. – Iliqn Gawrilow Dec 10 '21 at 18:25
  • If we simplify this to a 2D view, the Cue (a line segment) is coming into contact with a circle. The Cue has a magnitude and direction (Physics definition of a vector). Since your being simple, the direction that the circle will go is the direction that the line segment "hit" the circle. The magnitude will be applied to the circle. More Physics. – Thomas Matthews Dec 10 '21 at 18:25
  • The two ways the ball could lose energy (and therefore slow down) is friction and inelastic collisions. If you don't want to explicitly model friction, then you can fake it by having the velocity of the ball start at some value proportional to your "power" then decrease (linearly, quadratically, etc) with distance traveled. – Cory Kramer Dec 10 '21 at 18:25
  • @CoryKramer Yeah pretty much – Iliqn Gawrilow Dec 10 '21 at 18:27
  • You may want to use Polar Coordinates since you are dealing with directions (angles) and distances (radius). Convert back to Cartesian Coordinates as necessary. – Thomas Matthews Dec 10 '21 at 18:27

1 Answers1

0

You probably want to work in terms of orthogonal components, basically thinking of the displacement of the ball in terms of deltaX and deltaY instead of finding a line it will travel. Conveniently, you are already in rectangular coordinates and can compute your changes in x and y followed by scaling them by your power factor. For example, here, deltaX = 2*(280-230) or -100, so the destination will be 280 + -100, which equals 180.

To account for the edges, you bound the movement in any direction to be within the 4 edges. You'll have some extra displacement if it strikes the edge. You might think of a bounce as reversing some of the remainder and then recursively call your moveBall function with power 1 when given the location on the edge the ball strikes plus the excess deltaX and deltaY changed in sign appropriately. If moveBall took std::pair<int, int> startingPosition, std::pair<int, int> displacement, int power, if it hits the wall, you'll return moveBall(locationOnEdge, predictedLocationBasedOnExcess, 1). This setup will recursively call itself as many times as is needed until the ball finally finds its ending position (a ball can bounce off edges multiple times).

For example, if you had an edge at x = 200 and y = 100 (meaning your asserted desired output was different), you'd have a remaining deltaX of -20 and deltaY of 50. Since the ball was traveling up and to the left, it will bounce down and to the left. You'd call moveBall with starting location (200, 100), displacement (-20, -50), and power 1.

I'm doing some guesswork here since you didn't define the expected behavior when the ball bounces off an edge.

user904963
  • 1,520
  • 2
  • 15
  • 33
  • So if it hits the edge I don't need to calculate the angle? And also one more thing - how would this formula change if the diameter is more than 0 so it's like an actual ball and not just moving nothing? – Iliqn Gawrilow Dec 10 '21 at 22:16
  • It all depends on friction. Without it, it matters not whether it is a ball or point, no rotation is imparted by the bumper and the angle of reflection is simply `Pi - angle of incidence`, If the bumper is elastic (energy loss in the rebound) then use a simple conservation of momentum for elastic collisions to set the state (momentum/energy) of the ball after collision with the bumper. – David C. Rankin Dec 10 '21 at 23:05
  • Most problems like this can be solved via energy (`1/2 * m * v * v`) and momentum.(`m * v`). In the inelastic case, you know both energy and momentum are conserved, so you can write the equations for the energy and momentum before and after the collision and set them equal to one another (e.g. `m0 = m1` and `E0 = E1`) to solve for most unknowns. Positions can be used to derive a direction or path. As mentioned by others earlier, **always** break **all** vectors down into `i`, `j`, `k` components and solve using straight vector methods. Much easier than drawing equivalent triangles. – David C. Rankin Dec 12 '21 at 01:30