first commit
This commit is contained in:
442
CS4451/proj1/functions.cpp
Normal file
442
CS4451/proj1/functions.cpp
Normal file
@@ -0,0 +1,442 @@
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "defs.h"
|
||||
#include "functions.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void printObject(Vector v) {
|
||||
cerr << v.x << " " << v.y << " " << v.z << endl;
|
||||
}
|
||||
|
||||
void printObject(int i) {
|
||||
cerr << i << endl;
|
||||
}
|
||||
|
||||
void printObject(double f) {
|
||||
cerr << f << endl;
|
||||
}
|
||||
|
||||
void printObject(Light l) {
|
||||
cerr << l.center.x << " " << l.center.y << " " << l.center.z << " I: " << l.intensity << endl;
|
||||
}
|
||||
|
||||
|
||||
void printObject(MaterialAttributes attrib) {
|
||||
cerr << " k_dr, k_dg, k_db " << attrib.k_dr << " " << attrib.k_dg << " " << attrib.k_db << " "
|
||||
<< attrib.k_ar << " " << attrib.k_ag << " " << attrib.k_ab << " "
|
||||
<< attrib.k_s << " " << attrib.n_spec << endl;
|
||||
}
|
||||
|
||||
|
||||
void scanInput(MaterialAttributes &attrib, char* input) {
|
||||
char *pEnd;
|
||||
|
||||
cin.getline(input,81);
|
||||
|
||||
attrib.k_dr = strtod(input,&pEnd);
|
||||
attrib.k_dg = strtod(pEnd,&pEnd);
|
||||
attrib.k_db = strtod(pEnd,&pEnd);
|
||||
attrib.k_ar = strtod(pEnd,&pEnd);
|
||||
attrib.k_ag = strtod(pEnd,&pEnd);
|
||||
attrib.k_ab = strtod(pEnd,&pEnd);
|
||||
attrib.k_s = strtod(pEnd,&pEnd);
|
||||
attrib.n_spec = strtod(pEnd,NULL);
|
||||
}
|
||||
|
||||
void scanInput(vector<Primitive*> &primitives, int numPrimitives, char* input) {
|
||||
int i;
|
||||
char *pEnd;
|
||||
|
||||
for (i = 0; i < numPrimitives; i++) {
|
||||
cin.getline(input,81);
|
||||
|
||||
switch (input[0]) {
|
||||
case 'S': {
|
||||
Sphere* sphere = new Sphere();
|
||||
|
||||
cin.getline(input,81);
|
||||
sphere->center.x = strtod(input, &pEnd);
|
||||
sphere->center.y = strtod(pEnd, &pEnd);
|
||||
sphere->center.z = strtod(pEnd, &pEnd);
|
||||
sphere->radius = strtod(pEnd,NULL);
|
||||
|
||||
scanInput(sphere->attrib, input);
|
||||
|
||||
primitives.push_back(sphere);
|
||||
|
||||
//printObject(sphere->attrib);
|
||||
|
||||
#ifdef bDebug
|
||||
cout << "Got Sphere.." << endl;
|
||||
printObject(sphere->center);
|
||||
printObject(sphere->radius);
|
||||
printObject(sphere->attrib);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case 'T': {
|
||||
Triangle* triangle = new Triangle();
|
||||
|
||||
scanInput(triangle->a1,input);
|
||||
scanInput(triangle->a2,input);
|
||||
scanInput(triangle->a3,input);
|
||||
|
||||
scanInput(triangle->attrib, input);
|
||||
|
||||
primitives.push_back(triangle);
|
||||
|
||||
#ifdef bDebug
|
||||
cout << "Got Triangle.." << endl;
|
||||
printObject(triangle->a1);
|
||||
printObject(triangle->a2);
|
||||
printObject(triangle->a3);
|
||||
printObject(triangle->attrib);
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cout << "Error bad\n";
|
||||
break;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void scanInput(Vector &v, char* input) {
|
||||
char* pEnd;
|
||||
|
||||
cin.getline(input, 81);
|
||||
v.x = strtod(input,&pEnd);
|
||||
v.y = strtod(pEnd,&pEnd);
|
||||
v.z = strtod(pEnd,NULL);
|
||||
}
|
||||
void scanInput(Light &light, char* input) {
|
||||
char* pEnd;
|
||||
|
||||
cin.getline(input,81);
|
||||
light.center.x = strtod(input, &pEnd);
|
||||
light.center.y = strtod(pEnd, &pEnd);
|
||||
light.center.z = strtod(pEnd, &pEnd);
|
||||
light.intensity = strtod(pEnd, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Useful operator overloads */
|
||||
|
||||
/* ------------- <Vector> -------------*/
|
||||
|
||||
Vector Vector::operator+(Vector &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x + other.x;
|
||||
v.y = y + other.y;
|
||||
v.z = z + other.z;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector Vector::operator-(Vector &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x - other.x;
|
||||
v.y = y - other.y;
|
||||
v.z = z - other.z;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector Vector::operator*(Vector &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x * other.x;
|
||||
v.y = y * other.y;
|
||||
v.z = z * other.z;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector Vector::operator/(Vector &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x / other.x;
|
||||
v.y = y / other.y;
|
||||
v.z = z / other.z;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector Vector::operator*(int &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x * other;
|
||||
v.y = y * other;
|
||||
v.z = z * other;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector Vector::operator*(double &other) {
|
||||
Vector v;
|
||||
|
||||
v.x = x * other;
|
||||
v.y = y * other;
|
||||
v.z = z * other;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/* ------------ </Vector> ----------- */
|
||||
|
||||
/* ------------ <ostream> ----------- */
|
||||
|
||||
ostream &operator<< ( ostream &ofs, struct MaterialAttributes m ) {
|
||||
ofs << " Material Attributes: " << endl;
|
||||
ofs << " k_dr: " << m.k_dr << " k_dg: " << m.k_dg << " k_db: " << m.k_db << endl;
|
||||
ofs << " k_ar: " << m.k_ar << " k_ag: " << m.k_ag << " k_ab: " << m.k_ab << endl;
|
||||
ofs << " k_s: " << m.k_s << " n_spec: " << m.n_spec << endl;
|
||||
return ofs;
|
||||
}
|
||||
|
||||
ostream &operator<< ( ostream &ofs, Sphere s ) {
|
||||
ofs << "Sphere: " << endl;
|
||||
ofs << " Center: " << "(" << s.center.x << ","
|
||||
<< s.center.y << "," << s.center.z << endl;
|
||||
|
||||
return ofs;
|
||||
}
|
||||
|
||||
|
||||
ostream &operator<< ( ostream &ofs, Triangle t ) {
|
||||
ofs << "Triangle: " << endl;
|
||||
return ofs;
|
||||
}
|
||||
|
||||
|
||||
/* ------------ </ostream> ------------- */
|
||||
|
||||
|
||||
/* ----------- Primitive stuff ----------- */
|
||||
|
||||
double length(Vector p) {
|
||||
double toRet;
|
||||
|
||||
toRet = pow(p.x,2)+pow(p.y,2)+pow(p.z,2);
|
||||
toRet = sqrt(toRet);
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
double dot(Vector v1, Vector v2) {
|
||||
double toRet;
|
||||
|
||||
toRet = (v1.x*v2.x) + (v1.y*v2.y) + (v1.z*v2.z);
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
inline double discriminant(double A, double B, double C) {
|
||||
return ((B*B) - (4*A*C));
|
||||
}
|
||||
|
||||
void Sphere::printName() {
|
||||
cout << "This is of type Sphere" << endl;
|
||||
}
|
||||
|
||||
bool Sphere::intersectsWithSelf(Point p, Light l, Point v) {
|
||||
Vector cp, pl;
|
||||
|
||||
cp = p - this->center;
|
||||
pl = l.center - p;
|
||||
|
||||
if (dot(cp,pl) < 0) {
|
||||
return true;
|
||||
} else return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
double Sphere::intersectsWith(Ray ray) {
|
||||
|
||||
double C = pow(length(ray.origin - this->center),2) - pow(this->radius,2);
|
||||
double B;
|
||||
double A;
|
||||
double discrim;
|
||||
|
||||
A = pow(length(ray.direction),2);
|
||||
B = 2*dot(ray.direction,ray.origin - this->center);
|
||||
|
||||
discrim = discriminant(A,B,C);
|
||||
|
||||
if (discrim < 0) {
|
||||
return -1;
|
||||
} else if (discrim > 0) {
|
||||
double a, b;
|
||||
a = ((-1*B)+sqrt(discrim))/(2*A);
|
||||
b = ((-1*B)-sqrt(discrim))/(2*A);
|
||||
if (b>=0) return b;
|
||||
else return a;
|
||||
} else { //discrim==0
|
||||
return ((-1*B) / (2*A));
|
||||
}
|
||||
}
|
||||
|
||||
void Triangle::printName() {
|
||||
cout << "This is of type Triangle" << endl;
|
||||
}
|
||||
|
||||
inline Vector cross(Vector a, Vector b) {
|
||||
Vector toRet;
|
||||
|
||||
toRet.x = ( (a.y*b.z) - (a.z*b.y) ); //i
|
||||
toRet.y = ( (a.z*b.x) - (a.x*b.z) ); //j
|
||||
toRet.z = ( (a.x*b.y) - (a.y*b.x) ); //k
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
inline char bestCoord(Vector v1) {
|
||||
//Lazy fast method
|
||||
if (abs((int)v1.x) > abs((int)v1.y)) {
|
||||
if (abs((int)v1.x) > abs((int)v1.z)) {
|
||||
return 'x';
|
||||
} else {
|
||||
return 'z';
|
||||
}
|
||||
} else {
|
||||
if (abs((int)v1.y) > abs((int)v1.z)) {
|
||||
return 'y';
|
||||
} else {
|
||||
return 'z';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector Sphere::normal(Point p, Light l) {
|
||||
Vector normal;
|
||||
|
||||
normal = p-this->center;
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
Vector Triangle::normal(Point p, Light l) {
|
||||
Vector normal, a1a2, a1a3, pl;
|
||||
|
||||
a1a2 = this->a2 - this->a1;
|
||||
a1a3 = this->a3 - this->a1;
|
||||
|
||||
normal = cross(a1a2,a1a3);
|
||||
|
||||
pl = l.center - p;
|
||||
|
||||
if (dot(normal,pl) < 0) {
|
||||
//normal = normal * ((double)-1.0);
|
||||
//STUPID OPERATOR OVERLOADING DOESNT WORK
|
||||
normal.x = normal.x * -1;
|
||||
normal.y = normal.y * -1;
|
||||
normal.z = normal.z * -1;
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
Vector Triangle::normal(Point p) {
|
||||
Vector normal, a1a2, a1a3, pl;
|
||||
|
||||
a1a2 = this->a2 - this->a1;
|
||||
a1a3 = this->a3 - this->a1;
|
||||
|
||||
normal = cross(a1a2,a1a3);
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
bool Triangle::intersectsWithSelf(Point p, Light l, Point v) {
|
||||
Vector normal = this->normal(p,l), pv;
|
||||
|
||||
pv = v - p;
|
||||
|
||||
if (dot(normal,pv) < 0) {
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
double Triangle::intersectsWith(Ray ray) {
|
||||
Vector normal = this->normal(this->a1);
|
||||
|
||||
//calculate t
|
||||
double top = dot(ray.origin - a1,normal);
|
||||
double bottom = dot(ray.direction, normal);
|
||||
double t = -1.0 * (top/bottom);
|
||||
|
||||
if (t < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
Point p = (ray.direction * t) + ray.origin;
|
||||
|
||||
Vector pa1 = this->a1 - p;
|
||||
Vector pa2 = this->a2 - p;
|
||||
Vector pa3 = this->a3 - p;
|
||||
|
||||
Vector pa1pa2 = cross(pa1,pa2);
|
||||
Vector pa2pa3 = cross(pa2,pa3);
|
||||
Vector pa3pa1 = cross(pa3,pa1);
|
||||
|
||||
char best = bestCoord(pa1pa2);
|
||||
|
||||
switch (best) {
|
||||
case 'x':
|
||||
if ((pa1pa2.x > 0 && pa2pa3.x > 0 && pa3pa1.x > 0)
|
||||
|| (pa1pa2.x < 0 && pa2pa3.x < 0 && pa3pa1.x < 0))
|
||||
{
|
||||
return t;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case 'y':
|
||||
if ((pa1pa2.y > 0 && pa2pa3.y > 0 && pa3pa1.y > 0)
|
||||
|| (pa1pa2.y < 0 && pa2pa3.y < 0 && pa3pa1.y < 0))
|
||||
{
|
||||
return t;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case 'z':
|
||||
if ((pa1pa2.z > 0 && pa2pa3.z > 0 && pa3pa1.z > 0)
|
||||
|| (pa1pa2.z < 0 && pa2pa3.z < 0 && pa3pa1.z < 0))
|
||||
{
|
||||
return t;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
cerr << "How?";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user