You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Shapely沿由(x,y)点集组成的中心线绘制正方形/矩形?

How to Draw Red Squares Along a Line Using Shapely

First off, Shapely excels at geometric computations but doesn’t handle rendering on its own—so we’ll pair it with Matplotlib to visualize the final result. Here’s a step-by-step solution tailored to your needs:

Step 1: Import Required Libraries

Start by importing the tools we’ll need for geometry and plotting:

from shapely.geometry import LineString, Polygon
import matplotlib.pyplot as plt

Step 2: Define Your Line Coordinates

Convert your list of (x,y) points into a Shapely LineString to represent the original black line:

# Replace this with your actual coordinate list
coordinate_list = [(0, 0), (2, 1), (3, 3), (5, 4), (6, 2)]
original_line = LineString(coordinate_list)

Step 3: Generate Squares Along the Line

We’ll cover two common scenarios you might want:

Scenario 1: Squares Using Each Line Segment as a Side

This creates squares where every segment of your line acts as one side of the square, oriented perpendicular to the segment’s direction:

def create_square_from_segment(segment):
    # Extract the two endpoints of the segment
    point_a = segment.coords[0]
    point_b = segment.coords[1]
    
    # Calculate the vector of the segment
    dx = point_b[0] - point_a[0]
    dy = point_b[1] - point_a[1]
    
    # Compute the other two vertices (rotated 90° counterclockwise)
    point_c = (point_b[0] - dy, point_b[1] + dx)
    point_d = (point_a[0] - dy, point_a[1] + dx)
    
    # Return the square as a Shapely Polygon
    return Polygon([point_a, point_b, point_c, point_d])

# Split the original line into individual segments
line_segments = [LineString([coordinate_list[i], coordinate_list[i+1]]) 
                 for i in range(len(coordinate_list)-1)]

# Generate squares for each segment
segment_squares = [create_square_from_segment(seg) for seg in line_segments]

Scenario 2: Fixed-Size Squares Centered Along Each Segment

If you want squares of consistent size (regardless of segment length), use this approach. Squares will be centered on each segment and aligned with its direction:

def create_fixed_size_square(segment, side_length):
    point_a = segment.coords[0]
    point_b = segment.coords[1]
    
    dx = point_b[0] - point_a[0]
    dy = point_b[1] - point_a[1]
    segment_length = segment.length
    
    # Unit vectors along and perpendicular to the segment
    unit_along = (dx / segment_length, dy / segment_length)
    unit_perpendicular = (-dy / segment_length, dx / segment_length)  # CCW direction
    
    # Midpoint of the segment
    mid_x = (point_a[0] + point_b[0]) / 2
    mid_y = (point_a[1] + point_b[1]) / 2
    
    half_side = side_length / 2
    
    # Calculate all four corners of the square
    corner1 = (mid_x + half_side*unit_along[0] + half_side*unit_perpendicular[0],
               mid_y + half_side*unit_along[1] + half_side*unit_perpendicular[1])
    corner2 = (mid_x + half_side*unit_along[0] - half_side*unit_perpendicular[0],
               mid_y + half_side*unit_along[1] - half_side*unit_perpendicular[1])
    corner3 = (mid_x - half_side*unit_along[0] - half_side*unit_perpendicular[0],
               mid_y - half_side*unit_along[1] - half_side*unit_perpendicular[1])
    corner4 = (mid_x - half_side*unit_along[0] + half_side*unit_perpendicular[0],
               mid_y - half_side*unit_along[1] + half_side*unit_perpendicular[1])
    
    return Polygon([corner1, corner2, corner3, corner4])

# Generate fixed-size squares (adjust side_length as needed)
fixed_size_squares = [create_fixed_size_square(seg, side_length=1) for seg in line_segments]

Step 4: Visualize the Result

Use Matplotlib to draw the original black line and red squares:

# Plot the original line
x_line, y_line = original_line.xy
plt.plot(x_line, y_line, color='black', linewidth=2, label='Original Line')

# Plot squares (use segment_squares or fixed_size_squares based on your choice)
for square in fixed_size_squares:
    x_sq, y_sq = square.exterior.xy
    plt.fill(x_sq, y_sq, color='red', alpha=0.5, label='Red Squares' if fixed_size_squares.index(square)==0 else "")

plt.legend()
plt.axis('equal')  # Ensures squares don't look stretched
plt.show()

Quick Tips:

  • To rotate squares clockwise instead of counterclockwise, swap the perpendicular vector to (dy / segment_length, -dx / segment_length).
  • Adjust the alpha value in plt.fill() to make squares more or less transparent.
  • Shapely’s Polygon class ensures your squares are valid geometric shapes, which you can use for further calculations if needed.

内容的提问来源于stack exchange,提问作者Kush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:44:30