示例#1
0
  public static boolean addOne(Vertex p) {
    boolean visible = false;

    // mark from p visible faces
    QueueElement<Face> wf = ConvexHull.faces.getFirst();
    while (wf.getNext() != null) {
      Face f = wf.getElem();
      if (volume(f, p) < 0) {
        f.visible = true;
        visible = true;
      }
      wf = wf.getNext();
    }

    // no faces visible, p is inside of hull
    if (!visible) {
      p.onhull = false;
      return false;
    }

    QueueElement<Edge> we = ConvexHull.edges.getFirst();
    while (we.getNext() != null) {
      Edge e = we.getElem();
      if (e.getAdjface(0).visible && e.getAdjface(1).visible) {
        e.deleted = true;
      } else {
        if (e.getAdjface(0).visible || e.getAdjface(1).visible) {
          e.newface = makeStructs(e, p);
        }
      }
      we = we.getNext();
    }

    return true;
  }
示例#2
0
  /**
   * splits the facet incident to h and g into two facets with a new diagonal between the two
   * vertices denoted by h and g respectively. The second (new) facet is a copy of the first facet.
   * Returns h->next() after the operation, i.e., the new diagonal. The new face is to the right of
   * the new diagonal, the old face is to the left. The time is proportional to the distance from h
   * to g around the facet.
   */
  public Halfedge splitFacet(Halfedge h, Halfedge g) {
    if (h == null || g == null) throw new Error("splitFacet: null pointer");
    if (h.face != g.face) throw new Error("splitFacet: different incident facets");
    if (h == g || h.next == g || g.next == h) {
      throw new Error("loops and multiple edges are not allowed");
    }

    Halfedge<X> newDiagonal = new Halfedge<X>();
    Halfedge<X> oppositeNewDiagonal = new Halfedge<X>();
    Face<X> newFace = new Face<X>();

    newFace.halfedge = g;
    newDiagonal.opposite = oppositeNewDiagonal;
    oppositeNewDiagonal.opposite = newDiagonal;
    newDiagonal.face = h.face;
    oppositeNewDiagonal.face = newFace;

    // a completer

    Halfedge p = h.next;
    while (p != g) {
      p.face = newFace;
      p = p.next;
    }

    h.next = newDiagonal;
    g.next = oppositeNewDiagonal;
    return newDiagonal;
  }
示例#3
0
 public void setPoint(final Vector3 point) {
   this.point.set(point);
   for (final Face<?, ?> face : faces) {
     face.markDirty();
   }
   owner.markDirty();
 }
示例#4
0
  public void paint(Graphics gg) {
    int faceSize = Math.min(getWidth() - 4, getHeight() - 4);
    if (face == null)
      face =
          new PADFaceMapped(
              Math.max(2, (getWidth() - faceSize) / 2),
              Math.max(2, (getHeight() - faceSize) / 2),
              faceSize);
    if (buffer == null) {
      im = this.createImage(getWidth(), getHeight());
      buffer = im.getGraphics();
    }
    super.paint(buffer);

    buffer.setColor(new Color(255, 255, 255, 0));
    buffer.fillRect(0, 0, im.getWidth(null), im.getHeight(null));

    face.setDimensions(
        Math.max(2, (getWidth() - faceSize) / 2),
        Math.max(2, (getHeight() - faceSize) / 2),
        faceSize);
    face.paint(buffer);

    // draw buffer to screen
    gg.drawImage(im, 0, 0, null, null);
  }
示例#5
0
    public boolean Set(Face f, Mkv a, Mkv b, Mkv c) {
      Vector3f tmp1 = Stack.alloc(Vector3f.class);
      Vector3f tmp2 = Stack.alloc(Vector3f.class);
      Vector3f tmp3 = Stack.alloc(Vector3f.class);

      Vector3f nrm = Stack.alloc(Vector3f.class);
      tmp1.sub(b.w, a.w);
      tmp2.sub(c.w, a.w);
      nrm.cross(tmp1, tmp2);

      float len = nrm.length();

      tmp1.cross(a.w, b.w);
      tmp2.cross(b.w, c.w);
      tmp3.cross(c.w, a.w);

      boolean valid =
          (tmp1.dot(nrm) >= -EPA_inface_eps)
              && (tmp2.dot(nrm) >= -EPA_inface_eps)
              && (tmp3.dot(nrm) >= -EPA_inface_eps);

      f.v[0] = a;
      f.v[1] = b;
      f.v[2] = c;
      f.mark = 0;
      f.n.scale(1f / (len > 0f ? len : cstInf), nrm);
      f.d = Math.max(0, -f.n.dot(a.w));
      return valid;
    }
