Example #1
0
 public String getVertexString() {
   String s = null;
   HalfEdge he = he0;
   do {
     if (s == null) {
       s = "" + he.head().index;
     } else {
       s += " " + he.head().index;
     }
     he = he.next;
   } while (he != he0);
   return s;
 }
Example #2
0
  public void computeNormal(Vector3d normal, double minArea) {
    computeNormal(normal);

    if (area < minArea) {
      System.out.println("area=" + area);
      // make the normal more robust by removing
      // components parallel to the longest edge

      HalfEdge hedgeMax = null;
      double lenSqrMax = 0;
      HalfEdge hedge = he0;
      do {
        double lenSqr = hedge.lengthSquared();
        if (lenSqr > lenSqrMax) {
          hedgeMax = hedge;
          lenSqrMax = lenSqr;
        }
        hedge = hedge.next;
      } while (hedge != he0);

      Point3d p2 = hedgeMax.head().pnt;
      Point3d p1 = hedgeMax.tail().pnt;
      double lenMax = Math.sqrt(lenSqrMax);
      double ux = (p2.x - p1.x) / lenMax;
      double uy = (p2.y - p1.y) / lenMax;
      double uz = (p2.z - p1.z) / lenMax;
      double dot = normal.x * ux + normal.y * uy + normal.z * uz;
      normal.x -= dot * ux;
      normal.y -= dot * uy;
      normal.z -= dot * uz;

      normal.normalize();
    }
  }
Example #3
0
 public void getVertexIndices(int[] idxs) {
   HalfEdge he = he0;
   int i = 0;
   do {
     idxs[i++] = he.head().index;
     he = he.next;
   } while (he != he0);
 }
Example #4
0
 public void computeCentroid(Point3d centroid) {
   centroid.setZero();
   HalfEdge he = he0;
   do {
     centroid.add(he.head().pnt);
     he = he.next;
   } while (he != he0);
   centroid.scale(1 / (double) numVerts);
 }
Example #5
0
 /**
  * Finds the half-edge within this face which has tail <code>vt</code> and head <code>vh</code>.
  *
  * @param vt tail point
  * @param vh head point
  * @return the half-edge, or null if none is found.
  */
 public HalfEdge findEdge(Vertex vt, Vertex vh) {
   HalfEdge he = he0;
   do {
     if (he.head() == vh && he.tail() == vt) {
       return he;
     }
     he = he.next;
   } while (he != he0);
   return null;
 }
Example #6
0
  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();
    }
  }
Example #7
0
  private double areaSquared(HalfEdge hedge0, HalfEdge hedge1) {
    // return the squared area of the triangle defined
    // by the half edge hedge0 and the point at the
    // head of hedge1.

    Point3d p0 = hedge0.tail().pnt;
    Point3d p1 = hedge0.head().pnt;
    Point3d p2 = hedge1.head().pnt;

    double dx1 = p1.x - p0.x;
    double dy1 = p1.y - p0.y;
    double dz1 = p1.z - p0.z;

    double dx2 = p2.x - p0.x;
    double dy2 = p2.y - p0.y;
    double dz2 = p2.z - p0.z;

    double x = dy1 * dz2 - dz1 * dy2;
    double y = dz1 * dx2 - dx1 * dz2;
    double z = dx1 * dy2 - dy1 * dx2;

    return x * x + y * y + z * z;
  }
Example #8
0
  public void computeNormal(Vector3d normal) {
    HalfEdge he1 = he0.next;
    HalfEdge he2 = he1.next;

    Point3d p0 = he0.head().pnt;
    Point3d p2 = he1.head().pnt;

    double d2x = p2.x - p0.x;
    double d2y = p2.y - p0.y;
    double d2z = p2.z - p0.z;

    normal.setZero();

    numVerts = 2;

    while (he2 != he0) {
      double d1x = d2x;
      double d1y = d2y;
      double d1z = d2z;

      p2 = he2.head().pnt;
      d2x = p2.x - p0.x;
      d2y = p2.y - p0.y;
      d2z = p2.z - p0.z;

      normal.x += d1y * d2z - d1z * d2y;
      normal.y += d1z * d2x - d1x * d2z;
      normal.z += d1x * d2y - d1y * d2x;

      he1 = he2;
      he2 = he2.next;
      numVerts++;
    }
    area = normal.norm();
    normal.scale(1 / area);
  }
Example #9
0
  void checkConsistency() {
    // do a sanity check on the face
    HalfEdge hedge = he0;
    double maxd = 0;
    int numv = 0;

    if (numVerts < 3) {
      throw new InternalErrorException("degenerate face: " + getVertexString());
    }
    do {
      HalfEdge hedgeOpp = hedge.getOpposite();
      if (hedgeOpp == null) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "unreflected half edge "
                + hedge.getVertexString());
      } else if (hedgeOpp.getOpposite() != hedge) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "opposite half edge "
                + hedgeOpp.getVertexString()
                + " has opposite "
                + hedgeOpp.getOpposite().getVertexString());
      }
      if (hedgeOpp.head() != hedge.tail() || hedge.head() != hedgeOpp.tail()) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "half edge "
                + hedge.getVertexString()
                + " reflected by "
                + hedgeOpp.getVertexString());
      }
      Face oppFace = hedgeOpp.face;
      if (oppFace == null) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "no face on half edge "
                + hedgeOpp.getVertexString());
      } else if (oppFace.mark == DELETED) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "opposite face "
                + oppFace.getVertexString()
                + " not on hull");
      }
      double d = Math.abs(distanceToPlane(hedge.head().pnt));
      if (d > maxd) {
        maxd = d;
      }
      numv++;
      hedge = hedge.next;
    } while (hedge != he0);

    if (numv != numVerts) {
      throw new InternalErrorException(
          "face " + getVertexString() + " numVerts=" + numVerts + " should be " + numv);
    }
  }