<commit_before>// Sphere.cpp

#include "../Header.h"

//===========================================================================
Sphere::Sphere( const c3ga::vectorE3GA& center, double radius, const c3ga::vectorE3GA& color )
{
	dualSphere = c3ga::no + center + 0.5 * ( c3ga::lc( center, center ) - radius * radius ) * c3ga::ni;
	this->color = color;
}

//===========================================================================
Sphere::Sphere( const c3ga::dualSphere& dualSphere, const c3ga::vectorE3GA& color )
{
	this->dualSphere = dualSphere;
	this->color = color;
}

//===========================================================================
/*virtual*/ Sphere::~Sphere( void )
{
}

//===========================================================================
/*virtual*/ Scene::Element* Sphere::Clone( void ) const
{
	return new Sphere( dualSphere, color );
}

//===========================================================================
// This math is over-kill, but it's an alternative to the traditional method.
/*virtual*/ bool Sphere::CalculateSurfacePoint(
							const Scene::Ray& ray,
							Scene::SurfacePoint& surfacePoint,
							double& distance ) const
{
	c3ga::vectorE3GA otherRayPoint = ray.point + ray.direction;

	c3ga::dualLine dualLine;
	dualLine = ( c3ga::no + ray.point + 0.5 * c3ga::lc( ray.point, ray.point ) * c3ga::ni ) ^
		( c3ga::no + otherRayPoint + 0.5 * c3ga::lc( otherRayPoint, otherRayPoint ) * c3ga::ni ) ^
		c3ga::ni;

	// A real dual point-pair is an imaginary direct circle.
	c3ga::circle dualPointPair;
	dualPointPair = dualLine ^ dualSphere;

	c3ga::vectorE3GA normal = ray.direction;
	c3ga::trivectorE3GA i( c3ga::trivectorE3GA::coord_e1e2e3, 1.0 );
	c3ga::vectorE2GA center;
	center = normal * ( c3ga::lc( c3ga::noni, dualPointPair ^ c3ga::gp( c3ga::no, c3ga::ni ) ) ) * i;

	c3ga::mv mv = -c3ga::lc( center, center ) + 2.0 * c3ga::gp(
					c3ga::lc( c3ga::noni, c3ga::no ^ dualPointPair ) * i +
					c3ga::gp( c3ga::lc( center, normal ), center ), normal );
	double squareRadius = mv.get_scalar();
	
	// If the point-pair was imaginary, then the ray did not intersect the sphere.
	if( squareRadius < 0.0 )
		return false;

	c3ga::vectorE3GA sphereCenter;
	sphereCenter = c3ga::applyUnitVersor( dualSphere, c3ga::ni );

	surfacePoint.point = center - c3ga::gp( normal, sqrt( squareRadius ) );
	surfacePoint.normal = c3ga::unit( surfacePoint.point - sphereCenter );
	surfacePoint.color = color;
	surfacePoint.reflectionCoeficient = 0.0;
	surfacePoint.refractionCoeficient = 0.0;

	return true;
}

// Sphere.cpp<commit_msg>potentially a bit faster (still untested)<commit_after>// Sphere.cpp

#include "../Header.h"

//===========================================================================
Sphere::Sphere( const c3ga::vectorE3GA& center, double radius, const c3ga::vectorE3GA& color )
{
	dualSphere = c3ga::no + center + 0.5 * ( c3ga::lc( center, center ) - radius * radius ) * c3ga::ni;
	this->color = color;
}

//===========================================================================
Sphere::Sphere( const c3ga::dualSphere& dualSphere, const c3ga::vectorE3GA& color )
{
	this->dualSphere = dualSphere;
	this->color = color;
}

//===========================================================================
/*virtual*/ Sphere::~Sphere( void )
{
}

//===========================================================================
/*virtual*/ Scene::Element* Sphere::Clone( void ) const
{
	return new Sphere( dualSphere, color );
}

//===========================================================================
// This math is over-kill, but it's an alternative to the traditional method.
/*virtual*/ bool Sphere::CalculateSurfacePoint(
							const Scene::Ray& ray,
							Scene::SurfacePoint& surfacePoint,
							double& distance ) const
{
	c3ga::trivectorE3GA i( c3ga::trivectorE3GA::coord_e1e2e3, 1.0 );

	c3ga::dualLine dualLine;
	dualLine = ( ray.direction + ( ray.point ^ ray.direction ) * c3ga::ni ) * i;

	// A real dual point-pair is an imaginary direct circle.
	c3ga::circle dualPointPair;
	dualPointPair = dualLine ^ dualSphere;

	c3ga::vectorE3GA normal = ray.direction;
	c3ga::vectorE2GA center;
	center = normal * ( c3ga::lc( c3ga::noni, dualPointPair ^ ( c3ga::no * c3ga::ni ) ) ) * i;

	c3ga::mv mv = -c3ga::lc( center, center ) + 2.0 * (
					c3ga::lc( c3ga::noni, c3ga::no ^ dualPointPair ) * i +
					( c3ga::lc( center, normal ) * center ) * normal );
	double squareRadius = mv.get_scalar();
	
	// If the point-pair was imaginary, then the ray did not intersect the sphere.
	if( squareRadius < 0.0 )
		return false;

	c3ga::vectorE3GA sphereCenter;
	sphereCenter = dualSphere; //c3ga::applyUnitVersor( dualSphere, c3ga::ni );

	surfacePoint.point = center - normal * sqrt( squareRadius );
	surfacePoint.normal = c3ga::unit( surfacePoint.point - sphereCenter );
	surfacePoint.color = color;
	surfacePoint.reflectionCoeficient = 0.0;
	surfacePoint.refractionCoeficient = 0.0;

	return true;
}

// Sphere.cpp
{'fraction_non_alphanumeric': 0.27912572688991377, 'fraction_numerical': 0.023661519951874873, 'mean_word_length': 4.952267303102626, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5661711', 'n_tokens_mistral': 1742, 'n_tokens_neox': 1589, 'n_words': 367}