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

Matlab中如何将凸包分割为多个共享边界的 hull 技术咨询

Splitting a Convex Hull into Shared-Boundary Sub-Hulls in MATLAB

Great question! I’ve worked with convex hull partitioning in MATLAB before, so I can walk you through the relevant algorithms and practical implementations to split a single convex hull into shared-boundary sub-hulls of the same category.

Relevant Algorithms

Since your original shape is a convex hull, we can leverage its properties to ensure all sub-hulls remain convex and share clean boundaries:

  • Constrained Convex Partitioning: The most straightforward approach. Define internal split lines (connecting vertices, edges, or internal points) to divide the hull into smaller convex sub-hulls. Any straight-line split of a convex shape will result in convex sub-hulls, and adjacent sub-hulls will automatically share the split line as a boundary.
  • Voronoi-Based Partitioning: If you need sub-hulls centered around specific internal points (e.g., cluster centers), place seed points inside the hull, compute the Voronoi diagram, then clip each Voronoi cell to the original convex hull. The clipped cells will be convex and share boundaries with their neighbors.
  • Grid-Based Partitioning: For regular, uniform splits (like dividing the hull into equal rectangles/triangles), overlay a grid on the hull and extract each grid cell that lies within the original shape. This works well for simple, structured partitioning.

MATLAB Implementation Examples

Let’s dive into code for each method, using practical examples:

1. Constrained Split (Manual Boundary Definition)

Suppose you have a convex hull and want to split it along a vertical line through its center:

% Define original convex hull (square vertices)
hull_vertices = [0 0; 0 1; 1 1; 1 0];

% Define split line: connects bottom-center to top-center
split_start = [0.5, 0];
split_end = [0.5, 1];

% Construct the two sub-hulls
subhull_left = [hull_vertices(1:2, :); split_end; split_start];
subhull_right = [hull_vertices(3:4, :); split_start; split_end];

% Visualize results
figure;
plot(hull_vertices(:,1), hull_vertices(:,2), 'b-', 'LineWidth', 2);
hold on;
plot(subhull_left(:,1), subhull_left(:,2), 'r--', 'LineWidth', 1.5);
plot(subhull_right(:,1), subhull_right(:,2), 'g--', 'LineWidth', 1.5);
plot([split_start(1), split_end(1)], [split_start(2), split_end(2)], 'ko-', 'MarkerSize', 6);
axis equal;
legend('Original Hull', 'Left Sub-hull', 'Right Sub-hull');

2. Voronoi-Based Partitioning

If you want to split the hull into sub-hulls around 3 internal seed points:

% Original convex hull (rectangle)
hull_vertices = [0 0; 0 2; 3 2; 3 0];

% Define 3 seed points inside the hull
seeds = [1 1; 2 1; 1.5 1.5];

% Compute Voronoi diagram
[vx, vy] = voronoi(seeds(:,1), seeds(:,2));

% Clip each Voronoi cell to the convex hull
subhulls = cell(size(seeds,1), 1);
hull_closed = [hull_vertices; hull_vertices(1,:)]; % Close the hull polygon

for i = 1:size(seeds,1)
    % Extract finite vertices of the Voronoi cell
    cell_vx = vx(:,i);
    cell_vy = vy(:,i);
    cell_vertices = [cell_vx(~isinf(cell_vx)), cell_vy(~isinf(cell_vy))];
    
    % Clip cell to the original hull using polyxpoly
    [clip_x, clip_y] = polyxpoly(cell_vertices(:,1), cell_vertices(:,2), ...
                                hull_closed(:,1), hull_closed(:,2));
    subhulls{i} = [clip_x, clip_y];
end

% Plot results
figure;
plot(hull_vertices(:,1), hull_vertices(:,2), 'b-', 'LineWidth', 2);
hold on;
colors = ['r', 'g', 'm'];
for i = 1:length(subhulls)
    plot(subhulls{i}(:,1), subhulls{i}(:,2), [colors(i) '--'], 'LineWidth', 1.5);
    plot(seeds(i,1), seeds(i,2), [colors(i) 'o'], 'MarkerSize', 8);
end
axis equal;
legend('Original Hull', 'Sub-hull 1', 'Sub-hull 2', 'Sub-hull 3');

3. Grid-Based Regular Split

To split the hull into a 2x3 grid of rectangular sub-hulls:

% Original convex hull (rectangle)
hull_vertices = [0 0; 0 4; 6 4; 6 0];

% Grid parameters: 2 rows, 3 columns
num_rows = 2;
num_cols = 3;

% Calculate grid step sizes
x_min = min(hull_vertices(:,1));
x_max = max(hull_vertices(:,1));
y_min = min(hull_vertices(:,2));
y_max = max(hull_vertices(:,2));
x_step = (x_max - x_min)/num_cols;
y_step = (y_max - y_min)/num_rows;

% Generate sub-hulls
subhulls = cell(num_rows*num_cols, 1);
hull_closed = [hull_vertices; hull_vertices(1,:)];
idx = 1;

for i = 0:num_rows-1
    for j = 0:num_cols-1
        % Define grid cell vertices
        cell_vertices = [x_min + j*x_step, y_min + i*y_step;
                         x_min + (j+1)*x_step, y_min + i*y_step;
                         x_min + (j+1)*x_step, y_min + (i+1)*y_step;
                         x_min + j*x_step, y_min + (i+1)*y_step];
        
        % Clip cell to hull (redundant here, but useful for non-rectangular convex hulls)
        [clip_x, clip_y] = polyxpoly(cell_vertices(:,1), cell_vertices(:,2), ...
                                    hull_closed(:,1), hull_closed(:,2));
        subhulls{idx} = [clip_x, clip_y];
        idx = idx + 1;
    end
end

% Plot
figure;
plot(hull_vertices(:,1), hull_vertices(:,2), 'b-', 'LineWidth', 2);
hold on;
colors = ['r', 'g', 'm', 'c', 'y', 'k'];
for i = 1:length(subhulls)
    plot(subhulls{i}(:,1), subhulls{i}(:,2), [colors(i) '--'], 'LineWidth', 1.5);
end
axis equal;
title('Grid-Based Convex Hull Split');

Key Notes

  • Convexity Guarantee: Since the original shape is convex, all splits using these methods will produce convex sub-hulls—no need to re-compute convexity for each sub-hull.
  • Shared Boundaries: All adjacent sub-hulls will share exact boundary segments, so there’s no gap or overlap between them.
  • Iterative Splitting: For complex splits (more than 2 sub-hulls), you can iteratively apply constrained partitioning: split the original hull into two, then split one of the sub-hulls again, and so on.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:04:37