//===========================================================================
/*virtual*/ double CylindricalInversion::EvaluatePartialZ( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	return 4.0*z*z*z + 2.0*A*x*z + 2.0*B*z + 4.0*x*x*z;
}
//===========================================================================
/*virtual*/ double CylindricalInversion::EvaluatePartialX( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	double x2 = x * x;
	double y2 = y * y;
	double z2 = z * z;

	return 4.0*x2*x + 3.0*A*x2 + A*y2 + A*z2 + 2.0*B*x + 4.0*x*( y2 + z2 );
}
Beispiel #3
0
//=================================================================================
/*static*/ bool Node::WriteVectorE3GA( lua_State* L, Context& context, const std::string& name, const c3ga::vectorE3GA& vector )
{
	lua_newtable( L );

	WriteNumber( L, context, "x", vector.get_e1() );
	WriteNumber( L, context, "y", vector.get_e2() );
	WriteNumber( L, context, "z", vector.get_e3() );

	lua_setfield( L, -2, name.c_str() );

	return true;
}
Beispiel #4
0
//===========================================================================
/*virtual*/ double DoubleTorus::EvaluatePartialY( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	double x2 = x * x;
	double y2 = y * y;
	double z2 = z * z;

	// f_y(x,y,z) = 16x^2y + 16x^4y + 4y^3
	return 16.0*x2*y + 10.0*x2*x2*y + 4.0*y2*y;
}
Beispiel #5
0
//===========================================================================
/*virtual*/ double DoubleTorus::EvaluatePartialX( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	double x2 = x * x;
	double y2 = y * y;
	double z2 = z * z;

	double x4 = x2 * x2;

	// f_x(x,y,z) = 64x^3 - 192x^5 - 16xy^2 + 128x^7 + 32x^3y^2
	return 64.0*x2*x - 192.0*x4*x - 16.0*x*y2 + 128.0*x4*x2*x + 3.0*x2*x*y2;
}
Beispiel #6
0
//===========================================================================
/*virtual*/ double DoubleTorus::Evaluate( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	double x2 = x * x;
	double y2 = y * y;
	double z2 = z * z;

	double x4 = x2 * x2;

	// f(x,y,z) = 16x^4 - 32x^6 - 8x^2y^2 + 16x^8 + 8x^4y^2 + y^4 + z^2 + 0.25
	return 16.0*x4 - 32.0*x4*x2 - 8.0*x2*y2 + 16.0*x4*x4 + 8.0*x4*y2 + y2*y2 + z2 + 0.25;
}
//===========================================================================
/*virtual*/ double CylindricalInversion::Evaluate( const c3ga::vectorE3GA& point ) const
{
	double x = point.get_e1();
	double y = point.get_e2();
	double z = point.get_e3();

	double x2 = x * x;
	double y2 = y * y;
	double z2 = z * z;

	double x4 = x2 * x2;
	double y4 = y2 * y2;
	double z4 = z2 * z2;

	return x4 + y4 + z4 + A*x*( x2 + y2 + z2 ) + B*( x2 + z2 ) + 2.0*x2*( y2 + z2 );
}
Beispiel #8
0
//===========================================================================
// A coordinate system is layed out on the plane and the texture is
// scaled into the first quadrant of that system.  UV coordintes
// will go outside of the range [0,1]x[0,1] if the given surface point
// is not in the square of this first quadrant.
/*virtual*/ bool Plane::CalculateTextureCoordinates( const c3ga::vectorE3GA& point, c3ga::vectorE3GA& textureCoordinates ) const
{
	c3ga::bivectorE3GA plane = c3ga::gp( normal, c3ga::I3 );

	c3ga::vectorE3GA uAxis, vAxis;

	uAxis.set( c3ga::vectorE3GA::coord_e1_e2_e3, 1.0, 0.0, 0.0 );
	uAxis = c3ga::lc( c3ga::lc( uAxis, plane ), c3ga::reverse( plane ) );
	if( c3ga::norm( uAxis ) == 0.0 )
	{
		uAxis.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 1.0, 0.0 );
		uAxis = c3ga::lc( c3ga::lc( uAxis, plane ), c3ga::reverse( plane ) );
		if( c3ga::norm( uAxis ) == 0.0 )
		{
			uAxis.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 0.0, 1.0 );
			uAxis = c3ga::lc( c3ga::lc( uAxis, plane ), c3ga::reverse( plane ) );
			if( c3ga::norm( uAxis ) == 0.0 )
				return false;
		}
	}

	uAxis = c3ga::unit( uAxis );
	vAxis = c3ga::gp( c3ga::op( normal, uAxis ), c3ga::I3 );

	c3ga::vectorE3GA vector = point - center;

	// This works, because the UV axes are orthonormal.
	double u = c3ga::lc( vector, uAxis ) / textureScale;
	double v = c3ga::lc( vector, vAxis ) / textureScale;

	textureCoordinates.set( c3ga::vectorE3GA::coord_e1_e2_e3, u, v, 0.0 );
	return true;
}
Beispiel #9
0
//===========================================================================
/*virtual*/ double DoubleTorus::EvaluatePartialZ( const c3ga::vectorE3GA& point ) const
{
	double z = point.get_e3();

	// f_z(x,y,z) = 2z
	return 2.0*z;
}
Beispiel #10
0
//=================================================================================
/*static*/ bool Node::ReadVectorE3GA( lua_State* L, Context& context, const std::string& name, c3ga::vectorE3GA& vector, const c3ga::vectorE3GA* defaultValue /*= 0*/ )
{
	bool success = false;
	int top = lua_gettop( L );

	try
	{
		if( defaultValue )
			vector = *defaultValue;
		else
			vector.set( c3ga::vectorE3GA::coord_e1_e2_e3, 0.0, 0.0, 0.0 );

		lua_getfield( L, -1, name.c_str() );
		if( lua_isnil( L, -1 ) || !lua_istable( L, -1 ) )
		{
			if( context.GetNodeReadingDisposition() == Context::NONEXISTENCE_OF_FIELD_IS_FATAL_ERROR )
				throw new Error( "ReadVectorE3GA failed to read \"%s\" as a table.", name.c_str() );
		}
		else
		{
			if( !ReadNumber( L, context, "x", vector.m_e1, 0.0 ) )
				throw new Error( "ReadVectorE3GA failed to read \"x\" from \"%s\".", name.c_str() );

			if( !ReadNumber( L, context, "y", vector.m_e2, 0.0 ) )
				throw new Error( "ReadVectorE3GA failed to read \"y\" from \"%s\".", name.c_str() );

			if( !ReadNumber( L, context, "z", vector.m_e3, 0.0 ) )
				throw new Error( "ReadVectorE3GA failed to read \"z\" from \"%s\".", name.c_str() );
		}

		// Pop the vector table.
		lua_pop( L, 1 );

		success = true;
	}
	catch( Error* error )
	{
		context.IssueError( error );
	}

	lua_settop( L, top );

	return success;
}
//=====================================================================================
/*static*/ void Sphere::RenderSphereTriangle(
					const c3ga::vectorE3GA& point0,
					const c3ga::vectorE3GA& point1,
					const c3ga::vectorE3GA& point2,
					const c3ga::evenVersor& evenVersor, int subDivisionCount )
{
	if( subDivisionCount == 0 )
	{
		c3ga::vectorE3GA normal0, normal1, normal2;

		normal0 = point0;
		normal1 = point1;
		normal2 = point2;

		c3ga::normalizedPoint cp0 = c3ga::normalizedPoint( c3ga::normalizedPoint::coord_e1_e2_e3_ni, point0.get_e1(), point0.get_e2(), point0.get_e3(), c3ga::norm2( point0 ) );
		c3ga::normalizedPoint cp1 = c3ga::normalizedPoint( c3ga::normalizedPoint::coord_e1_e2_e3_ni, point1.get_e1(), point1.get_e2(), point1.get_e3(), c3ga::norm2( point1 ) );
		c3ga::normalizedPoint cp2 = c3ga::normalizedPoint( c3ga::normalizedPoint::coord_e1_e2_e3_ni, point2.get_e1(), point2.get_e2(), point2.get_e3(), c3ga::norm2( point2 ) );
		
		// Each of these dual spheres has a radius of zero, so they're really points in space.
		// Notice that while the given versor is NOT a unit-versor, I am applying it here as
		// such, because doing so gives us the normalized dual sphere in the end.
		c3ga::dualSphere ds0 = c3ga::applyUnitVersor( evenVersor, cp0 );
		c3ga::dualSphere ds1 = c3ga::applyUnitVersor( evenVersor, cp1 );
		c3ga::dualSphere ds2 = c3ga::applyUnitVersor( evenVersor, cp2 );

		glNormal3d( normal0.get_e1(), normal0.get_e2(), normal0.get_e3() );
		glVertex3d( ds0.get_e1(), ds0.get_e2(), ds0.get_e3() );

		glNormal3d( normal1.get_e1(), normal1.get_e2(), normal1.get_e3() );
		glVertex3d( ds1.get_e1(), ds1.get_e2(), ds1.get_e3() );

		glNormal3d( normal2.get_e1(), normal2.get_e2(), normal2.get_e3() );
		glVertex3d( ds2.get_e1(), ds2.get_e2(), ds2.get_e3() );
	}
	else
	{
		c3ga::vectorE3GA point01, point12, point20;

		point01 = c3ga::unit( c3ga::add( c3ga::gp( point0, 0.5 ), c3ga::gp( point1, 0.5 ) ) );
		point12 = c3ga::unit( c3ga::add( c3ga::gp( point1, 0.5 ), c3ga::gp( point2, 0.5 ) ) );
		point20 = c3ga::unit( c3ga::add( c3ga::gp( point2, 0.5 ), c3ga::gp( point0, 0.5 ) ) );

		subDivisionCount--;
		RenderSphereTriangle( point0, point01, point20, evenVersor, subDivisionCount );
		RenderSphereTriangle( point1, point12, point01, evenVersor, subDivisionCount );
		RenderSphereTriangle( point2, point20, point12, evenVersor, subDivisionCount );
		RenderSphereTriangle( point01, point12, point20, evenVersor, subDivisionCount );
	}
}