(* Copyright (c) 1992 The Geometry Center; University of Minnesota
   1300 South Second Street;  Minneapolis, MN  55454, USA;
   
This file is part of CirclePack. CirclePack is free software; you can
redistribute it and/or modify it only under the terms given in the
file COPYING, which you should have received along with this file.
This and other software may be obtained via anonymous ftp from
geom.umn.edu; email: software@geom.umn.edu. *)

(* Author: Silvio Levy *)
(* $Id: Circle3D.m,v 1.2 1992/07/17 16:09:52 oag Exp $ *)
(* NOTE: This package is under development as part of a separate 
   hyperbolic geometry package. *)

BeginPackage["Circle3D`","Normalize`"]

Circle3D::usage = "\n
  Circle3D[center,radius,normal] returns a circle with specified\n
  center and radius, on a plane orthogonal to normal.\n
  Circle3D[center,{semiaxis1,semiaxis2},{t1,t2}] returns an arc of\n
  the ellipse parametrized by center+semiaxis1 Cos[t]+semiaxis2 Sin[t],\n
  for t going from t1 to t2. Options are passed to ParametricPlot3D."

Circle3D::badnormal = "Normal vector `` should not have length 0"

Hyperbola3D::usage = "\n
  Hyperbola3D[center,{semiaxis1,semiaxis2},{t1,t2}] returns an arc of\n
  the hyperbola parametrized by center+semiaxis1 Cosh[t]+semiaxis2 Sinh[t],\n
  for t going from t1 to t2. Options are passed to ParametricPlot3D."

Begin["`private`"]

Cross[x_,y_] := RotateLeft[RotateLeft[y] x - RotateLeft[x] y]

Circle3D[center_,radius_,normal_?VectorQ,options___] :=
  If[N[normal.normal]==0,Message[Circle3D::badnormal,normal];Null, 
    Block[
      {semiaxis1,semiaxis2,l},
      semiaxis1=Normalize[
        Cross[normal,If[N[normal[[1]]]==N[normal[[2]]]==0,{0,1,0},{0,0,1}]]];
      semiaxis2=Normalize[Cross[semiaxis1,normal]];
      Circle3D[center,radius{semiaxis1,semiaxis2},{0,2Pi},options]]]

Circle3D[center_,{sa1_,sa2_},{t1_,t2_},options___] := 
  fixpp[ParametricPlot3D[center+sa1 Cos[t]+sa2 Sin[t],{t,t1,t2},options,
    DisplayFunction->Identity, Compiled->False][[1]]]

Circle3D[center_,{sa1_,sa2_},options___] :=
  Circle3D[center,{sa1,sa2},{0,2Pi},options]

Disk3D[x__]:= Polygon @@ Circle3D[x]

Hyperbola3D[center_,{sa1_,sa2_},{t1_,t2_},options___] := 
  fixpp[ParametricPlot3D[center+sa1 Cosh[t]+sa2 Sinh[t],{t,t1,t2},options,
    DisplayFunction->Identity, Compiled->False][[1]]]

fixpp[x_] := Line[Append[#[[1,1]]&/@x,x[[-1,-1,-1]]]]

End[]
EndPackage[]


