Java: efficient collection concept for conjugate objects

I am missing some collection function for a specific problem.

I would like to start with a few details about the problem - maybe there is a more elegant way to solve it, which does not end with the specific problem I'm stuck with:

I am modeling a volumetric grid of tetrahedral cells (the 2D analogue will be a triangular grid). Two tetrahedra are considered adjacent if they share one triangular face (which occupies three vertices). My application should be able to move from cell to cell through their normal face.

To satisfy some other requirements, I had to divide the faces into two so-called semifinals, which have the same vertices, but belong to different cells and have the opposite orientation.

The application should be able to make calls like this (where it Facemodels half the face):

Cell getAdjacentCell(Cell cell, int faceIndex) {
    Face face = cell.getFace(faceIndex);
    Face partnerFace = face.getPartner();
    if (partnerFace == null) return null; // no adjacent cell present
    Cell adjacentCell = partnerFace.getCell();
    return adjacentCell;
}

The implementation of the method getPartner()is the method in question. My approach is this:

Face-objects can create some kind of immutable object Signaturecontaining only the vertex configuration, orientation (clockwise (cw) or counterclockwise (ccw)) and a backward link to the original Face-object. Face.Signature objects are considered equal ( @Override equals()) if they occupy the same three vertices - regardless of their orientation and the cell associated with them.

I created two sets in Mesh-objects to contain all semigroups grouped by their orientation:

Set<Face.Signature> faceSignatureCcw = new HashSet<Face.Signature>();
Set<Face.Signature> faceSignatureCw = new HashSet<Face.Signature>();

Now I can determine if a partner exists ...

class Face {
    public Face getPartner() {
        if (this.getSignature().isCcw()) {
            boolean partnerExists = this.getMesh().faceSignatureCw.contains(this);
        } else {
            boolean partnerExists = this.getMesh().faceSignatureCcw.contains(this);
        }
    }
}

... Set , ! , , .equals().

( )

Collection, :

  • Face -Object ( , , )
  • Face -Object, .equals(),

( ) :

class PartnerCollection {
    List<Face.Signature> faceSignatureCcw = new ArrayList<Face.Signature>();
    List<Face.Signature> faceSignatureCw = new ArrayList<Face.Signature>();

    void add(Face.Signature faceSignature) {
        (faceSignature.isCcw() ? faceSignatureCw : faceSignatureCcw).add(faceSignature);
    }

    Face.Signature getPartner(Face.Signature faceSignature) {
        List<Face.Signature> partnerList = faceSignature.isCcw() ? faceSignatureCw : faceSignatureCcw;
        for (Face.Signature partnerSignature : partnerList) {
            if (faceSignature.equals(partnerSignature)) return partnerSignature;
        }
        return null;
    }
}

: Face -Objects . , - .

, :) , - .

+5
4

- Map<Face.Signature, Face.Signature>?
?

. .

+3

, , -, -. , , ? :

    List<Face.Signature> partnerList = faceSignature.isCcw() ? faceSignatureCw : faceSignatureCcw;
    int idx = partnerList.indexOf(faceSignature);
    if(idx == -1)
       return null;
    return partnerList.get(idx);

, Lists , , , new ArrayList(100000) .

, , , .

EDIT: , Octuply Linked List, , ().

0

, . , , , , ? , jGraphT

0

? ,

public class Face
{
    Face partner;
    //whatever else
}

The design is a Face.Signaturelittle hairy and really not needed. If each person has a partner (or Faceobjects can have a partner enough , it makes sense to think that there is a connection between the Facepartner Face), the connection should simply be an instance variable. If you can use this approach, it should greatly simplify your code. If not, return the reason this will not work for you so that I can continue to try to help.

0
source

All Articles