java堆栈合成分解,java - 我如何改善分离良好的对分解的实现 - 堆栈内存溢出

我试图实现3D分离良好的对分解的算法WSPD使用八叉树 。

首先,我首先实现以下类的OctreeNode

public class OctreeNode {

public static final int BSW = 0;

public static final int BSE = 1;

public static final int BNW = 2;

public static final int BNE = 3;

public static final int ASW = 4;

public static final int ASE = 5;

public static final int ANW = 6;

public static final int ANE = 7;

public int level = 0; // level set to 0.

public OctreeNode[] children = null;

public OctreeNode father = null; // father is null

public Point_3 p = null; //point stored in a leaf

public Point_3 center = null; // point to define the center of the box of the node.

public double height = 0.0, width = 0.0, depth = 0.0;

每个非叶节点都有8个子节点。 我为该类实现了一个构造函数,该构造函数采用3D点列表。

/**

* Create the octree for storing an input point cloud.

*/

public OctreeNode(List points) {

// We construct the octree only for non empty point cloud.

assert(points.size() > 0);

/**

* We start by computing a box containing the point cloud.

*/

// The minimum value of x,y,z in the point cloud.

double minX = points.get(0).getX().doubleValue();

double minY = points.get(0).getY().doubleValue();

double minZ = points.get(0).getZ().doubleValue();

// The maximum value of x,y,z in the point cloud.

double maxX = points.get(0).getX().doubleValue();

double maxY = points.get(0).getY().doubleValue();

double maxZ = points.get(0).getZ().doubleValue();

for(Point_3 point : points) {

// update the minimum.

if(minX > point.getX().doubleValue()) {

minX = point.getX().doubleValue();

}

// update the minimum.

if(minY > point.getY().doubleValue()) {

minY = point.getY().doubleValue();

}

// update the minimum.

if(minZ > point.getZ().doubleValue()) {

minZ = point.getZ().doubleValue();

}

// update the maximum.

if(maxX < point.getX().doubleValue()) {

maxX = point.getX().doubleValue();

}

// update the maximum.

if(maxY < point.getY().doubleValue()) {

maxY = point.getY().doubleValue();

}

// update the maximum.

if(maxZ < point.getZ().doubleValue()) {

maxZ = point.getZ().doubleValue();

}

}

this.center = new Point_3((minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2);

this.width = 0.75*(maxX - minX);

this.height = 0.75*(maxY - minY);

this.depth = 0.75*(maxZ - minZ);

for(Point_3 point : points) {

this.add(point);

}

}

之后,我实现班级的添加功能

/**

* @return true if the current node is a leaf.

*/

public boolean isLeaf() {

return (this.children == null);

}

/**

* @return true if the current node is empty.

*/

public boolean isEmpty() {

return (this.children == null && this.p == null);

}

/**

* @return true if the current node is single point.

*/

public boolean isSinglePoint() {

return (this.children == null && this.p != null);

}

/**

* @param o an Object.

* @return true if the current node is equals to o

*/

@Override

public boolean equals(Object o) {

OctreeNode n = (OctreeNode) o;

return (n != null) && (this.center.equals(n.center));

}

/**

* @return the diameter of the node : 0 if is empty or single point and the diameter of the box otherwise.

*/

public double diam() {

if(this.isLeaf()) {

return 0.0;

}

return 2*Math.sqrt(this.width*this.width

+ this.height*this.height

+ this.depth*this.depth);

}

/**

* Check if the point is in the boundary of the OctreeNode

* @param p a Point_3.

* @return true if p is in the cube of the OctreeNode

*/

public boolean inBoundary(Point_3 p) {

Vector_3 v = (Vector_3) this.center.minus(p);

return (Math.abs(v.getX().doubleValue()) <= this.width && Math.abs(v.getY().doubleValue()) <= this.height && Math.abs(v.getZ().doubleValue()) <= this.depth);

}

/**

* Add a node into the OctreeNode

*/

public void add(Point_3 p) {

assert(this.center != null);

if(!this.inBoundary(p))

return;

// Check if the current node is a leaf.

if(this.isLeaf()) {

// Check if the current node is empty.

if(this.isEmpty()) {

this.p = p;

return;

}

else {

// Check if the node contains the same point already.

if(this.p.equals(p)) {

return;

}

// The current node contains only one point and the new point

// is different from the point of the current OctreeNode.

// We create the set of children for the current OctreeNode.

this.children = new OctreeNode[8];

// Initialize the children.

for(int i = 0; i < 8; i++) {

this.children[i] = new OctreeNode();

}

// For all children we put the current OctreeNode as father and

// we increment the level.

for(OctreeNode child : this.children) {

child.father = this;

child.level = this.level + 1;

}

// We compute then the center points for every child

Vector_3 vi = new Vector_3(this.width / 2, 0.0, 0.0);

Vector_3 vj = new Vector_3(0.0, this.height / 2, 0.0);

Vector_3 vk = new Vector_3(0.0, 0.0, this.depth / 2);

this.children[BSW].center = this.center.sum(vk.opposite()).sum(vj.opposite()).sum(vi.opposite());

this.children[BSE].center = this.center.sum(vk.opposite()).sum(vj.opposite()).sum(vi);

this.children[BNW].center = this.center.sum(vk.opposite()).sum(vj).sum(vi.opposite());

this.children[BNE].center = this.center.sum(vk.opposite()).sum(vj).sum(vi);

this.children[ASW].center = this.center.sum(vk).sum(vj.opposite()).sum(vi.opposite());

this.children[ASE].center = this.center.sum(vk).sum(vj.opposite()).sum(vi);

this.children[ANW].center = this.center.sum(vk).sum(vj).sum(vi.opposite());

this.children[ANE].center = this.center.sum(vk).sum(vj).sum(vi);

// We put half of the dimensions of the cube for every child.

for(OctreeNode child : children) {

child.width = this.width / 2;

child.depth = this.depth / 2;

child.height = this.height / 2;

}

// Look for the child to add the point of the current OctreeNode.

for(OctreeNode child : children) {

if(child.inBoundary(this.p)) {

child.add(this.p);

break;

}

}

// Look for the child to add the point p.

for(OctreeNode child : children) {

if(child.inBoundary(p)) {

child.add(p);

break;

}

}

// this.p = null;

}

}

else {

// Look for the child to add the point p.

for(OctreeNode child : children) {

if(child.inBoundary(p)) {

child.add(p);

break;

}

}

}

}

我还实现了一个函数距离,以计算Octree中两个节点之间的距离,即节点两个框之间的距离。

/**

* @param o an OctreeNode.

* @param u an OctreeNode.

* @return the distance between the two nodes.

*/

public static double distance(OctreeNode o, OctreeNode u) {

if(o == null || o.isEmpty() || u == null || u.isEmpty()) {

return 0.0;

}

if(u.isLeaf() && o.isLeaf()) {

return u.p.distanceFrom(o.p).doubleValue();

}

double x = 0.0;

double y = 0.0;

double z = 0.0;

Vector_3 v;

if(u.isLeaf()) {

v = (Vector_3) u.p.minus(o.center);

x = Math.min(Math.abs(v.getX().doubleValue()) - o.width, 0.0);

y = Math.min(Math.abs(v.getX().doubleValue()) - o.height, 0.0);

z = Math.min(Math.abs(v.getX().doubleValue()) - o.depth, 0.0);

return Math.sqrt(x*x + y*y + z*z);

}

if(o.isLeaf()) {

return distance(u, o);

}

v = (Vector_3) u.center.minus(o.center);

x = Math.min(Math.abs(v.getX().doubleValue()) - o.width - u.width, 0.0);

y = Math.min(Math.abs(v.getX().doubleValue()) - o.height - u.height, 0.0);

z = Math.min(Math.abs(v.getX().doubleValue()) - o.depth - u.depth, 0.0);

return Math.sqrt(x*x + y*y + z*z);

}

}

现在,我实现“ Octree表示”和“ Octree”类

public class Octree {

public OctreeNode root;

/**

* Create an octree from the array points.

*/

public Octree(Point_3[] points){

/**

* We use the constructor provided by the class OctreeNode to

* construct the root.

*/

this.root = new OctreeNode(Arrays.asList(points));

}

}

在这里我有一个问题。 您是否认为实施是最好的方法?

在这部分之后,我实现了分离良好的对分解类

public class WellSeparatedPairDecomposition {

class Pair {

X x; Y y;

Pair(X xx, Y yy) {

x = xx;

y = yy;

}

public X getFirst() {

return x;

}

public Y getSecond() {

return y;

}

@Override

public boolean equals(Object o) {

Pair p = (Pair) o;

return (p!=null && p.getFirst() == x && p.getSecond() == y);

}

}

/**

* Compute the WSPD from an octree and a threshold s.

* @param T the Octree,

* @param s threshold.

* @return the pairs of WSPD.

*/

public OctreeNode[][] wspd (Octree T, double epsilon) {

Set> H = new HashSet>();

wspd(T.root, T.root, epsilon, H);

int n = H.size();

OctreeNode[][] result = new OctreeNode[n][2];

int i = 0;

for(Pair pair : H) {

result[i][0] = pair.getFirst();

result[i][1] = pair.getSecond();

i++;

}

return result;

}

boolean isWS(OctreeNode u, OctreeNode v, double epsilon) {

if(u == null || v == null || u.isEmpty() || v.isEmpty()) {

return false;

}

double distance = OctreeNode.distance(u, v);

return (u.diam() < epsilon*distance && v.diam() < epsilon*distance);

}

void wspd(OctreeNode u, OctreeNode v, double epsilon, Set> H) {

if(u.isEmpty() || v.isEmpty() || (v.isLeaf() && u.isLeaf() && v.equals(u)))

return;

if(isWS(u, v, epsilon)) {

H.add(new Pair(u, v));

return;

}

if(u.level > v.level) {

OctreeNode temp = u;

u = v;

v = temp;

}

if(!u.isLeaf()) {

for(OctreeNode uchild : u.children) {

wspd(uchild, v, epsilon, H);

}

}

}

}

我的实现是对算法的准确描述。 但是,当我测试时它非常慢。 我如何改善这种实现?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值