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

scalismo.mesh.kdtree.Region.scala Maven / Gradle / Ivy

/*
 * Copyright 2012 Nadav Samet  https://github.com/thesamet/kdtree-scala
 *
 * 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 scalismo.mesh.kdtree

import scala.language.implicitConversions

sealed private[scalismo] trait Region[A] {
  def overlapsWith(other: Region[A])(implicit ord: DimensionalOrdering[A]): Boolean
  def contains(p: A)(implicit ord: DimensionalOrdering[A]): Boolean
}

private[scalismo] case class EntireSpace[A]() extends Region[A] {
  def overlapsWith(other: Region[A])(implicit ord: DimensionalOrdering[A]): Boolean = true
  def contains(p: A)(implicit ord: DimensionalOrdering[A]): Boolean = true
}

private[scalismo] case class AboveHyperplane[A](a: A, dim: Int) extends Region[A] {
  def overlapsWith(other: Region[A])(implicit ord: DimensionalOrdering[A]): Boolean = other match {
    case EntireSpace()               => true
    case AboveHyperplane(b, bdim)    => true
    case BelowHyperplane(b, bdim)    => (dim != bdim) || (ord.compareProjection(dim)(b, a) >= 0)
    case RegionIntersection(regions) => regions.forall(overlapsWith _)
  }
  def contains(p: A)(implicit ord: DimensionalOrdering[A]): Boolean =
    ord.compareProjection(dim)(p, a) >= 0
}

private[scalismo] case class BelowHyperplane[A](a: A, dim: Int) extends Region[A] {
  def overlapsWith(other: Region[A])(implicit ord: DimensionalOrdering[A]): Boolean = other match {
    case EntireSpace()               => true
    case AboveHyperplane(b, bdim)    => (dim != bdim) || (ord.compareProjection(dim)(b, a) <= 0)
    case BelowHyperplane(b, bdim)    => true
    case RegionIntersection(regions) => regions.forall(overlapsWith)
  }
  def contains(p: A)(implicit ord: DimensionalOrdering[A]): Boolean =
    ord.compareProjection(dim)(p, a) <= 0
}

private[scalismo] case class RegionIntersection[A](regions: Seq[Region[A]]) extends Region[A] {
  def overlapsWith(other: Region[A])(implicit ord: DimensionalOrdering[A]): Boolean = {
    regions.forall(_.overlapsWith(other))
  }
  def contains(p: A)(implicit ord: DimensionalOrdering[A]): Boolean =
    regions.forall(_.contains(p))
}

private[scalismo] class RegionBuilder[A] {
  var regions = new scala.collection.mutable.ArrayBuffer[Region[A]]

  def addRegion(region: Region[A]) = {
    regions += region
    this
  }

  def from(a: A, dim: Int): RegionBuilder[A] = addRegion(AboveHyperplane(a, dim))

  def to(a: A, dim: Int): RegionBuilder[A] = addRegion(BelowHyperplane(a, dim))

  def and(other: RegionBuilder[A]): RegionBuilder[A] = {
    regions ++= other.regions
    this
  }

  def build: Region[A] = regions.length match {
    case 0 => EntireSpace()
    case 1 => regions.head
    case _ => RegionIntersection(regions.toSeq)
  }
}

private[scalismo] object Region {
  implicit def fromBuilder[A](builder: RegionBuilder[A]): Region[A] = builder.build
  def from[A](a: A, dim: Int): RegionBuilder[A] = (new RegionBuilder).from(a, dim)
  def to[A](a: A, dim: Int): RegionBuilder[A] = (new RegionBuilder).to(a, dim)
  def and[A](other: RegionBuilder[A]): RegionBuilder[A] = (new RegionBuilder).and(other)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy