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

scalismo.common.Domain.scala Maven / Gradle / Ivy

There is a newer version: 1.0-RC1
Show newest version
/*
 * Copyright 2015 University of Basel, Graphics and Vision Research Group
 *
 * 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.common

import scalismo.geometry._
import scalismo.transformations.{CanInvert, Transformation}

trait Domain[D] {
  self =>
  def isDefinedAt(pt: Point[D]): Boolean

  def warp(t: Transformation[D] with CanInvert[D, Transformation]): Domain[D] = new Domain[D] {
    val tinv = t.inverse

    override def isDefinedAt(pt: Point[D]): Boolean = {
      self.isDefinedAt(tinv(pt))
    }
  }
}

object Domain {
  def fromPredicate[D](chi: Point[D] => Boolean) = new Domain[D] {
    override def isDefinedAt(pt: Point[D]) = chi(pt)
  }

  def intersection[D](thisDomain: Domain[D], thatDomain: Domain[D]) = new Domain[D] {
    override def isDefinedAt(pt: Point[D]) = thisDomain.isDefinedAt(pt) && thatDomain.isDefinedAt(pt)
  }

  def union[D](thisDomain: Domain[D], thatDomain: Domain[D]) = new Domain[D] {
    override def isDefinedAt(pt: Point[D]) = thisDomain.isDefinedAt(pt) || thatDomain.isDefinedAt(pt)
  }
}

class EuclideanSpace[D]() extends Domain[D] {
  override def isDefinedAt(pt: Point[D]) = true
}

object EuclideanSpace {
  def apply[D]: EuclideanSpace[D] = new EuclideanSpace[D]()
}

object EuclideanSpace1D extends EuclideanSpace[_1D]
object EuclideanSpace2D extends EuclideanSpace[_2D]
object EuclideanSpace3D extends EuclideanSpace[_3D]

@deprecated("please use EuclideanSpace instead", "v0.18")
class RealSpace[D] extends Domain[D] {
  override def isDefinedAt(pt: Point[D]) = true
}

object RealSpace {
  @deprecated("please use EuclideanSpace instead", "v0.18")
  def apply[D] = new RealSpace[D]
}

trait BoxDomain[D] extends Domain[D] {

  def origin: Point[D]
  def oppositeCorner: Point[D]

  def isDefinedAt(pt: Point[D]): Boolean = {
    def isInsideAxis(i: Int) = pt(i) >= origin(i) && pt(i) <= oppositeCorner(i)
    (0 until pt.dimensionality).forall(i => isInsideAxis(i))
  }

  def extent: EuclideanVector[D] = oppositeCorner - origin
  def volume: Double =
    (0 until origin.dimensionality).foldLeft(1.0)((prod, i) => prod * (oppositeCorner(i) - origin(i)))

}

object BoxDomain {
  def apply(origin: Point1D, oppositeCorner: Point1D) = BoxDomain1D(origin, oppositeCorner)
  def apply(origin: Point2D, oppositeCorner: Point2D) = BoxDomain2D(origin, oppositeCorner)
  def apply(origin: Point3D, oppositeCorner: Point3D) = BoxDomain3D(origin, oppositeCorner)

  /**
   * Creates a BoxDomain of dimensionality D. Attention, due to the fact that it is a generic
   * constructor, the isDefinedAt method of the resulting object will not be as optimized as when created for a
   * specific dimensionality
   */
  def apply[D: NDSpace](orig: Point[D], oppCorner: Point[D]) = new BoxDomain[D] {
    override val oppositeCorner = oppCorner
    override val origin = orig
  }
}

case class BoxDomain1D(origin: Point[_1D], oppositeCorner: Point[_1D]) extends BoxDomain[_1D] {
  override def isDefinedAt(p: Point[_1D]): Boolean = {
    val pt: Point1D = p
    pt.x >= origin.x && pt.x <= oppositeCorner.x
  }
}

case class BoxDomain2D(origin: Point[_2D], oppositeCorner: Point[_2D]) extends BoxDomain[_2D] {
  override def isDefinedAt(p: Point[_2D]): Boolean = {
    val pt: Point2D = p
    pt.x >= origin.x && pt.x <= oppositeCorner.x &&
    pt.y >= origin.y && pt.y <= oppositeCorner.y
  }
}

case class BoxDomain3D(origin: Point[_3D], oppositeCorner: Point[_3D]) extends BoxDomain[_3D] {
  override def isDefinedAt(p: Point[_3D]): Boolean = {
    val pt: Point3D = p
    pt.x >= origin.x && pt.x <= oppositeCorner.x &&
    pt.y >= origin.y && pt.y <= oppositeCorner.y &&
    pt.z >= origin.z && pt.z <= oppositeCorner.z
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy