I have been trying to pack as many circles in a polygon as possible.
Having found this – Controlled circle packing with Python –
I though it would be a useful code if the checkBorders
function was to be changed to one that fits better.
I have tried solving that using physics and forces: when a ball crosses the edge, we find the normal of that edge and bounce back the ball at the same angle.
However, my code does not seem to be working at all, could somebody perhaps help with this?
This is what I have so far
def checkBorders(self, ball):
pointy = Point(ball.x, ball.y)
polygon = Polygon(self.POLY)
is_inside = polygon.contains(pointy)
if not is_inside:
min_distance = float("inf")
closest_edge = None
for i in range(len(self.POLY)):
p1, p2 = np.array(self.POLY[i]), np.array(
self.POLY[(i + 1) % len(self.POLY)]
)
edge = p2 - p1
edge_normalized = self._normalize(edge)
ball_to_p1 = np.array(ball.position) - p1
projection = np.dot(ball_to_p1, edge_normalized) * edge_normalized
distance = np.linalg.norm(ball_to_p1 - projection)
if distance < min_distance:
min_distance, closest_edge = distance, (p1, p2)
normal = np.array(
[
closest_edge[1][1] - closest_edge[0][1],
closest_edge[0][0] - closest_edge[1][0],
]
)
normal = self._normalize(normal) # Normalize the edge normal
# Calculate the reflection vector
dot_product = np.dot(ball.velocity, normal)
ball.velocity = ball.velocity - 2 * dot_product * normal
ball.update()
Output – this is what I get and the circles are now not moving at all.
sara brdnik is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3