Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将任意三角形打包到有限盒中?_C++_Algorithm_Opengl_Optimization - Fatal编程技术网

C++ 将任意三角形打包到有限盒中?

C++ 将任意三角形打包到有限盒中?,c++,algorithm,opengl,optimization,C++,Algorithm,Opengl,Optimization,作为3D优化的一部分,我需要将三角形尽可能紧密地打包到一个盒子中(我正在使用不同纹理的片段将alpha填充到一个不同的纹理中,用于深度排序,这样纹理就不会随着每个新的三角形而切换) 有这样做的算法吗?三角形本身可以制作成可编程的(可转换成直角,有效地使其成为一种装箱算法),但如果可能的话,我想避免这种情况,因为它会扭曲底层的纹理艺术。“尽可能紧密”->有效果总比没有好 这些代码片段提供了一个简单的解决方案,可以将形状(也包括三角形)逐条填充到矩形中 public abstract class S

作为3D优化的一部分,我需要将三角形尽可能紧密地打包到一个盒子中(我正在使用不同纹理的片段将alpha填充到一个不同的纹理中,用于深度排序,这样纹理就不会随着每个新的三角形而切换)

有这样做的算法吗?三角形本身可以制作成可编程的(可转换成直角,有效地使其成为一种装箱算法),但如果可能的话,我想避免这种情况,因为它会扭曲底层的纹理艺术。

“尽可能紧密”->有效果总比没有好

这些代码片段提供了一个简单的解决方案,可以将形状(也包括三角形)逐条填充到矩形中

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;
    }
}
公共抽象类形状{
保护点偏移=新点();
公共抽象int getHeight();
公共抽象int getWidth();
}
公共类三角形扩展形状{
//所有点都相对于偏移(从形状)
Point top=new Point();//top.y始终为0,left.y>=0 right.y>=0
点左=新点();//左.x<右.x
右点=新点();
公共整数getHeight(){
返回left.y>=right.y?left.y:right.y;
}
公共int getWidth(){
intxmin=left.x=top.x?right.x:top.x;
返回xmax-xmin;
}
}
公共类StuffRectangle扩展形状{
专用点ww=新点();
private ArrayList Maintened=新建ArrayList();
私人综合督察;
私家侦探;
私有int-maxy;
公共整数getHeight(){
返回ww.y;
}
公共int getWidth(){
返回ww.x;
}
公共空间清除(){
insx=0;
insy=0;
maxy=0;
保持。清除();
}
/**
*一条一条地填充矩形。
* 
*插入的形状将从提供的形状集合中删除。
* 
*@param形状
*要插入的形状
*@返回插入形状的计数。
*/
公共整数填充(集合形状){
插入的int=0;
对于(;;){
int insertedInPass=0;
for(迭代器i=shapes.Iterator();i.hasNext();){
Shape=i.next();
//这个形状适合当前的波段吗?
int sx=shape.getWidth();
如果(insx+sx>getWidth())
继续;
int sy=shape.getHeight();
如果(insy+sy>getHeight())
继续;
//合身
++插入通路;
//从形状中删除
i、 删除();
//添加到“已维护”并调整偏移
保持。添加(形状);
形状偏移量x=insx;
形状.偏移量.y=insy;
insx+=sx;
如果(sy>maxy)
maxy=sy;
}
插入+=插入过程;
if(shapes.isEmpty())
打破
//没有任何东西适合当前乐队-尝试新乐队
if(insertedInPass==0){
//已经有了一个新乐队-根本不适合
如果(insx==0)
打破
//开始新乐队
insx=0;
insy+=maxy;
maxy=0;
继续;
}
}
返回插入;
}
}

有趣的问题。三角形的反射和任意旋转是允许的吗?嗯,有32种(不是16种)方法将2个三角形A和B组合在一起,以避免延伸A的边界框的4条边中的1条:B w.r.t.A的4个90度旋转,以及以下8种“布局”:A到B的{左,右}及其{上,下}大多数点对齐;A{上方,下方}B,其{左,右}最点对齐。但我认为仅仅考虑这些问题是不够的——通过将B放在一些“中间”位置,可能会得到更小的整体边界框……(我恐怕没有一个我打算给出的“完整”答案,但奥托请忽略这些接近票数的问题——这些天几乎每一个问题都会出现这些票数,可能是因为它们只能被选为“向上”。这是一个非常有趣的问题,最好保持开放状态:)我很确定这个问题是NP完全问题。通过快速搜索,我发现它描述了一种将三角形打包成正方形的启发式算法,但我认为您无法找到完美的多项式时间解决方案。为了澄清一下,
box
在这种情况下是三维(长方体)还是二维(正方形/矩形)?我习惯于在2D中使用启发式方法将三角形或四边形打包到纹理坐标UV空间中,但不是在3D中操作的。