# Tools for tracing straight rays through simple solids in Cartesian space {\RR^d}.
# Last edited on 2021-09-29 01:53:49 by stolfi

import rootray_cart_IMP
import rootray

# See {rootray.py} for an explanation of root-rays.

# RAYTRACING PRIMITIVES

# In the procedure of this section, the trajectory {r} is defined by two
# points {p,q} of some Cartesian space {\RR^d}, as {r(t) = t p +
# (1-t)q}. Note that this trajectory spans the whole infinite straight
# line defined by the two points. Each procedure returns a root ray for
# {r} relative to some simple subset {F} of {\RR^n}. 
#
# The two points must be distinct tuples or lists of floats with the same length {d}.
# These shapes assume the Cartesian model of Euclidean space.
  
def halfspace(p, q, k):
  # The figure {F} is the halfspace whose interior is all points whose coordinate {k} 
  # is negative. The index{k} should be in {0..d-1}.
  return rootray_cart_IMP.halfspace(p, q, k)
  
def slab(p, q, k):
  # The figure {F} consists of the points whose coordinate {k} is in the range {(-1 _ +1)}.
  return rootray_cart_IMP.slab(p, q, k)
  
def cube(p, q):
  # The figure {F} is the axis-aligned {d}-dimensional hypercube of side 
  # 2 centered at the origin; that is, {[-1 _+1]^d}.
  return rootray_cart_IMP.cube(p, q)
  
def box(p, q, ca, cb):
  # The figure {F} is the axis-aligned {d}-dimensional box with opposite corners 
  # {ca,cb}.  The box must have non-zero size along all axes.
  return rootray_cart_IMP.box(p, q, ca, cb)

def quadric(p, q, n, m, bias):
  # The figure {F} is the quadratic form of {\RR^n} which is the sum of
  # squares of the first {m} coordinates, minus the sum of squares of
  # the following {n-m} coordinates, plus the given {bias}. Any
  # additional coordinates are ignored. If {p} and {q} have less than n
  # coordinates, they are implicitly extended with zeros.
  #
  # If {m = n} and {bias} is not negative, the quadric is equivalent to
  # {rootray.vacuum()} . If {m} is zero and {bias} is non-positive, it
  # is equivalent to {rootray.plenum()}.
 return rootray_cart_IMP.quadric(p, q, n, m, bias)

def cylinder(p, q, m):
  # The figure {F} is a cylinder centered at the origin
  # that is a ball of unit radius on the first {m} coordinates,
  # and unrestrited in the last {d-m}. For example, if {d=3} and {m=2}, then {F}
  # is the infinite cylinder in {\RR^3} radius 1 whose axis is the {Z} axis.
  # It is equivalent to {quadric(p, q, m, m, -1)}.
  #
  # If {m == 0}, this is equivalent to {rootray.plenum()}. If {m == 1},
  # this is equivalent to {slab(p,q,0)}. If {m == d}, this is equivalent
  # to {ball(p,q)}.
  return rootray_cart_IMP.cylinder(p, q, m)
  
def cone(p, q, m):
  # The figure {F} is the quadratic form of {\RR^d} which is the sum of squares
  # of the first {m} coordinates minus the sum of squares of the next {d-m}.
  # It is the same as {quadric(p, q, d, m, 0)}.
  #
  # For example, if {d=3} and {m=2}, {F} consists of the two oppositely directed infinite cones
  # with vertex at the origin and revolving around the {Z} axis, with walls sloping at 45 degrees.
  # If {d=2} and {m=1}, {F} is the 
  #
  # If {m == 0}, this is essentially equivalent to {plenum()}. If {m == d}, this is essentially
  # equivalent {vacuum}.
  return rootray_cart_IMP.cone(p, q, m)

def ball(p, q):
  # The figure {F} is the {d}-dimensional ball of unit radius centered 
  # at the origin.  It is equivalent to {quadric(p,q,d,d,-1)}.
  return rootray_cart_IMP.ball(p, q)

def prism(p, q, PTS):
  # The figure {F} is a prism consisting of all points of {\RR^d} whose 
  # first two coordinates lie inside the simple polygon of {\RR^2} 
  # whose vertices are the elements of the list {PTS}.
  #
  # The polygon is assumed to be oriented so that the ineterior is on the
  # left margin.  Namely, if the vertices are listed in CCW order, the 
  # interior is the bounded side; if listed in CW order, the interior
  # is the unbounded side.
  return rootray_cart_IMP.prism(p, q, PTS)
