基于graphics.py实现点位所属图形检测的技术需求问询
Alright, let's figure out how to make this work with graphics.py! Since the library doesn't have a built-in method to check which shape a point is inside of directly, we can build our own solution that fits your radar detection use case perfectly.
The Core Idea
First, we need to keep track of all the shapes we've drawn on the window—graphics.py doesn't automatically maintain this list for us. Then, we can write a function that checks a given (x, y) coordinate against every stored shape to see if it's inside any of them.
Step 1: Track All Drawn Shapes
Create a global or class-level list to store every shape you draw. Add a helper function to handle adding shapes to this list and drawing them to the window in one step:
from graphics import * # This list will hold every shape we draw drawn_shapes = [] def draw_and_track_shape(shape, window): """Draw a shape to the window and add it to our tracked list""" drawn_shapes.append(shape) shape.draw(window)
Step 2: Implement Point-in-Shape Checks
Next, write a function that takes an x and y coordinate, then checks against all tracked shapes to find if the point is inside any of them. We'll handle common shape types like Circle, Rectangle, Oval, and Polygon individually:
def get_shape_at_point(x, y): """Check if (x,y) is inside any tracked shape, return the shape or None""" for shape in drawn_shapes: # Check for Circle if isinstance(shape, Circle): center = shape.getCenter() dx = x - center.getX() dy = y - center.getY() # Compare squared distance to squared radius (avoids sqrt for efficiency) if dx**2 + dy**2 <= shape.getRadius()**2: return shape # Check for Rectangle elif isinstance(shape, Rectangle): p1 = shape.getP1() p2 = shape.getP2() # Handle cases where P1 isn't the top-left corner min_x = min(p1.getX(), p2.getX()) max_x = max(p1.getX(), p2.getX()) min_y = min(p1.getY(), p2.getY()) max_y = max(p1.getY(), p2.getY()) if min_x <= x <= max_x and min_y <= y <= max_y: return shape # Check for Oval elif isinstance(shape, Oval): p1 = shape.getP1() p2 = shape.getP2() min_x = min(p1.getX(), p2.getX()) max_x = max(p1.getX(), p2.getX()) min_y = min(p1.getY(), p2.getY()) max_y = max(p1.getY(), p2.getY()) # Calculate ellipse center and semi-axes cx = (min_x + max_x) / 2 cy = (min_y + max_y) / 2 a = (max_x - min_x) / 2 b = (max_y - min_y) / 2 # Use standard ellipse equation to check containment if ((x - cx)/a)**2 + ((y - cy)/b)**2 <= 1: return shape # Check for Polygon (using ray-casting algorithm) elif isinstance(shape, Polygon): points = shape.getPoints() inside = False num_points = len(points) for i in range(num_points): p = points[i] q = points[(i + 1) % num_points] # Check if the point's y is between the edge's y values if ((p.getY() > y) != (q.getY() > y)): # Calculate the x intersection of the edge with the point's y x_intersect = (y - p.getY()) * (q.getX() - p.getX()) / (q.getY() - p.getY()) + p.getX() if x <= x_intersect: inside = not inside if inside: return shape # If no shape contains the point, return None return None
Step 3: Use It in Your Radar Logic
Now you can use this function exactly like the Point(x,y).getObject() logic you wanted:
# Example setup win = GraphWin("Radar Detection", 800, 600) # Draw some test shapes test_circle = Circle(Point(400, 300), 75) test_circle.setFill("blue") draw_and_track_shape(test_circle, win) test_rect = Rectangle(Point(150, 150), Point(250, 250)) test_rect.setFill("red") draw_and_track_shape(test_rect, win) # Radar detection example radar_x, radar_y = 400, 300 # Your radar's detected point detected_shape = get_shape_at_point(radar_x, radar_y) if detected_shape is None: print("No object detected at this coordinate") # Add your radar "clear" logic here else: print(f"Detected object: {type(detected_shape).__name__}") # Add your radar "target found" logic here win.getMouse() win.close()
Optimizations for Your Radar Use Case
- Filter by Radar Range: If your radar only checks a specific area, first filter the
drawn_shapeslist to exclude shapes that are completely outside the radar bounds. This reduces the number of checks you need to do. - Encapsulate in a Class: For cleaner code, wrap the shape tracking and detection logic in a
RadarSystemclass instead of using global variables.
内容的提问来源于stack exchange,提问作者JazzDoe