示例#6
0
 /**
  * This returns an enumeration of all Darts in Graph G in a canonical order starting with
  * firstDart. The order is canonical in the sense that it only depends on the oriented isomorphism
  * class of G (and firstDart). That is, if there is an oriented iso G <-> G' sending firstDart <->
  * firstDart', then that bijection will send getDarts <-> getDarts'.
  *
  * <p>This enumeration is useful in finding explicit bijections of isomorphic graphs.
  */
 public static Dart[] getDarts(Dart firstDart, Graph G) {
   /**
    * Description of algorithm: Return all the couples around V0=firstDart.V, then all couples
    * around V1, .... The order for couples around firstDart.V is counterclockwise starting with
    * firstDart.F. clockwise around V1,... So we need to order the vertices V0,V1,... and pick the
    * first face to use at each vertex and the rest is determined. Order on V0,... = first
    * encountered. Order on faces at vertex = first encountered.
    */
   distinctFIFO vQueue = new distinctFIFO();
   util.ConditionGetter fQueue = new util.ConditionGetter();
   fQueue.add(firstDart.getF());
   vQueue.put(firstDart.getV());
   Collection coups = new ArrayList();
   int coupsIndex = 0;
   Vertex V;
   while ((V = (Vertex) vQueue.remove()) != null) {
     Face F = (Face) fQueue.get(new incidence(V));
     for (int i = 0; i < V.size(); i++) {
       Face Fx = V.next(F, i);
       coups.add(new Dart(V, Fx));
       vQueue.put(Fx.next(V, 1));
       fQueue.add(Fx);
     }
   }
   return (Dart[]) coups.toArray(new Dart[coups.size()]);
 }
示例#7
0
 public ImmutableList<Face> bake(Function<Node<?>, Matrix4f> animator) {
   ImmutableList.Builder<Face> builder = ImmutableList.builder();
   for (Face f : getFaces()) {
     Vertex v1 = f.getV1().bake(this, animator);
     Vertex v2 = f.getV2().bake(this, animator);
     Vertex v3 = f.getV3().bake(this, animator);
     builder.add(new Face(v1, v2, v3, f.getBrush()));
   }
   return builder.build();
 }
示例#8
0
  /**
   * creates a new triangle facet within the hole incident to h by connecting the tip of h with two
   * new halfedges and a new vertex. Returns the halfedge of the new edge that is incident to the
   * new facet and the new vertex.
   */
  public Halfedge<X> addTriangleToBorder(Halfedge h, X point) {
    if (h.face != null) throw new Error("no border edge");
    System.out.println("adding triangle to " + h);

    Face<X> newFace = new Face<X>();
    Vertex<X> newVertex = new Vertex<X>(point);
    Halfedge<X> hPrev = new Halfedge<X>();
    Halfedge<X> hNext = new Halfedge<X>();
    Halfedge<X> hPrevOpp = new Halfedge<X>();
    Halfedge<X> hNextOpp = new Halfedge<X>();

    // setting the new face
    newFace.setEdge(h);
    // setting hPrev (halfedge preceding h in the new face)
    hPrev.setFace(newFace);
    hPrev.setVertex(h.getOpposite().getVertex());
    hPrev.setPrev(hNext);
    hPrev.setNext(h);
    hPrev.setOpposite(hPrevOpp);
    // setting hNext (halfedge following h in the new face)
    hNext.setFace(newFace);
    hNext.setVertex(newVertex);
    hNext.setPrev(h);
    hNext.setNext(hPrev);
    hNext.setOpposite(hNextOpp);
    // setting hPrevOpp (new boundary halfedge)
    hPrevOpp.setFace(null);
    hPrevOpp.setVertex(newVertex);
    hPrevOpp.setPrev(h.getPrev());
    hPrevOpp.setNext(hNextOpp);
    hPrevOpp.setOpposite(hPrev);
    // setting hNextOpp (the other new boundary halfedge)
    hNextOpp.setFace(null);
    hNextOpp.setVertex(h.getVertex());
    hNextOpp.setPrev(hPrevOpp);
    hNextOpp.setNext(h.getNext());
    hNextOpp.setOpposite(hNext);
    // updating old boundary halfedge informations
    h.setFace(newFace);
    h.setPrev(hPrev);
    h.setNext(hNext);
    // setting newVertex
    newVertex.setEdge(hPrev); // LCA: a controler si c'est hPrev ou hNext

    // adding new facet, vertex and the four halfedges
    this.vertices.add(newVertex);
    this.facets.add(newFace);
    this.halfedges.add(hPrev);
    this.halfedges.add(hNext);
    this.halfedges.add(hPrevOpp);
    this.halfedges.add(hNextOpp);

    return hNext;
  }
