All Downloads are FREE. Search and download functionalities are using the official Maven repository.

swim.math.CircleR2 Maven / Gradle / Ivy

// Copyright 2015-2019 SWIM.AI inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package swim.math;

import swim.codec.Debug;
import swim.codec.Format;
import swim.codec.Output;
import swim.structure.Kind;
import swim.structure.Value;
import swim.util.Murmur3;

public class CircleR2 extends R2Shape implements Debug {
  public final double cx;
  public final double cy;
  public final double r;

  public CircleR2(double cx, double cy, double r) {
    this.cx = cx;
    this.cy = cy;
    this.r = r;
  }

  @Override
  public final double xMin() {
    return this.cx - this.r;
  }

  @Override
  public final double yMin() {
    return this.cy - this.r;
  }

  @Override
  public final double xMax() {
    return this.cx + this.r;
  }

  @Override
  public final double yMax() {
    return this.cy + this.r;
  }

  @Override
  public boolean contains(R2Shape shape) {
    if (shape instanceof PointR2) {
      return contains((PointR2) shape);
    } else if (shape instanceof BoxR2) {
      return contains((BoxR2) shape);
    } else if (shape instanceof CircleR2) {
      return contains((CircleR2) shape);
    } else {
      return false;
    }
  }

  public boolean contains(PointR2 point) {
    final double dx = point.x - this.cx;
    final double dy = point.y - this.cy;
    return dx * dx + dy * dy <= this.r * this.r;
  }

  public boolean contains(BoxR2 box) {
    final double dxMin = box.xMin - this.cx;
    final double dyMin = box.yMin - this.cy;
    final double dxMax = box.xMax - this.cx;
    final double dyMax = box.yMax - this.cy;
    final double r2 = this.r * this.r;
    return dxMin * dxMin + dyMin * dyMin <= r2
        && dxMin * dxMin + dyMax * dyMax <= r2
        && dxMax * dxMax + dyMin * dyMin <= r2
        && dxMax * dxMax + dyMax * dyMax <= r2;
  }

  public boolean contains(CircleR2 circle) {
    final double dx = circle.cx - this.cx;
    final double dy = circle.cy - this.cy;
    return dx * dx + dy * dy + circle.r * circle.r <= this.r * this.r;
  }

  @Override
  public boolean intersects(R2Shape shape) {
    if (shape instanceof PointR2) {
      return intersects((PointR2) shape);
    } else if (shape instanceof BoxR2) {
      return intersects((BoxR2) shape);
    } else if (shape instanceof CircleR2) {
      return intersects((CircleR2) shape);
    } else {
      return shape.intersects(this);
    }
  }

  public boolean intersects(PointR2 point) {
    final double dx = point.x - this.cx;
    final double dy = point.y - this.cy;
    return dx * dx + dy * dy <= this.r * this.r;
  }

  public boolean intersects(BoxR2 box) {
    final double dx = (this.cx < box.xMin ? box.xMin : box.xMax < this.cx ? box.xMax : this.cx) - this.cx;
    final double dy = (this.cy < box.yMin ? box.yMin : box.yMax < this.cy ? box.yMax : this.cy) - this.cy;
    return dx * dx + dy * dy <= this.r * this.r;
  }

  public boolean intersects(CircleR2 circle) {
    final double dx = circle.cx - this.cx;
    final double dy = circle.cy - this.cy;
    final double rr = this.r + circle.r;
    return dx * dx + dy * dy <= rr * rr;
  }

  @Override
  public BoxZ2 transform(R2ToZ2Function f) {
    final double xMin = this.cx - this.r;
    final double yMin = this.cy - this.r;
    final double xMax = this.cx + this.r;
    final double yMax = this.cy + this.r;
    return new BoxZ2(f.transformX(xMin, yMin), f.transformY(xMin, yMin),
                     f.transformX(xMax, yMax), f.transformY(xMax, yMax));
  }

  @Override
  public Value toValue() {
    return form().mold(this).toValue();
  }

  protected boolean canEqual(CircleR2 that) {
    return true;
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    } else if (other instanceof CircleR2) {
      final CircleR2 that = (CircleR2) other;
      return that.canEqual(this) && this.cx == that.cx && this.cy == that.cy && this.r == that.r;
    }
    return false;
  }

  @Override
  public int hashCode() {
    if (hashSeed == 0) {
      hashSeed = Murmur3.seed(CircleR2.class);
    }
    return Murmur3.mash(Murmur3.mix(Murmur3.mix(Murmur3.mix(hashSeed,
        Murmur3.hash(this.cx)), Murmur3.hash(this.cy)), Murmur3.hash(this.r)));
  }

  @Override
  public void debug(Output output) {
    output.write("CircleR2").write('.').write("of").write('(')
        .debug(this.cx).write(", ").debug(this.cy).write(", ").debug(this.r).write(')');
  }

  @Override
  public String toString() {
    return Format.debug(this);
  }

  private static int hashSeed;

  private static R2Form form;

  public static CircleR2 of(double cx, double cy, double r) {
    return new CircleR2(cx, cy, r);
  }

  @Kind
  public static R2Form form() {
    if (form == null) {
      form = new CircleR2Form();
    }
    return form;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy