Beispiel #1
0
float CylinderObject::hit_test(const Ray &ray, Vector &normal, const Point *max_pos, bool *inside)
{
	Ray inv_ray;
	inv_ray.origin = mul_point(inv_trans, ray.origin);
	inv_ray.direction = mul_vec(inv_trans, ray.direction);
	inv_ray.direction.normalize();

	Vector c_normal;
	bool c_inside;
	double t = FLT_MAX;

	// check collision with cylinder body
	double c_t = hit_cylinder(inv_ray, c_normal, c_inside);
	if(c_t > FLT_EPSILON && c_t < t)
	{
		t = c_t;
		normal = c_normal;
		if(inside)
			*inside = c_inside;
	}

	// check collision with bottom disk
	c_t = hit_disk(inv_ray, c_normal, Vector(0, -1, 0), Point(0, bottom, 0));
	if(c_t > FLT_EPSILON && c_t < t)
	{
		t = c_t;
		normal = c_normal;
		if(inside)
			*inside = false;
	}

	// check collision with top disk
	c_t = hit_disk(inv_ray, c_normal, Vector(0, 1, 0), Point(0, top, 0));
	if(c_t > FLT_EPSILON && c_t < t)
	{
		t = c_t;
		normal = c_normal;
		if(inside)
			*inside = false;
	}

	double max_t;
    if(max_pos)
        max_t = (max_pos->x - ray.origin.x) / ray.direction.x;
    else
        max_t = FLT_MAX;

	if(t < max_t)
	{
		normal = mul_vec(inv_trans, normal);
		normal.normalize();
		return t;
	}
	else
		return -1.0;
}
Beispiel #2
0
float SphereObject::hit_test(const Ray &ray, Vector &normal, const Point *max_pos, bool *inside)
{
	Ray inv_ray;
	inv_ray.origin = mul_point(inv_trans, ray.origin);
	inv_ray.direction = mul_vec(inv_trans, ray.direction);
	inv_ray.direction.normalize();

	Vector e = (inv_ray.origin - pos);
    double a = Vector::dot(inv_ray.direction, inv_ray.direction);
    double b = 2.0f * Vector::dot(inv_ray.direction, e);
    double c = Vector::dot(e, e) - std::pow(radius, 2);
    double delta = std::pow(b, 2) - 4*a*c;

	if(delta < FLT_EPSILON)
        return -1.0f;

    // Resolving the equation.
    delta = std::sqrt(delta);

    // Test both solutions.
    double t1 = (-b - delta) / (2.0f * a);
    double t2 = (-b + delta) / (2.0f * a);

    // Calculate the maximum t.
    double max_t;
    if(max_pos)
        max_t = (max_pos->x - inv_ray.origin.x) / inv_ray.direction.x;
    else
        max_t = FLT_MAX;

    // t1 is always smaller than t2 because it uses -b -discriminant.
    if(t1 > FLT_EPSILON && t1 < max_t)
	{
        if(inside)	*inside = false;
		Point intersection = inv_ray.origin + t1 * inv_ray.direction;
		normal = (intersection - pos).normalize();
		normal = mul_vec(inv_trans, normal);
		normal.normalize();
        return t1;
    }
    else if(t2 > FLT_EPSILON && t2 < max_t)
	{
        if(inside)	*inside = true;
		Point intersection = inv_ray.origin + t2* inv_ray.direction;
		normal = (intersection - pos).normalize();
		normal = mul_vec(inv_trans, normal);
		normal.normalize();
        return t2;
    }
    else
        return -1.0f;
}
Beispiel #3
0
float TorusObject::hit_test(const Ray &ray, Vector &normal, const Point *max_pos, bool *inside)
{
	Ray inv_ray;
	inv_ray.origin = mul_point(inv_trans, ray.origin);
	inv_ray.direction = mul_vec(inv_trans, ray.direction);
	inv_ray.direction.normalize();

	double x1 = inv_ray.origin.x; double y1 = inv_ray.origin.y; double z1 = inv_ray.origin.z;
	double d1 = inv_ray.direction.x; double d2 = inv_ray.direction.y; double d3 = inv_ray.direction.z;

	double coeffs[5];	// coefficient array
	double roots[4];	// solution array

	//define the coefficients
	double sum_d_sqrd = d1*d1 + d2*d2 + d3*d3;
	double e = x1*x1 + y1*y1 + z1*z1 - radius*radius - thickness*thickness;
	double f = x1*d1 + y1*d2 + z1*d3;
	double four_a_sqrd = 4.0 * radius*radius;

	coeffs[0] = e*e - four_a_sqrd * (thickness*thickness-y1*y1);	// constante term
	coeffs[1] = 4.0 * f * e + 2.0 * four_a_sqrd * y1 *d2;
	coeffs[2] = 2.0 * sum_d_sqrd * e + 4.0 * f * f + four_a_sqrd * d2 * d2;
	coeffs[3] = 4.0 * sum_d_sqrd * f;
	coeffs[4] = sum_d_sqrd * sum_d_sqrd;	// coefficient of t^4

	//fin the roots
	int num_real_roots = solveQuartic(coeffs, roots);

	bool intersected = false;
	double t = FLT_MAX;

	if ( num_real_roots == 0)	// ray misses the torus
		return -1.0;

	//find the smallest root greater than FLT_EPSILON, if any
	for( int j = 0; j < num_real_roots; j++)
	{
		if(roots[j] > FLT_EPSILON)
		{
			intersected = true;
			if(roots[j] < t)
				t = roots[j];
		}
	}

	double max_t;
    if(max_pos)
        max_t = (max_pos->x - ray.origin.x) / ray.direction.x;
    else
        max_t = FLT_MAX;

	if( t > max_t || !intersected)
		return -1.0;


	Point hit = inv_ray.origin + t*inv_ray.direction;
	normal = compute_normal(hit);
	normal = mul_vec(inv_trans, normal);
	normal.normalize();
	return t;
}
Beispiel #4
0
// FUNCTION : generate a public key
//
// Input : username, 
//         a4, a6 -> elliptic curve constants
//         xp, yp -> point's coordinate
//				 prime field
//         passphrase
// Output : file username.pkf which contains all
//          of those information
// 
// AUTHOR : TH <*****@*****.**>, Jan 2000
//
void gen_pubkey(const char* pkfilename, int blocksize)
{
	// declaration of variables
	char username[MAX];
	point P,H;
	bigmod a4,a6,xp,yp;
	bigint xdp,ydp,q;

	banner();
	cout<<"Before you can use encryption/decryption you must generate your public key.";
	cout<<"\nThe following process will guide you through generating your public key.";
	cout<<"\n\nTo achieve a cryptographically secure elliptic curve cryptosystem, you must ";
	cout<<"\nsupply a relatively big prime finite field (q), a good a, b";
	cout<<"\nfor elliptic curve equation and a point that lies on the curve.";

	//get EC parameters from user
	cout<<"\n\nGENERATE PUBLIC KEY\n";
	cout<<"-------------------";
	cout<<"\nPlease enter your user name : ";cin>>username;
		
	get_ecparm(a4,a6,xp,yp,q);
	
	// EC initialization
	P.init_curve(a4,a6);
	P.set_point(xp,yp);

	if (pkfilename==" ")
		pkfilename=PKFILENAME;

	// open public key file
	FILE* pkfile;
	pkfile=fopen(pkfilename,"a+");
	if(!pkfile)
	{
		cout<<"\nAZTECC ERROR : Error writing file ["<<pkfilename<<"]"<<endl;
		exit(1);
	}
	
	bigint d;
	get_passphrase(d,blocksize,username);
	
	// multiply the private key with EC point
	mul_point(H,d,P);
	
	// compute hash(d)
	char* sd=new char[MAX];
	bigint_to_string(d,sd);
	char* hash_d=new char[MAX];
	hash_d=MD5_hex_digest(sd);
	
	// convert the EC coordinate to string
	get_x(xdp,H);
	char* sxdp=new char[MAX];
	bigint_to_string(xdp,sxdp);
	get_y(ydp,H);
	char* sydp=new char[MAX];
	bigint_to_string(ydp,sydp);

	// convert a4, a6, xp, yp to string
	char* sa4=new char[MAX];
	bigmod_to_string(a4,sa4);
	char* sa6=new char[MAX];
	bigmod_to_string(a6,sa6);
	char* sxp=new char[MAX];
	bigmod_to_string(xp,sxp);
	char* syp=new char[MAX];
	bigmod_to_string(yp,syp);
	char* sq=new char[MAX];
	bigint_to_string(q,sq);
	
	// save all the info to public key file
   fputc('\n',pkfile);
	fprintf(pkfile,"%s#%s#%s#%s#%s#%s#%s#%s#%s",username,hash_d,sa4,sa6,sxp,syp,sxdp,sydp,sq);
	fclose(pkfile);
	cout<<"\nDone saving your public key to ["<<pkfilename<<"]"<<endl;

	//cleaning up
	delete[] sd;
	delete[] sxdp;
	delete[] sydp;
	delete[] sa4;
	delete[] sa6;
	delete[] sxp;
	delete[] syp;
	delete[] sq;
}