示例#9
0
文件: Face.java 项目: tintor/Archive
  public int mergeAdjacentFace(HalfEdge hedgeAdj, Face[] discarded) {
    Face oppFace = hedgeAdj.oppositeFace();
    int numDiscarded = 0;

    discarded[numDiscarded++] = oppFace;
    oppFace.mark = DELETED;

    HalfEdge hedgeOpp = hedgeAdj.getOpposite();

    HalfEdge hedgeAdjPrev = hedgeAdj.prev;
    HalfEdge hedgeAdjNext = hedgeAdj.next;
    HalfEdge hedgeOppPrev = hedgeOpp.prev;
    HalfEdge hedgeOppNext = hedgeOpp.next;

    while (hedgeAdjPrev.oppositeFace() == oppFace) {
      hedgeAdjPrev = hedgeAdjPrev.prev;
      hedgeOppNext = hedgeOppNext.next;
    }

    while (hedgeAdjNext.oppositeFace() == oppFace) {
      hedgeOppPrev = hedgeOppPrev.prev;
      hedgeAdjNext = hedgeAdjNext.next;
    }

    HalfEdge hedge;

    for (hedge = hedgeOppNext; hedge != hedgeOppPrev.next; hedge = hedge.next) {
      hedge.face = this;
    }

    if (hedgeAdj == he0) {
      he0 = hedgeAdjNext;
    }

    // handle the half edges at the head
    Face discardedFace;

    discardedFace = connectHalfEdges(hedgeOppPrev, hedgeAdjNext);
    if (discardedFace != null) {
      discarded[numDiscarded++] = discardedFace;
    }

    // handle the half edges at the tail
    discardedFace = connectHalfEdges(hedgeAdjPrev, hedgeOppNext);
    if (discardedFace != null) {
      discarded[numDiscarded++] = discardedFace;
    }

    computeNormalAndCentroid();
    checkConsistency();

    return numDiscarded;
  }
示例#10
0
  /**
   * This util method will be used to return an instance of Face for the specified value.
   *
   * <p>A null will be return if the specified input is not a valid face value.
   *
   * @param value
   * @return
   */
  public static Face getFace(String value) {

    for (Face face : Face.values()) {

      // ignore case
      if (face.getSymbol().equalsIgnoreCase(value)) {
        return face;
      }
    }

    return null;
  }
示例#11
0
  // ------------------------------------------------------------------------------------------------------------- //
  // The following should probably be moved into a "mesh" operator object that performs the
  // clean operation on a mesh. This way we can have lots of operations, without cluttering up basic
  // mesh functionality.
  // ------------------------------------------------------------------------------------------------------------- //
  public void clean() {
    while (connectAdjacentPaths()) ;

    // Remove any adjacent duplicates from the list, until none are found]
    List<Face> cleanedPolyLines = new ArrayList<Face>();
    for (Face poly : faces) {
      while (removeAdjacentDuplicates(poly)) ;
      if (poly.getVerts().size() > 1) cleanedPolyLines.add(poly);
    }

    faces.clear();
    faces.addAll(cleanedPolyLines);
  }
