gpt4 book ai didi

java - 用于空间分区的四叉树 (Java)

转载 作者:太空宇宙 更新时间:2023-11-04 13:33:59 24 4
gpt4 key购买 nike

我目前正在尝试实现四叉树来划分 map 。我过去一周做了研究,但没有成功。我试图将 map 分成各种矩形,根据人所在的位置,这些矩形将成为 map 的不同区域。我被困住了,因为出于某种原因,我的树无法超过 3 的深度。下面的代码是我的四叉树类。我附加了另外两个类,QuadNode 和 QuadRectangle。 QuadNode 是树中的节点,而 QuadRectangle 是玩家周围区域的矩形。

四叉树:

import java.util.*;

public class QuadTree {


private QuadNode root;
private QuadNode prevNode;
private double[][] points;

private double mapMinX;
private double mapMinY;
private double mapMaxX;
private double mapMaxY;

private int treeDepth;

private List<QuadRectangle> rectangles;

public void insert( double x, double y ){
QuadRectangle value = new QuadRectangle();
value.setPoint(x, y);

if( root == null ){
//System.out.println("Root");
QuadNode node = new QuadNode<>( value );
node.getRect().setLines( mapMinX, mapMinY, mapMaxX, mapMaxY );
root = node;
}
else {
//System.out.println("New Branch");
insertRec(root, value);
}
}

private void insertRec( QuadNode latest, QuadRectangle value ){

// Check to see if point is in NE -- x > x center AND y > y center
if ( latest.getRect().getCenterX() < value.getPointX() && latest.getRect().getCenterY() < value.getPointY() ){

if ( latest.getNE() == null ) {
QuadNode temp = new QuadNode<>(value);
temp.getRect().setLines(latest.getRect().getCenterX(), latest.getRect().getCenterY(), latest.getRect().getMaxX(), latest.getRect().getMaxY());
latest.setNE(temp);
}
else {
insertRec( latest.getNE(), value );
}

}
// Check to see if point is in NW -- x < x center AND y > y center
else if( latest.getRect().getCenterX() > value.getPointX() && latest.getRect().getCenterY() < value.getPointY() ) {

if ( latest.getNW() == null ){
QuadNode temp = new QuadNode<>(value);
temp.getRect().setLines(latest.getRect().getMinX(), latest.getRect().getCenterY(), latest.getRect().getCenterX(), latest.getRect().getMaxY());
latest.setNW(temp);
}
else {
insertRec( latest.getNW(), value );
}
}
// Check to see if point is in SE -- x > x center AND y < y center
else if( latest.getRect().getCenterX() < value.getPointX() && latest.getRect().getCenterY() > value.getPointY() ) {

if ( latest.getSE() == null ){
QuadNode temp = new QuadNode<>(value);
temp.getRect().setLines(latest.getRect().getCenterX(), latest.getRect().getMinY(), latest.getRect().getMaxX(), latest.getRect().getCenterY());
latest.setSE(temp);
}
else {
insertRec( latest.getSE(), value );
}
}
// Check to see if point is in SW -- x < x center AND y < y center
else if( latest.getRect().getCenterX() > value.getPointX() && latest.getRect().getCenterY() > value.getPointY() ) {

if ( latest.getSW() == null ){
QuadNode temp = new QuadNode<>(value);
temp.getRect().setLines(latest.getRect().getMinX(), latest.getRect().getMinY(), latest.getRect().getCenterX(), latest.getRect().getCenterY());
latest.setSW(temp);
}
else {
insertRec( latest.getSW(), value );
}
}
}

public QuadTree( double[][] vals, double minX, double minY, double maxX, double maxY ){

rectangles = new ArrayList<>();

points = vals.clone();

mapMinX = minX;
mapMinY = minY;
mapMaxX = maxX;
mapMaxY = maxY;

//orderPointsCounterClock();

for( int ii = 0; ii < vals[0].length; ii++){
insert(vals[0][ii], vals[1][ii]);
}

treeDepth = getDepth(root);
System.out.println(treeDepth);

addToList(root);



new DrawQuadTree( vals, rectangles ).setVisible(true);

}

private void orderPointsCounterClock(){
double originX = (mapMaxX + mapMinX) / 2;
double originY = (mapMaxY + mapMinY) / 2;

List<double[]> pointsDistance = new ArrayList<>();

boolean distFlag = true;

for( int ii = 0; ii < points[0].length; ii++){
double sqX = Math.pow( originX - points[0][ii], 2);
double sqY = Math.pow( originY - points[1][ii], 2);
double pointToOriginDist = Math.sqrt( sqX + sqY );

for(int jj = ii; jj < points[0].length; jj++){
double tempDist = Math.sqrt( Math.pow( originX - points[0][ii], 2) + Math.pow( originY - points[1][ii], 2) );
if( tempDist > pointToOriginDist ){
distFlag = false;
}
}

if( distFlag ){
pointsDistance.add( new double[]{ points[0][ii], points[1][ii] });
}
}

for( double[] l : pointsDistance ){
System.out.println( l[0] + " :: " + l[1] );
}

}

private int getDepth( QuadNode root ){
if( root == null ){
return 0;
}
else{
List maxValues = new ArrayList<>();

maxValues.add( 1 + getDepth( root.getNE() ));
maxValues.add( 1 + getDepth( root.getNW() ));
maxValues.add( 1 + getDepth( root.getSE() ));
maxValues.add( 1 + getDepth( root.getSW() ));

Collections.sort(maxValues);
return (int)maxValues.get( maxValues.size() - 1 );
}
}

public void addToList( QuadNode root ){
if( root != null ){
prevNode = root;
if( !rectangles.contains( prevNode.getRect() )) {
rectangles.add(prevNode.getRect());
}
addToList( root.getNE() );
addToList( root.getNW() );
addToList( root.getSE() );
addToList( root.getSW() );
}
else{
if( !rectangles.contains( prevNode.getRect() )) {
rectangles.add(prevNode.getRect());
}
}
}
}

