Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.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
Java 如何将对象插入到四叉树的多个节点中_Java_Data Structures_2d_Game Engine_Quadtree - Fatal编程技术网

Java 如何将对象插入到四叉树的多个节点中

Java 如何将对象插入到四叉树的多个节点中,java,data-structures,2d,game-engine,quadtree,Java,Data Structures,2d,Game Engine,Quadtree,我正在做一个2D游戏,看看我能做些什么。现在我要做的是物体碰撞,我选择使用四叉树。目前的问题是将一个对象插入多个子节点。因此,我遇到的问题是,当我将一个对象插入到树中时,树应该将该对象放入尽可能低的叶节点中。但由于某种原因,我还没有发现至少有一个对象在每个父节点中保留,而它本不应该保留 所以我的问题是,你们能帮我找出并提供解决上述问题的可能方法吗。如果你们认为这个问题无法解决,请提供另一种解决方法 我的代码: package net.evergone.engine; import java.ut

我正在做一个2D游戏,看看我能做些什么。现在我要做的是物体碰撞,我选择使用四叉树。目前的问题是将一个对象插入多个子节点。因此,我遇到的问题是,当我将一个对象插入到树中时,树应该将该对象放入尽可能低的叶节点中。但由于某种原因,我还没有发现至少有一个对象在每个父节点中保留,而它本不应该保留

所以我的问题是,你们能帮我找出并提供解决上述问题的可能方法吗。如果你们认为这个问题无法解决,请提供另一种解决方法

我的代码:

package net.evergone.engine;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;

import net.evergone.EverGone;
import net.evergone.game.BasicRectangle;

public class QuadtreeNode
{
    private int MAX_OBJECTS = 2;
    private int MAX_LEVELS = 6;
    private int level = 0;
    private boolean children = false;
    private static boolean temp = false;
    private BasicRectangle boundBox;
    private ArrayList<BasicRectangle> objects;
    private QuadtreeNode[] nodes;

    /**
     * 
     * Default constructor for QuadtreeNode
     */
    public QuadtreeNode(int level, BasicRectangle boundBox)
    {
        this.level = level;
        this.boundBox = boundBox;
        objects = new ArrayList<BasicRectangle>();
        nodes = new QuadtreeNode[4];
    }