示例#12
0
  public static Face makeCcw(Face f, Edge e, Vertex p) {
    int i;
    Face invisibleFace;

    if (e.getAdjface(1) == null) {
      invisibleFace = e.getAdjface(0);
    } else {
      if (!e.getAdjface(0).visible) {
        invisibleFace = e.getAdjface(0);
      } else {
        invisibleFace = e.getAdjface(1);
      }
    }

    for (i = 0; invisibleFace.getVertex(i) != e.getEndpt(1); i++) {}

    if (invisibleFace.getVertex((i + 1) % 3) != e.getEndpt(0)) {
      f.setVertex(0, e.getEndpt(1));
      f.setVertex(1, e.getEndpt(0));
    } else {
      f.setVertex(0, e.getEndpt(0));
      f.setVertex(1, e.getEndpt(1));

      swap(f.getEdge(1), f.getEdge(2));
    }

    f.setVertex(2, p);
    return f;
  }
示例#13
0
  public void createCenterVertex(Face<X> f) {
    int degree = f.degree();
    Point_[] neighbors = new Point_[degree];

    Halfedge<X> e = f.getEdge();
    neighbors[0] = e.getVertex().getPoint();
    for (int i = 1; i < degree; i++) {
      e = e.getNext();
      neighbors[i] = e.getVertex().getPoint();
    }
    Point_ centerVertex;
    if (neighbors[0].dimension() == 2) centerVertex = new Point_2();
    else if (neighbors[0].dimension() == 3) centerVertex = new Point_3();
    else throw new Error("error point dimension");
  }
  public void render() {

    if (faces.size() > 0) {

      Tessellator tessellator = Tessellator.instance;

      tessellator.startDrawing(glDrawingMode);

      for (Face face : faces) {
        face.addFaceForRender(tessellator);
      }

      tessellator.draw();
    }
  }
示例#15
0
 //
 // Triangulate a single face
 //
 // After the edges of a triangle have been split,
 // we need to connect the new (odd) vertices so each
 // face is split into four faces. The figure below shows
 // one step of that process by adding an edge connecting
 // vertices v1 and v3. Once this is complete we will
 // update f->e = enew and lather, rinse, repeat.
 // We're done when e = e->next->next->next; this
 // condition also prevents us from triangulating a
 // face that has already been triangulated.
 //
 // Interestingly enough, this routine will triangulate
 // any polygon whether the edges have been split or not.
 //
 //    * : even vertex  (old vertices from before edge splitt
 //    o : odd vertex (created from edge split)
 //    f : original face
 //    e = f->e : edge emanating from even vertex
 //    enew, esym : newly added edge and its symmetric edge
 //    fnew : newly added face
 //
 //                     v2
 //                      *
 //                     / \                      . avoiding
 //                    /   \                     . backslash
 //                e2 /fnew \ e1 = e->next       . as
 //                  / esym  \                   . last
 //              v3 o.........o v1 = e1->v       . character
 //                /   enew    \                 . on
 //           e3  /             \ e = f->e       . line
 //              /       f       \               .
 //             /                 \              .
 //         v4 *---------o---------* v0 = e->v
 //                     v5
 public void triangulate(Face f) {
   Edge e = E.get(f.e);
   Edge e1 = E.get(e.next);
   // check to make sure this face isn't already triangular
   if (e.i != E.get(E.get(e.next).next).next) {
     // done when e == e->next->next->next
     do {
       Edge e2 = E.get(e1.next);
       Edge e3 = E.get(e2.next);
       // Edge = {i, sym, v, f, prev, next}
       Edge enew = new Edge();
       enew.i = E.size();
       Edge esym = new Edge();
       esym.i = enew.i + 1;
       // Face = {i, e}
       Face fnew = new Face();
       fnew.i = F.size();
       fnew.e = e1.i;
       // set up esym
       esym.sym = enew.i;
       esym.v = e3.v;
       esym.f = fnew.i;
       esym.prev = e2.i;
       esym.next = e1.i;
       // set up enew
       enew.sym = esym.i;
       enew.v = e1.v;
       enew.f = f.i;
       enew.prev = e1.prev;
       enew.next = e2.next;
       E.add(enew);
       E.add(esym);
       F.add(fnew);
       // clean up loose ends
       // e1.prev.next, e2.next.prev, e1.prev, e2.next, e1.f, e2.f
       E.get(e1.prev).next = enew.i;
       e3.prev = enew.i;
       e1.prev = esym.i;
       e2.next = esym.i;
       e1.f = fnew.i;
       e2.f = fnew.i;
       f.e = enew.i;
       // set e1 and e2 for next step
       e1 = e3;
       // e2 = E.get(e3.next);
     } while (e.i != E.get(E.get(e.next).next).next);
   }
 }