四节点:

public class QuadNode<T> {

private QuadRectangle rect;
private QuadNode NE, NW, SE, SW;

public QuadNode( QuadRectangle value ){
this.rect = value;
this.NE = null;
this.NW = null;
this.SE = null;
this.SW = null;
}

public QuadRectangle getRect() {
return rect;
}

public void setNE(QuadNode NE) {
this.NE = NE;
}

public void setNW(QuadNode NW) {
this.NW = NW;
}

public void setSE(QuadNode SE) {
this.SE = SE;
}

public void setSW(QuadNode SW) {
this.SW = SW;
}

public QuadNode getNE() {
return NE;
}

public QuadNode getNW() {
return NW;
}

public QuadNode getSE() {
return SE;
}

public QuadNode getSW() {
return SW;
}
}

四边形:

public class QuadRectangle {
private Point[] line1;
private Point[] line2;
private Point[] line3;
private Point[] line4;

private double pointX;
private double pointY;

private double centerX;
private double centerY;

public void setOnlyPoint(boolean onlyPoint) {
this.onlyPoint = onlyPoint;
}

private double minX;
private double minY;
private double maxX;
private double maxY;

private boolean onlyPoint;


public QuadRectangle(){
line1 = new Point[2];
line2 = new Point[2];
line3 = new Point[2];
line4 = new Point[2];
}

public void setPoint( double x, double y ){
this.pointX = x;
this.pointY = y;
}

public void setLines( double minX, double minY, double maxX, double maxY ){
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;

Point tr = new Point();
tr.setPoint( maxX, maxY );
Point tl = new Point();
tl.setPoint( minX, maxY );
Point bl = new Point();
bl.setPoint( minX, minY );
Point br = new Point();
br.setPoint( maxX, minY );

line1[0] = tl;
line1[1] = tr;
line2[0] = tr;
line2[1] = br;
line3[0] = br;
line3[1] = bl;
line4[0] = bl;
line4[1] = tl;

centerX = (maxX + minX)/2;
centerY = (maxY + minY)/2;
}

public boolean contains( double x, double y ){
Point point = new Point();
point.setPoint(x, y);
if( line1[0].xCord < point.xCord && line1[1].xCord > point.xCord ){
if( this.line2[0].yCord > point.yCord && this.line2[1].yCord < point.yCord ){
return true;
}
else{
return false;
}
}
else{
return false;
}
}

public double getPointX(){
return this.pointX;
}

public double getPointY(){
return this.pointY;
}

public double getCenterX() {
return centerX;
}

public double getCenterY() {
return centerY;
}

public double getMinX() {
return minX;
}

public double getMinY() {
return minY;
}

public double getMaxX() {
return maxX;
}

public double getMaxY() {
return maxY;
}

public Point[] getLine1() {
return line1;
}

public Point[] getLine2() {
return line2;
}

public Point[] getLine3() {
return line3;
}

public Point[] getLine4() {
return line4;
}

对于这里的代码量,我深表歉意。我已经被困了几天了,我不知道该去哪里。

最佳答案

有很多实现。我刚刚创建了一个,你可以看看是否可以澄清你的想法:https://github.com/pvto/java-quadtree/blob/master/src/main/java/struct/quadtree/QuadTree.java .

这个想法是在 QuadNode 中进行所有比较。您可以完全删除 QuadRectangle 并将其替换为两对坐标:(x1,y1)(左上角)和(x2,y2)(右下角)。当您创建 QuadNode 时,您可以立即设置 x1,y1,x2,y2,并且之后不再更改它们。

您可以在该 QuadNode 中仅存储某种类型的一项,也可以像我一样存储一系列项目。如果它创建了子 QuadNode,那么它不应该存储任何项目,反之亦然。

希望这对您有所帮助。

关于java - 用于空间分区的四叉树 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31882829/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com