Example #1
0
Vector getRefractedRay(float initial_refraction, Spheres *sph, Vector surface_norm, Vector light_ray)
{
	float refraction_index = sph->refraction_index;
	float n = initial_refraction/refraction_index;

	Vector refract_ray;
	//n = .9;
	//light_ray.x = 0.707107;
	//light_ray.y = -0.707107;
	//light_ray.z = 0;
	//surface_norm.x = 0;
	//surface_norm.y = 1;
	//surface_norm.z = 0;

	float cosTheta1 = vec_dot(surface_norm, vec_scale(light_ray,-1));
	float cosTheta2 = sqrt(1.0f-pow(n,2)*(1-(cosTheta1*cosTheta1)));
	
	Vector a = vec_scale(light_ray, n);
	Vector b = vec_scale(surface_norm, n*cosTheta1 - cosTheta2);

	if(cosTheta1 > 0.0f)
	{
		refract_ray = vec_plus(vec_scale(light_ray,n), vec_scale(surface_norm, n*cosTheta1-cosTheta2));
	}
	else
	{
		refract_ray = vec_minus(vec_scale(light_ray,n), vec_scale(surface_norm, n*cosTheta1-cosTheta2));
	}
	return refract_ray;
}
Example #2
0
Vector getReflectedRay(Vector surface_norm, Vector light_ray)
{
	float cosTheta1 = vec_dot(surface_norm, vec_scale(light_ray,-1));
	Vector reflect_ray = vec_plus(light_ray, vec_scale(surface_norm, 2*cosTheta1));
	return reflect_ray;

}
Example #3
0
// This function is adapted from geom.cpp in ODE, which
// is copyright Russell Smith.
// given two line segments A and B with endpoints a1-a2 and b1-b2, return the
// points on A and B that are closest to each other (in cp1 and cp2).
// in the case of parallel lines where there are multiple solutions, a
// solution involving the endpoint of at least one line will be returned.
// this will work correctly for zero length lines, e.g. if a1==a2 and/or
// b1==b2.
//
// the algorithm works by applying the voronoi clipping rule to the features
// of the line segments. the three features of each line segment are the two
// endpoints and the line between them. the voronoi clipping rule states that,
// for feature X on line A and feature Y on line B, the closest points PA and
// PB between X and Y are globally the closest points if PA is in V(Y) and
// PB is in V(X), where V(X) is the voronoi region of X.
void line_segment_closest_points(double a1[3], double a2[3],
				 double b1[3], double b2[3],
				 double cp1[3], double cp2[3])
{
  double la, lb, k, da1, da2, da3, da4, db1, db2, db3, db4, det;
  double a1a2[3], b1b2[3], a1b1[3], a1b2[3], a2b1[3], a2b2[3], n[3], tmp[3];

  // check vertex-vertex features

  vec_subt(a1a2, a2, a1);
  vec_subt(b1b2, b2, b1);
  vec_subt(a1b1, b1, a1);

  da1 = vec_dot(a1a2, a1b1);
  db1 = vec_dot(b1b2, a1b1);

  if ((da1 <= 0) && (db1 >= 0)) {
    vec_copy(cp1, a1);
    vec_copy(cp2, b1);
    return;
  }

  vec_subt(a1b2, b2, a1);
  da2 = vec_dot(a1a2, a1b2);
  db2 = vec_dot(b1b2,a1b2);
  if ((da2 <= 0) && (db2 <= 0)) {
    vec_copy(cp1, a1);
    vec_copy(cp2, b2);
    return;
  }

  vec_subt(a2b1, b1, a2);
  da3 = vec_dot(a1a2, a2b1);
  db3 = vec_dot(b1b2, a2b1);
  if ((da3 >= 0) && (db3 >= 0)) {
    vec_copy(cp1, a2);
    vec_copy(cp2, b1);
    return;
  }

  vec_subt(a2b2, b2, a2);
  da4 = vec_dot(a1a2, a2b2);
  db4 = vec_dot(b1b2, a2b2);
  if ((da4 >= 0) && (db4 <= 0)) {
    vec_copy(cp1, a2);
    vec_copy(cp2, b2);
    return;
  }

  // check edge-vertex features.
  // if one or both of the lines has zero length, we will never get to here,
  // so we do not have to worry about the following divisions by zero.

  la = vec_dot(a1a2, a1a2);
  if ((da1 >= 0) && (da3 <= 0.0)) {
    k = da1 / la;
    vsv_mult(tmp, k, a1a2);
    vec_subt(n, a1b1, tmp);

    if (vec_dot(b1b2, n) >= 0.0) {
      vec_plus(cp1, a1, tmp);
      vec_copy(cp2, b1);
      return;
    }
  }

  if ((da2 >= 0) && (da4 <= 0)) {
    k = da2 / la;
    vsv_mult(tmp, k, a1a2);
    vec_subt(n, a1b2, tmp);
    if (vec_dot(b1b2, n) <= 0.0) {
      vec_plus(cp1, a1, tmp);
      vec_copy(cp2, b2);
      return;
    }
  }

  lb = vec_dot(b1b2, b1b2);
  if ((db1 <= 0) && (db2 >= 0.0)) {
    k = -db1 / lb;
    vsv_mult(tmp, k, b1b2);
    vec_neg(a1b1);
    vec_subt(n, a1b1, tmp);
    if (vec_dot(a1a2, n) >= 0.0) {
      vec_copy(cp1,a1);
      vec_plus(cp2, b1, tmp);
      return;
    }
  }

  if ((db3 <= 0.0) && (db4 >= 0.0)) {
    k = -db3 / lb;
    vsv_mult(tmp, k, b1b2);
    vec_neg(a2b1);
    vec_subt(n, a2b1, tmp);
    if (vec_dot(a1a2, n) <= 0.0) {
      vec_copy(cp1,a2);
      vec_plus(cp2, b1, tmp);
      return;
    }
  }

  // it must be edge-edge

  k = vec_dot(a1a2, b1b2);
  det = la*lb - k*k;
  if (det <= 0.0) {
    // this should never happen, but just in case...
    vec_copy(cp1, a1);
    vec_copy(cp2, b1);
    return;
  }

  det = 1.0/det;
  double alpha = (lb*da1 -  k*db1) * det;
  double beta  = ( k*da1 - la*db1) * det;

  vs_mult(a1a2, alpha);
  vec_plus(cp1, a1, a1a2);

  vs_mult(b1b2, beta);
  vec_plus(cp2, b1, b1b2);
}
Example #4
0
double line_segment_distance(double seg1_a[3], double seg1_b[3],
			   double seg2_a[3], double seg2_b[3])
{
  double sc, sd, sn, tc, td, tn;
  double uu, uv, vv, uw, vw, det;
  double u[3], v[3], w[3];

  vec_subt(u, seg1_b, seg1_a);
  vec_subt(v, seg2_b, seg2_a);
  vec_subt(w, seg1_a, seg2_a);

  uu = vec_dot(u, u);
  uv = vec_dot(u, v);
  vv = vec_dot(v, v);
  uw = vec_dot(u, w);
  vw = vec_dot(v, w);
  
  det = uu*vv - sqr(uv);
  sd = det;
  td = det;

  if (det < ALMOST_ZERO) {
    sn = 0.0;
    sd = 1.0;
    tn = vw;
    td = vv;
  } else {
    sn = uv*vw - vv*uw;
    tn = uu*vw - uv*uw;
    if (sn < 0.0) {
      sn = 0.0;
      tn = vw;
      td = vv;
    } else if (sn > sd) {
      sn = sd;
      tn = vw + uv;
      td = vv;
    }
  }

  if (tn < 0.0) {
    tn = 0.0;
    if (-uw < 0.0) {
      sn = 0.0;
    } else if (-uw > uu) {
      sn = sd;
    } else {
      sn = -uw;
      sd = uu;
    }
  } else if (tn > td) {
    tn = td;
    if (uv-uw < 0.0) {
      sn = 0.0;
    } else if (uv-uw > uu) {
      sn = sd;
    } else {
      sn = uv-uw;
      sd = uu;
    }
  }

  sc = (absv(sn) < ALMOST_ZERO ? 0.0 : sn / sd);
  tc = (absv(tn) < ALMOST_ZERO ? 0.0 : tn / td);

  vs_mult(u, sc);
  vs_mult(v, tc);
  vec_plus(w, w, u);
  vec_subt(w, w, v);

  return vec_dot(w, w);
}