示例#16
0
  public static Face makeStructs(Edge e, Vertex p) {
    Face new_face = new Face();
    Edge[] new_edge = new Edge[2];

    for (int i = 0; i < 2; i++) {
      if (!(e.getEndpt(i).duplicate == null)) {
        new_edge[i] = Edge.makeEdge(e.getEndpt(i), p);
        e.getEndpt(i).duplicate = new_edge[i];
      }
    }

    new_face = Face.makeFace(e, new_edge[0], new_edge[1]);
    new_face = makeCcw(new_face, e, p);

    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 3; ++j) {

        if (new_edge[i] == null || new_edge[i].getAdjface(j) == null) {
          new_edge[i].setAdjface(j, new_face);
          break;
        }
      }
    }

    return new_face;
  }
示例#17
0
  public Halfedge<X> fillHole(Halfedge h) {
    if (h.face != null) throw new Error("error filling hole: h not boundary edge");

    Face<X> newFace = new Face<X>();
    this.facets.add(newFace);
    newFace.setEdge(h);

    Halfedge p = h.next;
    h.face = newFace;
    int cont = 1;
    while (p != h) {
      p.face = newFace;
      p = p.next;
    }
    return h;
  }
示例#18
0
文件: Face.java 项目: Genxl/xlweixin
 // 根据人脸中心点坐标从左至右排序
 public int compareTo(Face face) {
   // TODO Auto-generated method stub
   int result = 0;
   if (this.getCenterX() > face.getCenterX()) result = 1;
   else result = -1;
   return result;
 }
示例#19
0
 public void Detach(Face face) {
   if (face.prev != null || face.next != null) {
     --nfaces;
     if (face == root) {
       root = face.next;
       root.prev = null;
     } else {
       if (face.next == null) {
         face.prev.next = null;
       } else {
         face.prev.next = face.next;
         face.next.prev = face.prev;
       }
     }
     face.prev = face.next = null;
   }
 }
示例#20
0
 public String facesToString() {
   String result = "List of faces\n";
   Iterator it = this.facets.iterator();
   int cont = 0;
   while (it.hasNext()) {
     Face<X> f = (Face<X>) it.next();
     result = result + "f" + cont + " ";
     Halfedge<X> e = f.getEdge();
     while (e.getNext() != f.getEdge()) {
       result = result + vertices.indexOf(e.getVertex()) + " ";
       e = e.getNext();
     }
     result = result + vertices.indexOf(e.getVertex()) + "\n";
     cont++;
   }
   return result;
 }
示例#21
0
 public void showState(int mousex, int mousey) {
   p = ((double) mousex - (double) getWidth() / (double) 2) / ((double) (getWidth() + 1) / 2.0);
   d = -((double) mousey - (double) getHeight() / (double) 2) / ((double) (getHeight() + 1) / 2.0);
   setXY(p, d);
   face.setEmotion(p, a, d, mousex, mousey);
   paint();
   this.getGraphics().drawLine(mousex - 3, mousey, mousex + 3, mousey);
   this.getGraphics().drawLine(mousex, mousey - 3, mousex, mousey + 3);
 }
示例#22
0
 public void addTexture(Face face, Bitmap bitmap, String id) {
   if (face == Face.All) {
     for (int i = 0; i < 6; i++) {
       faces[i].textures().addById(id);
     }
   } else {
     faces[face.ordinal()].textures().addById(id);
   }
 }
