将任意三角形装入有限的盒子中
Packing arbitrary triangles into a finite box?
我需要将三角形尽可能紧密地打包到一个盒子中,作为3D优化的一部分(我正在将不同纹理的alpha-using片段填充到单个不同纹理中,用于深度排序,因此纹理不会随着每个新的tri而切换)
有一个算法来做这个吗?三角形本身可以被制作成可玩的(可转换成直角,有效地使其成为填充框算法),但我希望尽可能避免这种情况,因为它会扭曲底层纹理艺术。
"严格合理" ->总比什么都没有好。
这些代码片段提供了一个简单的解决方案,将形状(也包括三角形)一条带一条带地填充到矩形中。
public abstract class Shape {
protected Point offset = new Point();
public abstract int getHeight();
public abstract int getWidth();
}
public class Triangle extends Shape {
// all points are relative to offset (from Shape)
Point top = new Point(); // top.y is always 0, left.y >= 0 right.y >= 0
Point left = new Point(); // left.x < right.x
Point right = new Point();
public int getHeight() {
return left.y >= right.y ? left.y : right.y;
}
public int getWidth() {
int xmin = left.x <= top.x ? left.x : top.x;
int xmax = right.x >= top.x ? right.x : top.x;
return xmax - xmin;
}
}
public class StuffRectangle extends Shape {
private Point ww = new Point();
private ArrayList<Shape> maintained = new ArrayList<Shape>();
private int insx;
private int insy;
private int maxy;
public int getHeight() {
return ww.y;
}
public int getWidth() {
return ww.x;
}
public void clear() {
insx = 0;
insy = 0;
maxy = 0;
maintained.clear();
}
/**
* Fill the rectangle band by band.
*
* The inserted shapes are removed from the provided shape collection.
*
* @param shapes
* the shapes to insert
* @return the count of inserted shapes.
*/
public int stuff(Collection<Shape> shapes) {
int inserted = 0;
for (;;) {
int insertedInPass = 0;
for (Iterator<Shape> i = shapes.iterator(); i.hasNext();) {
Shape shape = i.next();
// does the shape fit into current band?
int sx = shape.getWidth();
if (insx + sx > getWidth())
continue;
int sy = shape.getHeight();
if (insy + sy > getHeight())
continue;
// does fit
++insertedInPass;
// remove from shapes
i.remove();
// add to maintained and adjust offset
maintained.add(shape);
shape.offset.x = insx;
shape.offset.y = insy;
insx += sx;
if (sy > maxy)
maxy = sy;
}
inserted += insertedInPass;
if (shapes.isEmpty())
break;
// nothing fits current band - try a new band
if (insertedInPass == 0) {
// already a new band - does not fit at all
if (insx == 0)
break;
// start new band
insx = 0;
insy += maxy;
maxy = 0;
continue;
}
}
return inserted;
}
}
相关文章:
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 从函数返回任意简单类型的数据
- 如何生成一个随机的 n 位数,其中 n 是任意的
- C++ - 声明指向返回任何类型并获取任意数量参数的函数的指针
- 将正态随机变量与任意 RHO(corrcoef) 相关联
- 在C++中生成任意嵌套的向量
- Frank Luna 在他的书"使用 DirectX12 进行 3D 游戏编程"的介绍中盒子示例的问题
- 任意大小的 constexpr 数组是否可以用作 switch 语句中的案例?
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?
- OpenGL - 在任意轴上平移对象
- 如何绕任意轴旋转点?
- 在 std::vector<无符号字符中存储任意数据的方法>
- 如何在VS2019中获取数组的任意对齐?
- 具有任意数量参数的模板函数
- 从加密项目向量中解密任意选择的元素会导致无效的 PKCS #7 块错误
- 如何在C++中实现节点数任意的通用树数据结构?
- 正在取消线程池中运行的任意作业
- OpenMP 任意缩减(合并)
- 如何在C++中围绕任意值实现我所谓的"wraparound sort"?
- 将任意三角形装入有限的盒子中