Beispiel #1
0
  @Override
  public boolean hit(Hitting hitting) {

    if (waitForReset) { // prevent NPE
      return false;
    }

    if (getGeoElement().getAlphaValue() < EuclidianController.MIN_VISIBLE_ALPHA_VALUE) {
      return false;
    }

    GeoPlane3D plane = (GeoPlane3D) getGeoElement();

    // project hitting origin on plane
    if (hitting.isSphere()) {
      hitting.origin.projectPlane(plane.getCoordSys().getDrawingMatrix(), tmpCoords1, tmpCoords2);
    } else {
      hitting.origin.projectPlaneThruVIfPossible(
          plane.getCoordSys().getDrawingMatrix(), hitting.direction, tmpCoords1, tmpCoords2);
    }

    if (!hitting.isInsideClipping(tmpCoords1)) {
      return false;
    }

    double x = tmpCoords2.getX();
    if (x < plane.getXmin()) {
      return false;
    }
    if (x > plane.getXmax()) {
      return false;
    }

    double y = tmpCoords2.getY();
    if (y < plane.getYmin()) {
      return false;
    }
    if (y > plane.getYmax()) {
      return false;
    }

    if (hitting.isSphere()) {
      double d = tmpCoords1.distance(hitting.origin);
      double scale = getView3D().getScale();
      if (d * scale <= hitting.getThreshold()) {
        setZPick(-d, -d);
        return true;
      }

    } else {
      double parameterOnHitting = tmpCoords2.getZ(); // TODO use other for
      // non-parallel
      // projection :
      // -hitting.origin.distance(project[0]);
      setZPick(parameterOnHitting, parameterOnHitting);
      return true;
    }

    return false;
  }