示例#23
0
  public static void buildTetrahedron() {
    QueueElement<Vertex> v0;
    QueueElement<Vertex> v3;

    int volume;

    // find 3 noncollinear points
    v0 = ConvexHull.vertices.getFirst();
    while (collinear(v0.getElem(), v0.getNext().getElem(), v0.getNext().getNext().getElem())) {
      v0 = v0.getNext();
      if (v0.getNext() == ConvexHull.vertices.getFirst()) {
        System.err.println("All points are collinear");
        System.exit(0);
      }
    }

    // mark vertices as processed
    v0.getElem().setMark(true);
    v0.getNext().getElem().setMark(true);
    v0.getNext().getNext().getElem().setMark(true);

    Edge e0 = Edge.makeEdge(v0.getElem(), v0.getNext().getElem());
    Edge e1 = Edge.makeEdge(v0.getNext().getElem(), v0.getNext().getNext().getElem());
    Edge e2 = Edge.makeEdge(v0.getNext().getNext().getElem(), v0.getElem());

    Face f = Face.makeFace(e0, e1, e2);
    f.setVertices(v0.getElem(), v0.getNext().getElem(), v0.getNext().getNext().getElem());

    e0.setAdjface(0, f);
    e1.setAdjface(0, f);
    e1.setAdjface(0, f);

    // try to find another noncollinear vertex
    v3 = v0.getNext().getNext().getNext();
    volume = volume(f, v3.getElem());

    while (volume == 0) {
      v3 = v3.getNext();
      if (v3 == ConvexHull.vertices.getFirst()) {
        System.err.println("All points are coplanar");
        System.exit(0);
      }
      volume = volume(f, v3.getElem());
    }
    v3.getElem().setMark(true);

    // store vertices in ccw order
    if (volume < 0) {
      swap(f.getVertex(1), f.getVertex(2));
      swap(f.getEdge(1), f.getEdge(2));
    }

    e0.setAdjface(1, makeStructs(e0, v3.getElem()));
    e1.setAdjface(1, makeStructs(e1, v3.getElem()));
    e2.setAdjface(1, makeStructs(e2, v3.getElem()));

    Cleaning.cleanUp();
  }
示例#24
0
  private void combinePaths(Face dest, Face src, FindResults how) {
    if (how.flip) src.flip();

    // Add them forwards
    int addAt = 0;
    for (Vertex v : src.verts) {
      if (how.before) dest.verts.add(addAt++, v);
      else dest.verts.add(v);
    }
  }
示例#25
0
文件: Face.java 项目: tintor/Archive
  /**
   * Constructs a triangule Face from vertices v0, v1, and v2.
   *
   * @param v0 first vertex
   * @param v1 second vertex
   * @param v2 third vertex
   */
  public static Face createTriangle(Vertex v0, Vertex v1, Vertex v2, double minArea) {
    Face face = new Face();
    HalfEdge he0 = new HalfEdge(v0, face);
    HalfEdge he1 = new HalfEdge(v1, face);
    HalfEdge he2 = new HalfEdge(v2, face);

    he0.prev = he2;
    he0.next = he1;
    he1.prev = he0;
    he1.next = he2;
    he2.prev = he1;
    he2.next = he0;

    face.he0 = he0;

    // compute the normal and offset
    face.computeNormalAndCentroid(minArea);
    return face;
  }
示例#26
0
 public void mouseMoved(MouseEvent e) {
   if (isEnabled()) {
     setXY(
         ((double) e.getX() - (double) getWidth() / (double) 2)
             / ((double) (getWidth() + 1) / 2.0),
         -((double) e.getY() - (double) getHeight() / (double) 2)
             / ((double) (getHeight() + 1) / 2.0));
     face.setEmotion(p, a, d, e.getX(), e.getY());
   }
   paint();
 }
示例#27
0
文件: Face.java 项目: tintor/Archive
  public static Face create(Vertex[] vtxArray, int[] indices) {
    Face face = new Face();
    HalfEdge hePrev = null;
    for (int i = 0; i < indices.length; i++) {
      HalfEdge he = new HalfEdge(vtxArray[indices[i]], face);
      if (hePrev != null) {
        he.setPrev(hePrev);
        hePrev.setNext(he);
      } else {
        face.he0 = he;
      }
      hePrev = he;
    }
    face.he0.setPrev(hePrev);
    hePrev.setNext(face.he0);

    // compute the normal and offset
    face.computeNormalAndCentroid();
    return face;
  }
