# Tools for ray-tracing csg models in arbitrary spaces with arbitrary probing trajectories. # Last edited on 2021-09-29 14:51:22 by stolfi import rootray_shape_IMP; from rootray_shape_IMP import RootRay_Shape_IMP class RootRay_Shape(RootRay_Shape_IMP): # A {RootRay_Shape} object represents a complex shape obtained from # primitive objects by boolean operations and affine transformations. # # A {RootRay_Shape} object has an attribute {op}, a string that # determines the type of obejct. pass # PRIMITIVES def hspace(m): # Creates an object with {op} ="hspace" and an attribute {m}. The # characteristic function is coordinate {m} of the point. return rootray_shape_IMP.hspace(m) def box(ca, cb): # Creates an object with {op} ="box" and an attributes {ca,cb}. The points {ca,cb} must have # the same number {m} of coordinates. The # characteristic function is positive if the first {m} coordinaes # of the point are inside the box of {\RR^m} which has {ca} and {cb} # as opposite corners. return rootray_shape_IMP.box(ca, cb) def quadric(n, m, bias): # Creates an object with {op} = "quadric" and attributes {n}, {m}, and # {bias}. Its characteristic function is the sum of the squares of the # first {m} coordinates minus the squares of the next {n-m} # coordinates, plus the {bias}. return rootray_shape_IMP.quadric(n, m, bias) def prism(PTS): # Creates an object with {op} = "prism" object has a list of points of # {\RR^2}. See {rootray_cart.prism} for the semantics. return rootray_shape_IMP.prism(PTS) # TRANSFORM def affine(arg, Ainv, binv): # Creates an object with {op} = "affine". The attributes are: a child {RootRay_Shape} object {arg}, a {d} by # {d} non-singular array {Ainv}, and a {d}-vector {binv}. # # It represents the shape represented by {arg}, mapped by a linerar map # {Adir} and then translated by {bdir}. The attributes {Ainv} and {binv} # are the analogous parameters of the inverse affine map; that is, # {Ainv=Adir^{-1}} and {binv = bdir*Ainv}. return rootray_shape_IMP.affine(arg, Ainv, binv) # BOOLEAN def union(ARGS): # Creates an object with {op} = "union" object, whose attribute is a # list {ARGS} (possibly empty) of other {RootRay_Shape} objects. It # represents the union of the shapes defined by those objects. If the # list is empty, it describes the vacum shape. return rootray_shape_IMP.union(ARGS) def intersection(ARGS): # Creates an object with {op} = "intersection" object, whose attribute is a # list {ARGS} (possibly empty) of other {RootRay_Shape} objects. It # represents the intersection of the shapes defined by those objects. If the # list is empty, it describes the plenum shape. return rootray_shape_IMP.intersection(ARGS) def complement(arg): # Creates an object with {op} = "complement" object with one attribute # {arg}, a {RootRay_Shape} object. It represents the set-complement # with respect to {\RR^n} of the shape described by {arg}. return rootray_shape_IMP.complement(arg) # TRACING def trace(p, q, obj): # Traces the straight line through the points {p,q} and returns # a root-ray {(s,T)} that describes the intersections of that line # with the spahe defined by the {RootRay_Shape} object {obj}. # See the {rootray.py} interface for more details. return rootray_shape_IMP.trace(p, q, obj) # SPECIAL def from_polygons(PTCS, sgn_inf): # Assumes that {PTCS} is a list of lists, where each element is a # list of points that describe a simple closed polygon, with # the last point repeating the first point. The boundaries of the polygons should be # pairwise disjoint, and nested and oriented so that the nearest enclosing polygon # of each polygon should be oriented in opposite directions. Specifically, # island vertices should be in CCW order, and hole vertices should be in CW order. # # The parameter {sgn_inf} should be {+1} the outermost polygons are islands, # and {-1} if they are holes. # # Returns a {RootRay_Shape} object that describes the interior of that # collection of polygons. return rootray_shape_IMP.from_polygons(PTCS, sgn_inf)