    // @(#)root/g3d:$Name:  $:$Id: TCTUB.cxx,v 1.2 2000/11/21 20:15:33 brun Exp $
    // Author: Rene Brun   26/06/97

    /*************************************************************************
     * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
     * All rights reserved.                                                  *
     *                                                                       *
     * For the licensing terms see $ROOTSYS/LICENSE.                         *
     * For the list of contributors see $ROOTSYS/README/CREDITS.             *
     *************************************************************************/

    #include "TCTUB.h"
    #include "TClass.h"

    ClassImp(TCTUB)

    //______________________________________________________________________________
    //

    //                                                                        //
    // 'CTUB' is a cut  tube with 11 parameters.  The  first 5 parameters     //
    //        are the same  as for the TUBS.  The  remaining 6 parameters     //
    //        are the director  cosines of the surfaces  cutting the tube     //
    //        respectively at the low and high Z values.                      //
    //                                                                        //
    //     - name       name of the shape
    //     - title      shape's title
    //     - material  (see TMaterial)
    //     - rmin       inside radius
    //     - rmax       outside radius
    //     - dz         half length in z
    //     - phi1       starting angle of the segment
    //     - phi2       ending angle of the segment
    //     - coslx      x dir cosinus at low z face
    //     - cosly      y dir cosinus at low z face
    //     - coslz      z dir cosinus at low z face
    //     - coshx      x dir cosinus at high z face
    //     - coshy      y dir cosinus at high z face
    //     - coshz      z dir cosinus at high z face

    //______________________________________________________________________________
     TCTUB::TCTUB()
    {
    //*-*-*-*-*-*-*-*-*-*-*-*CTUB shape default constructor*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                    ==============================

    }

    //______________________________________________________________________________
     TCTUB::TCTUB(const char *name, const char *title, const char *material, Float_t rmin,
                 Float_t rmax, Float_t dz, Float_t phi1, Float_t phi2,
                 Float_t coslx, Float_t cosly, Float_t coslz,
                 Float_t coshx, Float_t coshy, Float_t coshz)
          : TTUBS(name,title,material,rmin,rmax,dz,phi1,phi2)
    {
    //*-*-*-*-*-*-*-*-*-*-*-*-*CTUB shape normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                      =============================

        fCosLow[0]  = coslx;
        fCosLow[1]  = cosly;
        fCosLow[2]  = coslz;
        fCosHigh[0] = coshx;
        fCosHigh[1] = coshy;
        fCosHigh[2] = coshz;
        TMath::Normalize(fCosLow);
        TMath::Normalize(fCosHigh);
    }

    //______________________________________________________________________________
     TCTUB::TCTUB(const char *name, const char *title, const char *material, Float_t rmin,
                 Float_t rmax, Float_t dz, Float_t phi1, Float_t phi2,
                 Float_t *lowNormal, Float_t *highNormal)
          : TTUBS(name,title,material,rmin,rmax,dz,phi1,phi2)
    {
    //*-*-*-*-*-*-*-*-*-*-*-*-*CTUB shape normal constructor*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                      =============================
        memcpy(fCosLow, lowNormal, sizeof(fCosLow) );
        memcpy(fCosHigh,highNormal,sizeof(fCosHigh));
        TMath::Normalize(fCosLow);
        TMath::Normalize(fCosHigh);
    }

    //______________________________________________________________________________
     TCTUB::~TCTUB()
    {
    //*-*-*-*-*-*-*-*-*-*-*-*-*CTUB shape default destructor*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                      =============================

    }

    //______________________________________________________________________________
    static Float_t Product(const Float_t *x, const Float_t *y)
    {
     Double_t s = 0;
     for (int i= 0 ; i <2 ; i++ ) s += x[i]*y[i];
     return Float_t(s);
    }
    //______________________________________________________________________________
     void TCTUB::SetPoints(Float_t *buff)
    {
    //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*Create TUBS points*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
    //*-*                            ==================

        Float_t dz;
        Int_t j, n;

        n = GetNumberOfDivisions()+1;

        dz   = TTUBE::fDz;

        if (buff) {
            Int_t indx = 0;
    //*-* We've to checxk whether the table does exist and create it
    //*-* since fCoTab/fSiTab are not saved with any TShape::Streamer function

            if (!fCoTab)   MakeTableOfCoSin();

            for (j = 0; j < n; j++) {
                buff[indx+6*n] = buff[indx] = fRmin * fCoTab[j];
                indx++;
                buff[indx+6*n] = buff[indx] = fAspectRatio*fRmin * fSiTab[j];
                indx++;
                buff[indx+6*n] = dz;
                buff[indx+6*n]-= Product(&buff[indx+6*n-2],fCosHigh)/fCosHigh[2];
                buff[indx]     =-dz;
                buff[indx]    -= Product(&buff[indx-2],fCosLow)/fCosLow[2];
                indx++;
            }
            for (j = 0; j < n; j++) {
                buff[indx+6*n] = buff[indx] = fRmax * fCoTab[j];
                indx++;
                buff[indx+6*n] = buff[indx] = fAspectRatio*fRmax * fSiTab[j];
                indx++;
                buff[indx+6*n] = dz;
                buff[indx+6*n]-= Product(&buff[indx+6*n-2],fCosHigh)/fCosHigh[2];
                buff[indx]     =-dz;
                buff[indx]    -= Product(&buff[indx-2],fCosLow)/fCosLow[2];
                indx++;
            }
        }
    }

    //______________________________________________________________________________
     void TCTUB::Streamer(TBuffer &R__b)
    {
       // Stream an object of class TCTUB.

       if (R__b.IsReading()) {
          UInt_t R__s, R__c;
          Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
          if (R__v > 1) {
             TCTUB::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
             return;
          }
          //====process old versions before automatic schema evolution
          TTUBS::Streamer(R__b);
          R__b.ReadStaticArray(fCosLow);
          R__b.ReadStaticArray(fCosHigh);
          R__b.CheckByteCount(R__s, R__c, TCTUB::IsA());
          //====end of old versions

       } else {
          TCTUB::Class()->WriteBuffer(R__b,this);
       }
    }