示例#28
0
 public void testDart() {
   String S = Formatter.testString; // see formatterString.gif
   Graph G = Graph.getInstance(new Formatter(S));
   Vertex V = null;
   int coupleCount = 0;
   for (Enumeration E = G.vertexEnumeration(); E.hasMoreElements(); /*--*/ ) {
     Vertex W = (Vertex) E.nextElement();
     coupleCount += W.size();
     if (W.size() == 3) V = W;
   }
   jassert(V.size() == 3);
   Face F = V.getAny();
   while (F.size() != 5) F = V.next(F, 1);
   jassert(F.size() == 5);
   Dart C = new Dart(V, F);
   Dart[] list = Dart.getDarts(C, G);
   // compute the expected number of return values;
   jassert(list.length == coupleCount);
   jassert(list[0].getV() == C.getV());
   jassert(list[0].getF() == C.getF());
   // check integrity of each couple.
   for (int i = 0; i < list.length; i++) {
     V = list[i].getV();
     F = list[i].getF();
     jassert(V.next(F, 0) == F);
     jassert(F.next(V, 0) == V);
   }
   // check that all couples are distinct.
   Hashtable table = new Hashtable(); // { V-> set of F }
   for (Enumeration E = G.vertexEnumeration(); E.hasMoreElements(); /*--*/ ) {
     V = (Vertex) E.nextElement();
     table.put(V, new HashSet());
   }
   for (int i = 0; i < list.length; i++) {
     V = list[i].getV();
     F = list[i].getF();
     HashSet H = (HashSet) table.get(V);
     jassert(!H.contains(F));
     H.add(F);
   }
 }
示例#29
0
  private static int volume(Face f, Vertex p) {
    double ax = f.getVertex(0).getCoordinate(0) - p.getCoordinate(0);
    double ay = f.getVertex(0).getCoordinate(1) - p.getCoordinate(1);
    double az = f.getVertex(0).getCoordinate(2) - p.getCoordinate(2);
    double bx = f.getVertex(1).getCoordinate(0) - p.getCoordinate(0);
    double by = f.getVertex(1).getCoordinate(1) - p.getCoordinate(1);
    double bz = f.getVertex(1).getCoordinate(2) - p.getCoordinate(2);
    double cx = f.getVertex(2).getCoordinate(0) - p.getCoordinate(0);
    double cy = f.getVertex(2).getCoordinate(1) - p.getCoordinate(1);
    double cz = f.getVertex(2).getCoordinate(2) - p.getCoordinate(2);

    double volume = ax * (by * cz - bz * cy) + ay * (bz * cx - bx * cz) + az * (bx * cy - by * cx);

    if (volume > 0.5) {
      return 1;
    } else if (volume < -0.5) {
      return -1;
    } else {
      return 0;
    }
  }
示例#30
0
文件: Face.java 项目: tintor/Archive
  public void triangulate(FaceList newFaces, double minArea) {
    HalfEdge hedge;

    if (numVertices() < 4) {
      return;
    }

    Vertex v0 = he0.head();
    Face prevFace = null;

    hedge = he0.next;
    HalfEdge oppPrev = hedge.opposite;
    Face face0 = null;

    for (hedge = hedge.next; hedge != he0.prev; hedge = hedge.next) {
      Face face = createTriangle(v0, hedge.prev.head(), hedge.head(), minArea);
      face.he0.next.setOpposite(oppPrev);
      face.he0.prev.setOpposite(hedge.opposite);
      oppPrev = face.he0;
      newFaces.add(face);
      if (face0 == null) {
        face0 = face;
      }
    }
    hedge = new HalfEdge(he0.prev.prev.head(), this);
    hedge.setOpposite(oppPrev);

    hedge.prev = he0;
    hedge.prev.next = hedge;

    hedge.next = he0.prev;
    hedge.next.prev = hedge;

    computeNormalAndCentroid(minArea);
    checkConsistency();

    for (Face face = face0; face != null; face = face.next) {
      face.checkConsistency();
    }
  }