如何使用Python判断指定点是否在多边形内部(含Turtle绘制多边形场景)
Great questions! Let's tackle both scenarios—starting with the general approach, then moving to how this works with Turtle's polygon drawings. The key here is using the ray casting algorithm, which is the industry standard for this kind of point-in-polygon check.
判断指定点是否在多边形内部(通用+Turtle场景)
1. 通用Python实现:射线法(Ray Casting Algorithm)
This method’s logic is straightforward to grasp:
- Shoot an infinite horizontal ray to the right from the target point
- Count how many times this ray intersects the polygon’s edges
- If the count is odd, the point is inside the polygon; if even, it’s outside
- Bonus: Add a check for whether the point lies exactly on a polygon edge (super useful for edge cases)
Here’s a complete, robust implementation:
def point_on_segment(p, a, b): """Check if point p lies on line segment ab""" # First verify p's coordinates are within the bounds of a and b if min(a[0], b[0]) <= p[0] <= max(a[0], b[0]) and min(a[1], b[1]) <= p[1] <= max(a[1], b[1]): # Check if the three points are collinear using cross product cross_product = (p[0] - a[0]) * (b[1] - a[1]) - (p[1] - a[1]) * (b[0] - a[0]) return abs(cross_product) < 1e-9 # Account for floating point precision errors return False def point_in_polygon(point, polygon): """Determine if a point is inside a polygon (includes boundary checks)""" x, y = point inside = False num_vertices = len(polygon) # Iterate through each edge of the polygon for i in range(num_vertices): vertex_a = polygon[i] vertex_b = polygon[(i + 1) % num_vertices] # Wrap around to first vertex for last edge # Check if point is directly on the current edge if point_on_segment(point, vertex_a, vertex_b): return True # Check if the ray intersects the current edge # First confirm the edge crosses the ray's y-level if ((vertex_a[1] > y) != (vertex_b[1] > y)): # Calculate the x-coordinate of the intersection point x_intersect = ((y - vertex_a[1]) * (vertex_b[0] - vertex_a[0])) / (vertex_b[1] - vertex_a[1]) + vertex_a[0] # If intersection is to the right of the target point, flip the inside flag if x < x_intersect: inside = not inside return inside
Quick usage example:
# Define a sample polygon (a quadrilateral) my_polygon = [(0,0), (0,10), (10,10), (10,0)] # Test points test_point_inside = (5,5) test_point_outside = (15,5) test_point_on_edge = (0,5) print(point_in_polygon(test_point_inside, my_polygon)) # Output: True print(point_in_polygon(test_point_outside, my_polygon)) # Output: False print(point_in_polygon(test_point_on_edge, my_polygon)) # Output: True
2. Turtle-Specific Implementation
If your polygon is drawn with Turtle using a coordinate list, you can reuse the exact same function above—since Turtle’s drawing is just connecting those coordinate points. Here’s a full example that draws the polygon, checks a target point, and visualizes the result:
import turtle # Define your polygon's coordinate list polygon_coords = [(0,0), (-100, 100), (-50, 200), (50, 200), (100, 100)] # Draw the polygon with Turtle pen = turtle.Turtle() pen.speed(2) pen.penup() pen.goto(polygon_coords[0]) pen.pendown() for coord in polygon_coords[1:]: pen.goto(coord) pen.goto(polygon_coords[0]) # Close the polygon # Target point to check target_point = (0, 150) # Use our existing function to check position is_inside = point_in_polygon(target_point, polygon_coords) # Visualize the result: red dot for inside, blue for outside pen.penup() pen.goto(target_point) pen.dot(10, "red" if is_inside else "blue") # Add text feedback on screen pen.penup() pen.goto(-150, -50) pen.write(f"Point {target_point} is {'inside' if is_inside else 'outside'} the polygon", font=("Arial", 12, "normal")) turtle.done()
Pro Tips:
- If you drew your polygon using Turtle’s
begin_poly()/end_poly()methods, you can get the coordinate list withpen.get_poly()and pass that directly topoint_in_polygon. - Always use a small epsilon value (like
1e-9) for floating point comparisons—this avoids false negatives from tiny calculation errors.
内容的提问来源于stack exchange,提问作者jays feng
相关产品推荐
相关产品推荐

