// semi-sphere-image.c Section: 5.7, The Rolling Ball Algorithm
//     Copyright 1994, Center for Computer Vision and Visualization,
//     University of Florida.  All rights reserved.

#include "semi-sphere-image.h"
#include "shaped-pointset.h"
#include "PSIter.h"


// This function produces the non-negative semi-spherical surface
//   of a sphere of dimension domain_dimension, and with the
//   indicated radius.
// Since the point type P is often IA_Point<int>, the domain
//   of the image will be a digital_disc() of the indicated radius.
// NOTE: parameters pzero and tzero are not used, but are necessary
//   because Cfront insists that the template parameters occur in
//   the signiture of the function, which does NOT include the
//   return type.  Use (P*)0 and (T*)0
//
template <class P, class T>
IA_Image<P,T>
semi_sphere_image( double radius, unsigned int domain_dimension,
		   P * pzero, T * tzero )
{
    IA_Set<P>
	bps( digital_disc( extend_to_point( 0, domain_dimension ),
			   radius ) );

    T * val( new T[ bps.card() ] );
    if ( val == 0 ) {
	ia_throw( IA::PSET_REQUIRE_EXTENSIVE, __FILE__, __LINE__ );
	return IA_Image<P,T>();
    }

    // We must fill the the values in in point set iteration order
    //   so we\'ll create an iterator and let it do the work.

    IA_PSIter<P> ips( bps );

    double r2 = radius * radius;
    P pt;
    int i=0;
    while( ips( pt ) ) {
	double  pt_norm( enorm( pt ) );
	val[ i++ ] = T( sqrt( r2 - pt_norm*pt_norm ) );
    }

    // We\'ll give the iac++ library storage management control.
    return
	IA_Image<P,T>( bps, val, bps.card(), 1 );
}
