예제 #1
0
파일: bspline.cpp 프로젝트: Gneogeo/Parking
void BSplineSurf::recalcCoords(float ds,float dt)
{
	float s,t;
	float out[3];
	int ns,nt;
	
	myVector<float> sv;
	myVector<float> tv;
	for (s=U[0]; s<U[1]; s+=ds) {
		sv.append(s);
	}
	sv.append(U[1]);

	for (t=V[0]; t<V[1]; t+=dt) {
		tv.append(t);
	}
	tv.append(V[1]);
	
	total_coords=sv.length()*tv.length();
	coords=(float(*)[3])malloc(total_coords*sizeof(float[3]));

	total_coords=0;
	for (ns=0; ns<sv.length(); ns++) {
		s=sv.at(ns);
		for (nt=0; nt<tv.length(); nt++) {
			t=tv.at(nt);	
			getParamPoint(s,t,coords[total_coords]);
			total_coords++;
		}
	}
	myVector<int> N;
	int striplen;
	for (ns=0; ns<sv.length()-1; ns++) {
		N.append(0);
		striplen=N.length()-1;
		for (nt=0; nt<tv.length(); nt++) {
			N.append(nt+tv.length()*ns);
			N.append(nt+ tv.length()*(ns+1));
		}
		N.at(striplen)=tv.length()*2;
	}
	N.append(0);
	
	free(strip);

	strip=(int*)malloc(N.length()*sizeof(int));
	memcpy(strip,N.getData(),N.length()*sizeof(int));


	free(normals);
	normals=(float(*)[3])calloc(total_coords,sizeof(float[3]));

	
	int *ar,totta,k;

	ar=strip;
	while (ar[0]) {
		totta=ar[0]; ar++;
		for (k=2; k<totta; k++) {
			float g1[3],g2[3],g3[3];
			vec_diff(g1,coords[ ar[k-2] ],coords[ ar[k-1] ]);
			vec_diff(g2,coords[ ar[k-1] ],coords[ ar[k] ]);
			vec_cross_product(g3,g1,g2);
			vec_normalize(g3);
			if (k&1) {
				vec_flip(g3,g3);
			}
			vec_sum(normals[ ar[k] ],normals[ ar[k] ],g3);
			if (k==2) {
				vec_sum(normals[ ar[0] ],normals[ ar[0] ],g3);
				vec_sum(normals[ ar[1] ],normals[ ar[1] ],g3);
			}
		}

		ar+=totta;
	}
	for (k=0; k<total_coords; k++) {
		vec_normalize(normals[k]);
	}

}
예제 #2
0
static intersectionT findSphereIntersection(rayT* ray, surfaceT* surface) {
    intersectionT   intersection = { 0 };
    sphereSurfaceT* sphere       = surface->data;

    intersection.surface = surface;
    intersection.ray     = *ray;

    // Sphere equation: x^2+y^2+z^2=r^2
    // Or, with a position: (x-c_x)^2+(y-c_y)^2+(z-c_z)^2 = r^2
    //
    // Intersecting it with a parametric line:
    //
    //   (o_x+td_x-c_x)^2+(o_y+td_y-c_y)^2+(o_z+td_z-c_z)^2 = r^2
    //
    // Solving for t:
    //   (o_x+td_x-c_x)^2+(o_y+td_y-c_y)^2+(o_z+td_z-c_z)^2-r^2 = 0
    //
    //   ((o_x-c_x)+td_x)^2+((o_y-c_y)+td_y)^2+((o_z-c_z)+td_z)^2-r^2 = 0
    //
    //   (o_x-c_x)^2+2*(o_x-c_x)*t*d_x+t^2d_x^2 +
    //   (o_y-c_y)^2+2*(o_y-c_y)*t*d_y+t^2d_y^2 +
    //   (o_z-c_z)^2+2*(o_z-c_z)*t*d_y+t^2d_y^2 - r^2 = 0
    //
    //   (o_x-c_x)^2+(o_y-c_y)^2+(o_z-c_z)^2 +
    //   2t((o_x-c_x)*d_x+(o_y-c_y)*d_y+(o_z-c_z)*d_y) +
    //   t^2(d_x^2+d_y^2+d_z^2) - r^2 = 0
    //
    // This gives us a quadratic equation of the form ax^2+bx+c=0:
    //
    //   a = (d_x^2+d_y^2+d_z^2)
    //   b = 2((o_x-c_x)*d_x+(o_y-c_y)*d_y+(o_z-c_z)*d_y)
    //   c = (o_x-c_x)^2+(o_y-c_y)^2+(o_z-c_z)^2-r
    //
    //   t^2+(b/a)t+(c/a) = 0
    //
    // Completing the square:
    //
    //   t^2+(b/a)t = -c/a
    //   (t+0.5(b/a))^2 = -c/a+0.25(b/a)^2
    //   t+0.5(b/a) = +-sqrt(-c/a+0.25(b/a)^2)
    //   t = +-sqrt(-c/a+0.25(b/a)^2) - 0.5(b/a)

    float a = square(ray->direction.x)
            + square(ray->direction.y)
            + square(ray->direction.z);

    float b = 2.0f * ((ray->origin.x - sphere->center.x) * ray->direction.x +
                      (ray->origin.y - sphere->center.y) * ray->direction.y +
                      (ray->origin.z - sphere->center.z) * ray->direction.z);

    float c = square(ray->origin.x - sphere->center.x) +
              square(ray->origin.y - sphere->center.y) +
              square(ray->origin.z - sphere->center.z) -
              square(sphere->radius);

    float d = -c/a + 0.25f*square(b/a);

    if (d >= 0.0f) {
        float t0     = -sqrtf(d) - 0.5*(b/a);
        float t1     =  sqrtf(d) - 0.5*(b/a);
        float t      =  t0;
        bool  inside =  false;

        if (t <= 0.0f) {
            // We're inside the sphere, or the sphere is behind us.
            t      = t1;
            inside = true;
        }

        intersection.t        = t;
        intersection.position = (vec3) { ray->origin.x + t*ray->direction.x,
                                         ray->origin.y + t*ray->direction.y,
                                         ray->origin.z + t*ray->direction.z };
        intersection.normal   = intersection.position;
        vec_sub(&intersection.normal, &sphere->center, &intersection.normal);
        vec_normalize(&intersection.normal, &intersection.normal);

        if (inside)
            vec_flip(&intersection.normal, &intersection.normal);
    }

    return (intersection);
}