package com.sundablog.clipper;
import java.util.ArrayList;
/**
* 多边形路径集合类,扩展自ArrayList<Path>,用于存储和处理多个多边形路径
* 提供从PolyTree转换、清理多边形、获取边界框等功能
*/
public class Paths extends ArrayList<Path> {
/**
* 从PolyTree中提取所有闭合路径
* @param polytree 多边形树结构
* @return 包含所有闭合路径的Paths集合
*/
public static Paths closedPathsFromPolyTree(PolyTree polytree ) {
final Paths result = new Paths();
// result.Capacity = polytree.Total;
result.addPolyNode( polytree, PolyNode.NodeType.CLOSED ); // 递归添加所有闭合节点
return result;
}
/**
* 将完整的PolyTree转换为Paths集合,包含所有类型的路径
* @param polytree 多边形树结构
* @return 包含所有路径的Paths集合
*/
public static Paths makePolyTreeToPaths(PolyTree polytree ) {
final Paths result = new Paths();
// result.Capacity = polytree.Total;
result.addPolyNode( polytree, PolyNode.NodeType.ANY ); // 递归添加所有节点
return result;
}
/**
* 从PolyTree中提取所有开放路径
* @param polytree 多边形树结构
* @return 包含所有开放路径的Paths集合
*/
public static Paths openPathsFromPolyTree(PolyTree polytree ) {
final Paths result = new Paths();
// result.Capacity = polytree.ChildCount;
for (final PolyNode c : polytree.getChilds()) {
if (c.isOpen()) { // 检查是否为开放路径
result.add( c.getPolygon() ); // 添加开放路径的多边形
}
}
return result;
}
/**
* 序列化版本ID
*/
private static final long serialVersionUID = 1910552127810480852L;
/**
* 默认构造函数,创建一个空的Paths集合
*/
public Paths() {
super();
}
/**
* 创建具有指定初始容量的Paths集合
* @param initialCapacity 初始容量
*/
public Paths( int initialCapacity ) {
super( initialCapacity );
}
/**
* 递归地将PolyNode及其子节点添加到Paths集合中
* @param polynode 要添加的多边形节点
* @param nt 节点类型过滤器,指定添加开放/闭合/所有类型的节点
*/
public void addPolyNode(PolyNode polynode, PolyNode.NodeType nt ) {
boolean match = true;
switch (nt) {
case OPEN:
return; // 如果需要开放节点但该方法不处理,直接返回
case CLOSED:
match = !polynode.isOpen(); // 检查节点是否为闭合节点
break;
default: // ANY类型,匹配所有节点
break;
}
if (polynode.getPolygon().size() > 0 && match) { // 如果节点有多边形且匹配类型条件
add( polynode.getPolygon() ); // 添加多边形到集合
}
// 递归处理所有子节点
for (final PolyNode pn : polynode.getChilds()) {
addPolyNode( pn, nt );
}
}
/**
* 清理所有多边形路径,移除冗余点,使用默认距离阈值
* @return 清理后的Paths集合
*/
public Paths cleanPolygons() {
return cleanPolygons( 1.415 ); // 使用默认距离阈值约为√2
}
/**
* 清理所有多边形路径,移除冗余点
* @param distance 清理距离阈值,小于此距离的相邻点将被合并
* @return 清理后的Paths集合
*/
public Paths cleanPolygons(double distance ) {
final Paths result = new Paths( size() ); // 创建与原集合大小相同的结果集合
for (int i = 0; i < size(); i++) {
result.add( get( i ).cleanPolygon( distance ) ); // 对每个多边形应用清理操作
}
return result;
}
/**
* 计算所有路径的边界框
* @return 包含所有路径的最小矩形边界
*/
public LongRect getBounds() {
int i = 0;
final int cnt = size();
final LongRect result = new LongRect();
// 跳过空路径,找到第一个非空路径
while (i < cnt && get( i ).isEmpty()) {
i++;
}
if (i == cnt) { // 如果所有路径都为空,返回空边界框
return result;
}
// 初始化边界框为第一个有效路径的第一个点
result.left = get( i ).get( 0 ).getX();
result.right = result.left;
result.top = get( i ).get( 0 ).getY();
result.bottom = result.top;
// 遍历所有路径的所有点,更新边界框
for (; i < cnt; i++) {
for (int j = 0; j < get( i ).size(); j++) {
if (get( i ).get( j ).getX() < result.left) {
result.left = get( i ).get( j ).getX();
}
else if (get( i ).get( j ).getX() > result.right) {
result.right = get( i ).get( j ).getX();
}
if (get( i ).get( j ).getY() < result.top) {
result.top = get( i ).get( j ).getY();
}
else if (get( i ).get( j ).getY() > result.bottom) {
result.bottom = get( i ).get( j ).getY();
}
}
}
return result;
}
/**
* 反转所有路径的顶点顺序
* 这会改变多边形的方向(顺时针变为逆时针,反之亦然)
*/
public void reversePaths() {
for (final Path poly : this) {
poly.reverse(); // 调用每个路径的reverse方法
}
}
}
最后修改:2025 年 12 月 03 日
© 允许规范转载