Skip navigation

Here is my ray sphere intersection code. Pay special attention to the __6__ possible results for the ray’s situation wrt the sphere.

bool Sphere::intersectExact( const Ray& ray, Intersection* intn )
{
  // an important override

  //If E is the starting point of the ray,
  //.. and L is the end point of the ray,
  //.. and C is the center of sphere you're testing against
  //.. and r is the radius of that sphere

  // Compute:
  //    d = L - E ; // Direction vector of ray, from start to end
  //    f = E - C ; // Vector from center sphere to ray start
  const Vector &d = ray.direction ;
  Vector f = ray.startPos - this->pos ;

  real a = d • d ;  // a is nonnegative, this is actually always 1.0
  real b = 2*(f • d) ;
  real c = f • f - radius*radius ;

  real discriminant = b*b-4*a*c;
  if( discriminant < 0 )
  {
    return false ;  // no intersections.
    // the geometric meaning of this is
    // the ray totally misses the sphere.
  }
  else
  {
    // ray didn't totally miss sphere,
    // so there is a solution to
    // the equation.

    discriminant = sqrt( discriminant );
    // just t1 here implies t1 VALID (ie 0 ≤ t1 ≤ len)
    // 3x HIT cases:
    //       -o->       --|-->  |            |  --|->
    // Impale(t1,t2), Poke(t1,t2>len), ExitWound(t1<0, t2), 
    
    // 3x MISS cases:
    //       ->  o                     o ->              
    // FallShort (t1>len,t2>len), Past (t1<0,t2<0)
    
    // | -> |
    // CompletelyInside(t1<0, t2>len)

    // You might consider CompletelyInside a HIT, but I consider it a miss here.
    // t1 is always the smaller value, because BOTH discriminant and
    // a are nonnegative.
    real t1 = (-b - discriminant)/(2*a);
    real t2 = (-b + discriminant)/(2*a);

    // Just purely sphere info
    if( BetweenIn(t1,0,ray.length) )
    {
      // t1 is the intersection, and its closer
      // Impale, Poke
      Vector p = ray.at( t1 ) ;
      if( intn )  *intn = Intersection( p, getNormalAt( p ), this ) ;
      return true ;
    }

    // here t1 didn't intersect so we are either started
    // inside the sphere or too 
    if( BetweenIn( t2,0,ray.length ) )
    {
      // ExitWound
      Vector p = ray.at( t2 ) ;

      // We invert the normal because you are inside the sphere.
      if( intn )  *intn = Intersection( p, -getNormalAt( p ), this ) ;
      return true ;
    }

    return false ; // no intn: FallShort, Past, CompletelyInside
  }
}
Advertisements

One Comment

  1. エクスプローラーI (Explorer I) 1953年発売。三針式、日付なし、黒文字盤の同社のスポーツモデルのさきがけとなった製品。初期型はRef.6150。その後Ref.1016、Cal.1560、ハック機能付きのRef.1016、Cal.1570に移行し1989年に一旦製造中止となったが、翌1990年にRef.14270、Cal.3000として文字盤のデザインを一新して再発売され、2001年よりRef.114270、Cal.3130に移行し、2010年に現行モデルであるRef.214270、Cal.3132にモデルチェンジされた。直径39mmで、クロノメーター認定取得。エドモンド?ヒラリーのエベレスト初登頂時に用いられたとする資料が多いが、実際にその時使用されていたかどうかは定かではない。ヒラリーはその後広告に使われ、このモデルも探検家用モデルとして有名になった。後述する1960年頃の一部のモデルを除き蛍光塗料によって針や文字盤表示が塗られており、暗いところでも時間の確認が容易である。通常のモデルと同じデザインと素材でありながらノンクロノメーターを一回り小さなボーイズサイズケースに収めたモデルも極限られた市場向けに少数販売された。
    ルイヴィトン財布 アメリア ヴォルフ http://www.bagkakaku.com/hermes_bag.html


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: