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; }
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; }
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; }
// 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; }