Beispiel #2
0
  @Override
  public boolean hit(Hitting hitting) {

    if (waitForReset) { // prevent NPE
      return false;
    }

    GeoQuadric3D quadric = (GeoQuadric3D) getGeoElement();

    quadric.resetLastHitParameters();

    if (quadric.getType() == GeoQuadricNDConstants.QUADRIC_NOT_CLASSIFIED) {
      return false;
    }

    if (quadric.getType() == GeoQuadricNDConstants.QUADRIC_SINGLE_POINT) {
      if (DrawPoint3D.hit(
          hitting,
          quadric.getMidpoint3D(),
          this,
          quadric.getLineThickness(),
          project,
          parameters,
          false)) {
        setPickingType(PickingType.POINT_OR_CURVE);
        return true;
      }
      return false;
    }

    if (quadric.getType() == GeoQuadricNDConstants.QUADRIC_LINE) {
      if (drawLine.hit(hitting)) {
        setZPick(drawLine.getZPickNear(), drawLine.getZPickFar());
        setPickingType(PickingType.POINT_OR_CURVE);
        return true;
      }
      return false;
    }

    if (getGeoElement().getAlphaValue() < EuclidianController.MIN_VISIBLE_ALPHA_VALUE) {
      return false;
    }

    if (quadric.getType() == GeoQuadricNDConstants.QUADRIC_PARALLEL_PLANES
        || quadric.getType() == GeoQuadricNDConstants.QUADRIC_INTERSECTING_PLANES) {
      double z1 = Double.NEGATIVE_INFINITY, z2 = Double.NEGATIVE_INFINITY;
      if (drawPlanes[0].hit(hitting, p1, project)) {
        z1 = drawPlanes[0].getZPickNear();
      }
      if (drawPlanes[1].hit(hitting, p2, project)) {
        z2 = drawPlanes[1].getZPickNear();
      }

      int planeIndex = 0;

      // keep highest value (closest to eye)
      if (z1 < z2) {
        z1 = z2;
        planeIndex = 1;
      }

      // if both negative infinity : not hitted
      if (Double.isInfinite(z1)) {
        quadric.resetLastHitParameters();
        return false;
      }

      // project with ortho matrix to get correct parameters
      hitting.origin.projectPlaneThruVIfPossible(
          quadric.getPlanes()[planeIndex].getCoordSys().getMatrixOrthonormal(),
          hitting.direction,
          p1,
          project);

      parameters1[0] = PathNormalizer.inverseInfFunction(project.getX()) + 2 * planeIndex;
      parameters1[1] = project.getY();
      quadric.setLastHitParameters(parameters1);

      // hitted
      setZPick(z1, z1);
      setPickingType(PickingType.SURFACE);
      return true;
    }

    if (quadric.getType() == GeoQuadricNDConstants.QUADRIC_PLANE) {
      if (drawPlanes[0].hit(hitting)) {
        setZPick(drawPlanes[0].getZPickNear(), drawPlanes[0].getZPickFar());
        setPickingType(PickingType.SURFACE);
        return true;
      }
      return false;
    }

    quadric.getProjections(
        null, hitting.origin, hitting.direction, p1, parameters1, p2, parameters2);

    double z1 = Double.NEGATIVE_INFINITY, z2 = Double.NEGATIVE_INFINITY;

    // check first point
    if (hitting.isInsideClipping(p1) && arePossibleParameters(parameters1[0], parameters1[1])) {
      // check distance to hitting line
      p1.projectLine(hitting.origin, hitting.direction, project, parameters);

      double d = p1.distance(project);
      if (d * getView3D().getScale() <= hitting.getThreshold()) {
        z1 = -parameters[0];
      }
    }

    // check second point (if defined)
    if (p2.isDefined()
        && hitting.isInsideClipping(p2)
        && arePossibleParameters(parameters2[0], parameters2[1])) {
      // check distance to hitting line
      p2.projectLine(hitting.origin, hitting.direction, project, parameters);

      double d = p2.distance(project);
      if (d * getView3D().getScale() <= hitting.getThreshold()) {
        z2 = -parameters[0];
      }
    }

    // keep highest value (closest to eye)
    if (z1 < z2) {
      z1 = z2;
      quadric.setLastHitParameters(parameters2);
    } else {
      quadric.setLastHitParameters(parameters1);
    }

    // if both negative infinity : not hitted
    if (Double.isInfinite(z1)) {
      quadric.resetLastHitParameters();
      return false;
    }

    // hitted
    setZPick(z1, z1);
    setPickingType(PickingType.SURFACE);
    return true;
  }
  @Override
  public boolean hit(Hitting hitting) {

    if (waitForReset) { // prevent NPE
      return false;
    }

    if (getGeoElement().getAlphaValue() < EuclidianController.MIN_VISIBLE_ALPHA_VALUE) {
      return false;
    }

    GeoPolygon poly = (GeoPolygon) getGeoElement();

    if (poly.getCoordSys() == null) {
      App.debug("" + poly);
      return false;
    }

    // project hitting origin on polygon plane
    if (globalCoords == null) {
      globalCoords = new Coords(4);
      inPlaneCoords = new Coords(4);
    }

    if (hitting.isSphere()) {
      hitting.origin.projectPlane(poly.getCoordSys().getMatrixOrthonormal(), globalCoords);

      if (hittingPointForOutline == null) {
        hittingPointForOutline = new GeoPoint3D(poly.getConstruction());
        hittingPointForOutline.setWillingCoordsUndefined();
        hittingPointForOutline.setWillingDirectionUndefined();
      }

      // try outline
      hittingPointForOutline.setCoords(globalCoords);
      poly.pointChanged(hittingPointForOutline);
      Coords p3d = hittingPointForOutline.getInhomCoordsInD3();

      if (project == null) {
        project = Coords.createInhomCoorsInD3();
      }

      double d = p3d.distance(hitting.origin);
      double scale = getView3D().getScale();
      if (d * scale <= poly.getLineThickness() + hitting.getThreshold()) {
        setZPick(-d, -d);
        setPickingType(PickingType.POINT_OR_CURVE);
        return true;
      }

      // try inside
      hittingPointForOutline.setCoords(globalCoords);
      hittingPointForOutline.setRegion(poly);
      poly.pointChangedForRegion(hittingPointForOutline);
      p3d = hittingPointForOutline.getInhomCoordsInD3();
      d = p3d.distance(hitting.origin);
      if (d * scale <= hitting.getThreshold()) {
        setZPick(-d, -d);
        setPickingType(PickingType.SURFACE);
        return true;
      }

    } else {
      hitting.origin.projectPlaneThruVIfPossible(
          poly.getCoordSys().getMatrixOrthonormal(),
          hitting.direction,
          globalCoords,
          inPlaneCoords);

      if (!hitting.isInsideClipping(globalCoords)) {
        return false;
      }

      boolean ret = false;

      // check if hitting projection hits the polygon
      if (poly.isInRegion(inPlaneCoords.getX(), inPlaneCoords.getY())) {
        double parameterOnHitting = inPlaneCoords.getZ(); // TODO use
        // other for
        // non-parallel
        // projection
        // :
        // -hitting.origin.distance(project[0]);
        setZPick(parameterOnHitting, parameterOnHitting);
        setPickingType(PickingType.SURFACE);
        ret = true;
      }

      // check if hitting is on path
      if (!poly.wasInitLabelsCalled()) {

        if (hittingPointForOutline == null) {
          hittingPointForOutline = new GeoPoint3D(poly.getConstruction());
        }
        hittingPointForOutline.setCoords(globalCoords);
        poly.pointChanged(hittingPointForOutline);
        Coords p3d = hittingPointForOutline.getInhomCoordsInD3();

        if (hitting.isInsideClipping(p3d)) {
          if (project == null) {
            project = Coords.createInhomCoorsInD3();
          }
          p3d.projectLine(
              hitting.origin,
              hitting.direction,
              project,
              parameters); // check distance to hitting line
          double d = p3d.distance(project);
          double scale = getView3D().getScale();
          if (d * scale <= poly.getLineThickness() + hitting.getThreshold()) {
            double z = -parameters[0];
            double dz = poly.getLineThickness() / scale;
            setZPick(z + dz, z - dz);
            setPickingType(PickingType.POINT_OR_CURVE);
            return true;
          }
        }
      }

      return ret;
    }

    return false;
  }