void Eigenvalues(const Matrix2& A,Complex& lambda1,Complex& lambda2)
{
  Real trace=A.trace();
  Real det=A.determinant();
  Complex temp2 = Sqr(trace) - 4.0*det;
  Complex temp = Sqrt(temp2);
  lambda1 = 0.5*(Complex(trace) + temp);
  lambda2 = 0.5*(Complex(trace) - temp);
}
bool Eigenvalues(const Matrix2& A,Real& lambda1,Real& lambda2)
{
  Real trace=A.trace();
  Real det=A.determinant();
  Real temp2 = Sqr(trace) - 4.0*det;
  if(temp2 < 0) return false;
  Real temp=Sqrt(temp2);
  lambda1 = 0.5*(trace + temp);
  lambda2 = 0.5*(trace - temp);
  return true;
}
Exemple #3
0
bool Segment2D::intersects(const Vector2& A,const Vector2& B,Vector2& p) const
{
  //find (u,v) s.t. a+u(b-a) = A+v(B-A)
  //=> (b-a | A-B)*(u,v)^T = (A-a)
  Matrix2 M;
  Vector2 res,uv;
  M.setCol1(b-a);
  M.setCol2(A-B);
  res = A-a;
  if(Math::FuzzyZero(M.determinant())) {
    //they're parallel
    Vector2 t = b-a;
    Vector2 n; n.setPerpendicular(t);
    Real D = dot(n,A);
    Real d = dot(n,a);
    if(Math::FuzzyEquals(d,D)) {  //they overlap
      ClosedInterval U,u;
      u.a = 0;
      u.b = t.normSquared();
      U.a = dot(t,A-a);
      U.b = dot(t,B-a);
      if(U.intersects(u)) {
	ClosedInterval i;
	i.setIntersection(u,U);
	Real param=0.5*(i.a+i.b);
	p = a + t*(param/u.b);
	return true;
      }
    }
    return false;
  }
  M.inplaceInverse();
  M.mul(res,uv);
  if(uv.x>=Zero && uv.x<=One &&
     uv.y>=Zero && uv.y<=One) {
    interpolate(a,b,uv.x,p);
    Vector2 temp;
    interpolate(A,B,uv.y,temp);
    if(temp.distance(p) > 1e-3) {
      cout<<"Error: intersection points are too far away "<<endl;
      cout<<A<<" -> "<<B<<endl;
      cout<<a<<" -> "<<b<<endl;
      cout<<"u,v "<<uv<<endl;
      cout<<"inverse basis "<<endl<<M<<endl;
      cout<<"p1,p2 "<<p<<", "<<temp<<endl;
      abort();
    }
    return true;
  }
  /*
  if(intersects(a,b)) {
    if(Math::FuzzyZero(uv.x)) { p=a; return true; }
    if(Math::FuzzyEquals(uv.x,One)) { p=b; return true; }
    if(Math::FuzzyZero(uv.y)) { p=a; return true; }
    if(Math::FuzzyEquals(uv.y,One)) { p=b; return true; }
    cout<<"Error! segment is supposed to intersect, but we don't have that in the basis!"<<endl;
    cout<<A<<" -> "<<B<<endl;
    cout<<a<<" -> "<<b<<endl;
    cout<<"u,v "<<uv<<endl;
    cout<<"inverse basis "<<endl<<M<<endl;
    abort();
  }
  */
  return false;
}