    /**
     * 
     * Splits the parent node into 4 leef nodes
     */
    public void split()
    {
        float parentX = boundBox.getPosition().getX();
        float parentY = boundBox.getPosition().getY();

        nodes[0] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX+boundBox.getWidth()/2, parentY), boundBox.getWidth()/2, boundBox.getHeight()/2));
        nodes[1] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX, parentY), boundBox.getWidth()/2, boundBox.getHeight()/2));
        nodes[2] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX, parentY+boundBox.getHeight()/2), boundBox.getWidth()/2, boundBox.getHeight()/2));
        nodes[3] = new QuadtreeNode(level+1, new BasicRectangle(new Vector2f(parentX+boundBox.getWidth()/2, parentY+boundBox.getHeight()/2), boundBox.getWidth()/2, boundBox.getHeight()/2));
        children  = true;
    }

    public int[] getIndex(BasicRectangle r)//TODO   use intersection methods
    {
        int[] indexs = new int[4];
        int e = 0;
        float verticalMidpoint = boundBox.getPosition().getX() + (boundBox.getWidth() / 2);
        float horizontalMidpoint = boundBox.getPosition().getY() + (boundBox.getHeight() / 2);
        //BasicRectangle can completely fit within the top quadrants
        boolean topQuadrant = (r.getPosition().getY() <= horizontalMidpoint);
        //BasicRectangle can completely fit within the bottom quadrants
        boolean bottomQuadrant = (r.getPosition().getY()+r.getHeight() >= horizontalMidpoint);
        //BasicRectangle can completely fit within the left quadrants
        boolean leftquadrant = (r.getPosition().getX() <= verticalMidpoint);
        //BasicRectangle can completely fit within the right quadrants
        boolean rightQuadrant = (r.getPosition().getX()+r.getWidth() >= verticalMidpoint);
        if(topQuadrant && rightQuadrant)
        {
            indexs[e] = 0;
            e++;
        }
        if(topQuadrant && leftquadrant)
        {
            indexs[e] = 1;
            e++;
        }
        if(bottomQuadrant && leftquadrant)
        {
            indexs[e] = 2;
            e++;
        }
        if(bottomQuadrant && rightQuadrant)
        {
            indexs[e] = 3;
        }
        for(int i =1;i<indexs.length;i++)
            if(indexs[i] == 0)
                indexs[i]=-1;
        return indexs;
    }

    public void insert(BasicRectangle r)//TODO
    {
        if(children)
        {
            int[] indexs = getIndex(r);
            for(int e : indexs)
                if(e != -1)
                    nodes[e].insert(r);
            return;
        }
        objects.add(r);
        if(objects.size()>MAX_OBJECTS && level < MAX_LEVELS)
        {
            if(!children)
                split();
            int i = 0;
            while(i<objects.size())
            {
                int[] indexs = getIndex(objects.get(i));
                for(int e : indexs)
                    if(e != -1)
                        nodes[e].insert(objects.get(i));
                objects.remove(i);
                i++;
            }
        }
        objects.trimToSize();
    }

    /**
     * Return all objects that could collide with the given object
     */
    public void retrieve(List<BasicRectangle> returnObjects, BasicRectangle r)
    {
        if(children)
        {
            int[] indexs = getIndex(r);
            for(int e : indexs)
                if(e != -1)
                    nodes[e].retrieve(returnObjects, r);
            return;
        }
        for(BasicRectangle e : objects)
            if(!returnObjects.contains(e))
                returnObjects.addAll(objects);
        /*if(!temp)
            retrieveHelper(returnObjects);
        temp = true;*/
        while(returnObjects.contains(r))
            returnObjects.remove(r);
    }

    public void retrieveHelper(List<BasicRectangle> returnObjects)
    {
        if(children)
            for(QuadtreeNode e : nodes)
                e.retrieveHelper(returnObjects);
        returnObjects.addAll(objects);
    }

    /**
     * 
     * clears the node
     */
    public void clear()
    {
        objects.clear();
        if(children)
            for(QuadtreeNode e : nodes)
                if(e != null)
                {
                    e.clear();
                    e = null;
                }
        children = false;
        temp = false;
    }

    public BasicRectangle getBoundBox()
    {
        return boundBox;
    }

    /**
     * 
     * Strictly debug only (draw method with be Quadtree.java)
     */
    public void draw()
    {
        if(children)
            for(QuadtreeNode e : nodes)
                e.draw();
        else
            boundBox.drawOutLine();
    }

    public void debugIndex(BasicRectangle r)
    {
        int[] indexs = getIndex(r);
        System.out.println(Arrays.toString(indexs));
        System.out.println("Parent node: "+objects.size());
        for(BasicRectangle e : objects)
            e.setColor(Color.yellow);
        for(int e : indexs)
            if(e != -1)
                System.out.println("node "+e+": "+nodes[e].objects.size());
    }

    public QuadtreeNode[] getNodes()
    {
        return nodes;
    }
}
package net.evergone.engine;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collection;
导入java.util.List;
导入org.lwjgl.util.vector.Vector2f;
导入org.newdawn.slick.Color;
导入net.evergen.evergen;
导入net.evergone.game.BasicRectangle;
公共级四通管
{
私有int MAX_OBJECTS=2;
私有整数最大值=6;
私有整数级=0;
私有布尔子对象=false;
私有静态布尔值temp=false;
私有BasicRectangle边界框;
私有ArrayList对象;
私有四元节点[]节点;
/**
* 
*QuadtreeNode的默认构造函数
*/
公共四叉树节点(整数级,基本矩形边界框)
{
这个水平=水平;
this.boundBox=boundBox;
objects=newarraylist();
节点=新的四元节点[4];
}
/**
* 
*将父节点拆分为4个leef节点
*/
公开作废拆分()
{
float parentX=boundBox.getPosition().getX();
float parentY=boundBox.getPosition().getY();
节点[0]=新的四边形节点(级别+1,新的基本矩形(新的向量2F(parentX+boundBox.getWidth()/2,parentY),boundBox.getWidth()/2,boundBox.getHeight()/2));
节点[1]=新的四边形节点(级别+1,新的基本矩形(新的向量2F(parentX,parentY),boundBox.getWidth()/2,boundBox.getHeight()/2));
节点[2]=新的四边形节点(级别+1,新的基本矩形(新的向量2F(parentX,parentY+boundBox.getHeight()/2),boundBox.getWidth()/2,boundBox.getHeight()/2));
节点[3]=新的四边形节点(级别+1,新的基本矩形(新的向量2F(parentX+boundBox.getWidth()/2,parentY+boundBox.getHeight()/2),boundBox.getWidth()/2,boundBox.getHeight()/2));
儿童=正确;
}
public int[]getIndex(basicrectangler)//TODO使用交集方法
{
int[]indexs=新的int[4];
int e=0;
float verticalMidpoint=boundBox.getPosition().getX()+(boundBox.getWidth()/2);
浮点水平中点=boundBox.getPosition().getY()+(boundBox.getHeight()/2);
//BasicRectangle可以完全适合顶部象限
布尔上象限=(r.getPosition().getY()=水平中点);
//BasicRectangle可以完全适合左象限
布尔左象限=(r.getPosition().getX()=垂直点);
if(顶部象限和右侧象限)
{
指数[e]=0;
e++;
}
if(顶部象限和左侧象限)
{
指数[e]=1;
e++;
}
if(底部象限和左侧象限)
{
指数[e]=2;
e++;
}
if(底部象限和右侧象限)
{
指数[e]=3;
}
对于(int i=1;iMAX_对象和级别<最大级别)
{
如果(!儿童)
split();
int i=0;

而(i在insert方法中,而不是删除对象(objects.remove(i);)时,将i处的对象设置为null(objects.set(i,null);)。

如果需要任何其他信息,请询问。我刚刚发现问题,我必须将i处的对象设置为null,而不是删除它(在insert方法中)。例如:objects.set(i,null);