Exemplo n.º 1
0
void SampleSlice::compute() {
  // Allocate space
  resize((steps[0] + 2) * (steps[1] + 2), -std::numeric_limits<real>::max());

  // Compute offsets
  const Vector2R &rmin = bbox.getMin();
  Vector2R scale = Vector2R(bbox.getWidth() / steps.x(),
                            bbox.getLength() / steps.y());
  Vector3R p = Vector3R(0, 0, z);

  // TODO Culling?

  // Sample
  //real *array = (*this)[0];
  for (unsigned y = 0; y < steps.y() + 2; y++) {
    p.y() = rmin.y() + y * scale.y();

    for (unsigned x = 0; x < steps.x() + 2; x++) {
      p.x() = rmin.x() + x * scale.x();

      // TODO func.getSample() was removed
      //*array++ = func.getSample(p);
    }
  }
}
Exemplo n.º 2
0
bool ConicSweep::contains(const Vector3R &start, const Vector3R &end,
                          const Vector3R &p) const {
  real x1 = start.x();
  real y1 = start.y();
  real z1 = start.z();

  real x2 = end.x();
  real y2 = end.y();
  real z2 = end.z();

  real x = p.x();
  real y = p.y();
  real z = p.z();

  // Z height range
  real minZ = z1 < z2 ? z1 : z2;
  real maxZ = z1 < z2 ? z2 : z1;
  if (z < minZ || maxZ + length < z) return false;

  real xLen = x2 - x1;
  real yLen = y2 - y1;
  real zLen = z2 - z1;

  bool horizontal = z1 == z2;
  bool vertical = x1 == x2 && y1 == y2;
  bool conical = radius1 != radius2;

  Vector2R q(x, y);
  Vector2R p1(x1, y1);
  Vector2R p2(x2, y2);

  real conicSlope = conical ? (radius1 - radius2) / length : 0;

  // Simple cases for horizontal and vertical moves
  real r2;
  if (conical) {
    if (z <= minZ) r2 = radius2;
    else if (maxZ + length <= z) r2 = radius1;
    else r2 = (z - minZ) * conicSlope + radius2;
    r2 *= r2;

  } else r2 = radius1 * radius1;

  if (vertical) return p1.distanceSquared(q) < r2;

  Vector2R c = Segment2R(p1, p2).closest(q);
  if (horizontal) return q.distanceSquared(c) < r2;

  // Slanting move
  // Find the ends of the line segment which passes through the move's
  // internal parallelogram at the z-height of p
  int count = 0;
  Vector2R s[2];

  // First check the verticals
  if (z1 <= z && z <= z1 + length) s[count++] = p1;
  if (z2 <= z && z <= z2 + length) s[count++] = p2;

  // Check top & bottom lines of the parallelogram
  if (count < 2) {
    real delta;
    if (minZ + length < z) delta = (z - minZ + length) / std::fabs(z2 - z1);
    else delta = (z - minZ) / std::fabs(z2 - z1);
    if (z1 < z2) s[count++] = p1 + (p2 - p1) * delta;
    else s[count++] = p2 + (p1 - p2) * delta;
  }

  // Find the closest point to p on the z-line segment
  c = Segment2R(s[0], s[1]).closest(q);

  // Check cone tool height for closest point
  if (conical) {
    // NOTE Slanting move so one or both of xLen and yLen is not zero
    real h = 0;
    if (xLen) h = z - (z1 + (c.x() - x1) / xLen * zLen);
    else if (yLen) h = z - (z1 + (c.y() - y1) / yLen * zLen);

    if (h < length) {
      r2 = h * conicSlope + radius2;
      r2 *= r2;
    }
  }

  real cDistSq = q.distanceSquared(c);
  if (cDistSq < r2) return true;
  if (!conical) return false;

  // Look up and down the z-line for a closer point on the cone
  real maxRadius = radius1 < radius2 ? radius2 : radius1;
  real l2 = maxRadius * maxRadius - cDistSq;
  real l = sqrt(l2); // How far to look
  Vector2R n = (s[1] - s[0]).normalize(); // Direction vector

  Vector2R a = c.distanceSquared(s[1]) < l2 ? s[1] : (c + n * l);
  Vector2R b = c.distanceSquared(s[0]) < l2 ? s[0] : (c - n * l);
  real aH = 0;
  real bH = 0;

  if (xLen) {
    aH = z - (z1 + (a.x() - x1) / xLen * zLen);
    bH = z - (z1 + (b.x() - x1) / xLen * zLen);

  } else if (yLen) {
    aH = z - (z1 + (a.y() - y1) / yLen * zLen);
    bH = z - (z1 + (b.y() - y1) / yLen * zLen);
  }

  real h = aH < bH ? bH : aH;
  c = aH < bH ? b : a;
  r2 = h * conicSlope + radius2;
  r2 *= r2;

  return q.distanceSquared(c) < r2;
}