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; }
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; }