\providecommand{\ccRequire}{\ccCommentHeading{Requirement}}

\begin{ccRefClass}{Sphere_d<Kernel>}\ccCreationVariable{S}

\ccDefinition

An instance $S$ of the data type \ccc{Sphere_d} is an oriented sphere
in some $d$-dimensional space. A sphere is defined by $d+1$ points
(class \ccc{Point_d<Kernel>}). We use $A$ to denote the array of the
defining points.  A set $A$ of defining points is \emph{legal} if
either the points are affinely independent or if the points are all
equal. Only a legal set of points defines a sphere in the geometric
sense and hence many operations on spheres require the set of defining
points to be legal.  The orientation of $S$ is equal to the
orientation of the defining points, i.e., \ccc{orientation(A)}.

\ccSetOneOfTwoColumns{4cm}

\ccTypes

% \ccNestedType{R}{the representation type.  }

% \ccNestedType{RT}{the ring type.  }

% \ccNestedType{FT}{the field type.  }

\ccNestedType{LA}{the linear algebra layer.  }

\ccNestedType{point_iterator}{a read-only iterator for points defining
the sphere.  }

\ccSetOneOfTwoColumns{4cm}

\ccCreation

\ccConstructor{Sphere_d<Kernel>()}{introduces a variable \ccc{S}
of type \ccc{Sphere_d<Kernel>}.}

\ccConstructor{template <class ForwardIterator> Sphere_d<Kernel>(int d,
ForwardIterator first, ForwardIterator last)}{introduces a variable
\ccc{S} of type \ccc{Sphere_d<Kernel>}. \ccc{S} is initialized to the
sphere through the points in \ccc{A = tuple [first,last)}.  \ccPrecond
$A$ consists of $d+1$ $d$-dimensional points. 
\ccRequire{ The value type of ForwardIterator is \ccc{Point_d<Kernel>}. }}

\ccSetTwoOfThreeColumns{2.5cm}{2cm}

\ccOperations

\ccMethod{int dimension();}{returns the dimension of the ambient space.}

\ccMethod{Point_d<Kernel> point(int i) ;}{returns the $i$th defining
point. \ccPrecond{$0 \le i \le \ccc{dim}$.}  }

\ccMethod{point_iterator points_begin() ;}{returns an iterator
  pointing to the first defining point.  }

\ccMethod{point_iterator points_end() ;}{returns an iterator pointing
  beyond the last defining point. }

\ccMethod{bool is_degenerate();}{returns true iff the defining points
  are not full dimensional. }

\ccMethod{bool is_legal() ;}{returns true iff the set of defining
  points is legal.  A set of defining points is legal iff their
  orientation is non-zero or if they are all equal.}

\ccMethod{Point_d<Kernel> center() ;}{returns the center of \ccc{S}.
  \ccPrecond{\ccc{S} is legal.}  }

\ccMethod{FT squared_radius() ;}{returns the squared radius of the
  sphere. \ccPrecond{\ccc{S} is legal.}}

\ccMethod{Orientation orientation() ;}{returns the orientation of
  \ccc{S}.}

\ccMethod{Oriented_side oriented_side(const Point_d<Kernel>& p) ;}{returns
  either the constant \ccc{ON_ORIENTED_BOUNDARY},
  \ccc{ON_POSITIVE_SIDE}, or \ccc{ON_NEGATIVE_SIDE}, iff p lies on the
  boundary, properly on the positive side, or properly on the negative
  side of sphere, resp. \ccPrecond{\ccc{S.dimension()==p.dimension()}}.
  }

\ccMethod{Bounded_side bounded_side(const Point_d<Kernel>& p) ;}{returns
  \ccc{ON_BOUNDED_SIDE}, \ccc{ON_BOUNDARY}, or \ccc{ON_UNBOUNDED_SIDE}
  iff p lies properly inside, on the boundary, or properly outside of
  sphere, resp. \ccPrecond{\ccc{S.dimension()==p.dimension()}.} }

\ccMethod{bool has_on_positive_side (const Point_d<Kernel>& p) ;}{returns
  \ccc{S.oriented_side(p)==ON_POSITIVE_SIDE}. \ccPrecond
  \ccc{S.dimension()==p.dimension()}. }

\ccMethod{bool has_on_negative_side (const Point_d<Kernel>& p) ;}{returns
  \ccc{S.oriented_side(p)==ON_NEGATIVE_SIDE}. \ccPrecond
  \ccc{S.dimension()==p.dimension()}. }

\ccMethod{bool has_on_boundary (const Point_d<Kernel>& p) ;}{returns
  \ccc{S.oriented_side(p)==ON_ORIENTED_BOUNDARY}, which is the same as
  \ccc{S.bounded_side(p)==ON_BOUNDARY}. \ccPrecond
  \ccc{S.dimension()==p.dimension()}. }

\ccMethod{bool has_on_bounded_side (const Point_d<Kernel>& p) ;}{returns
  \ccc{S.bounded_side(p)==ON_BOUNDED_SIDE}. \ccPrecond
  \ccc{S.dimension()==p.dimension()}. }

\ccMethod{bool has_on_unbounded_side (const Point_d<Kernel>& p) ;}{returns
  \ccc{S.bounded_side(p)==ON_UNBOUNDED_SIDE}.  \ccPrecond
  \ccc{S.dimension()==p.dimension()}. }

\ccMethod{Sphere_d<Kernel> opposite() ;}{returns the sphere with the same
  center and squared radius as \ccc{S} but with opposite orientation.
  }

%\ccMethod{Sphere_d<Kernel> transform(const Aff_transformation_d<Kernel>& t)
%;}{returns $t(s)$. \ccPrecond{\ccc{S.dimension()==t.dimension()}.} }

\ccMethod{Sphere_d<Kernel> operator+(const Vector_d<Kernel>& v) ;}{returns the
  sphere translated by \ccc{v}. \ccPrecond
  \ccc{S.dimension()==v.dimension()}. }

\ccHeading{Non-Member Functions}  

\ccFunction{bool weak_equality(const Sphere_d<Kernel>& S1, const
  Sphere_d<Kernel>& S2) ;}{Test for equality as unoriented spheres.
  \ccPrecond{\ccc{S1.dimension()==S2.dimension()}.} }

\ccImplementation

Spheres are implemented by a vector of points as a handle type.  All
operations like creation, initialization, tests, input and output of a
sphere $s$ take time $O(\ccc{s.dimension()})$. \ccc{dimension()},
point access take constant time.  The \ccc{center()}-operation takes
time $O(d^3)$ on its first call and constant time thereafter. The
sidedness and orientation tests take time $O(d^3)$.  The space
requirement for spheres is $O(\ccc{s.dimension()})$ neglecting the
storage room of the points.

\end{ccRefClass}


