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

多边形变形:确保内部顶点始终处于边界范围内

核心方法指引

1. 重心坐标映射法

  • 适用场景:初始边界为凸多边形(符合你的限定条件),目标边界可凸可凹
  • 原理:把内部顶点的位置转换成初始边界顶点的线性组合权重(重心坐标),再用该权重结合目标边界顶点坐标,计算内部顶点的目标位置
  • 优势:实现简单,能保证内部顶点始终处于目标边界内部,无需关注变形中间步骤
  • 关键步骤:
    • 计算内部顶点在初始凸多边形中的重心权重
    • 代入目标边界顶点坐标,推导内部顶点的最终位置

2. 径向基函数(RBF)插值法

  • 适用场景:目标边界为凸或凹多边形,需保留原内部顶点的相对形状关系
  • 原理:以边界顶点的起止坐标为控制点,构建薄板样条(TPS)等径向基函数的插值场,对内部顶点做坐标映射
  • 优势:变形结果平滑自然,无需依赖初始凸性的额外限制
  • 关键提示:TPS是这类场景下的首选基函数,能较好保留局部几何特征

3. 重新三角化法

  • 适用场景:对原内部顶点位置无保留需求,仅需适配目标边界的三角化结构
  • 原理:直接基于目标边界顶点,用Delaunay三角化算法重新生成内部网格
  • 优势:完全适配目标边界,无需处理原内部顶点的映射问题,生成的三角网格质量较高
Python实现参考

重心坐标映射示例

import numpy as np

def compute_barycentric(vertex, boundary_vertices):
    n = len(boundary_vertices)
    # 构建线性方程组求解重心权重
    A = np.vstack([boundary_vertices.T, np.ones(n)])
    b = np.array([vertex[0], vertex[1], 1])
    weights = np.linalg.lstsq(A.T, b, rcond=None)[0]
    weights /= np.sum(weights)  # 归一化确保权重和为1
    return weights

def map_to_target(weights, target_boundary):
    return np.dot(weights, target_boundary)

# 测试代码
start_boundary = np.array([[0,0], [1,0], [1,1], [0,1]])
target_boundary = np.array([[0,0], [2,0], [2,2], [0,3]])
internal_vertex = np.array([0.5, 0.5])

weights = compute_barycentric(internal_vertex, start_boundary)
target_internal = map_to_target(weights, target_boundary)
print(target_internal)

TPS径向基函数插值示例

import numpy as np
from scipy.interpolate import Rbf

# 边界顶点起止坐标
start_points = np.array([[0,0], [1,0], [1,1], [0,1]])
target_points = np.array([[0,0], [2,0], [2,2], [0,3]])

# 创建TPS插值器
rbf_x = Rbf(start_points[:,0], start_points[:,1], target_points[:,0], function='thin_plate')
rbf_y = Rbf(start_points[:,0], start_points[:,1], target_points[:,1], function='thin_plate')

# 映射内部顶点
internal_points = np.array([[0.5, 0.5], [0.25, 0.75]])
target_x = rbf_x(internal_points[:,0], internal_points[:,1])
target_y = rbf_y(internal_points[:,0], internal_points[:,1])
target_internal = np.column_stack((target_x, target_y))
print(target_internal)

Delaunay重新三角化示例

import numpy as np
from scipy.spatial import Delaunay
import matplotlib.pyplot as plt

# 目标边界顶点(需按顺序构成简单多边形)
target_boundary = np.array([[0,0], [2,0], [2,2], [0,3]])
# 生成目标边界内的内部点
np.random.seed(42)
internal_points = np.random.rand(10, 2) * np.array([2, 3])

# 过滤边界外的点
tri = Delaunay(target_boundary)
valid_internal = internal_points[tri.find_simplex(internal_points) != -1]

# 合并顶点并重新三角化
all_points = np.vstack([target_boundary, valid_internal])
final_tri = Delaunay(all_points)

# 可视化结果
plt.triplot(all_points[:,0], all_points[:,1], final_tri.simplices)
plt.plot(target_boundary[:,0], target_boundary[:,1], 'ro')
plt.plot(valid_internal[:,0], valid_internal[:,1], 'bo')
plt.show()
资料推荐
  • 《计算机图形学原理及实践》:详细讲解重心坐标、插值变形和三角化算法的原理与工程实现
  • 《Thin Plate Splines for Image Warping》:TPS径向基函数变形的经典论文,可深入理解插值逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:17:44