Ejemplo n.º 1
0
void Mobius::grandmasRecipie(complex<double> ta, complex<double> tb, Matrix &ma, Matrix &mb) {


    complex<double> tab;
    complex<double> z0;

    // first solve the quadratic equation x^2 - ta.tb.x + ta^2 + tb^2 = 0
 // using -b +- sqrt(b^2 - 4ac) / 2a   a = 1, b = -ta.tb and c = ta^2 + tb^2
 // set tab to x

    tab = solveQuadratic(complex<double>(1,0), complex<double>(-1, 0) * ta * tb, (ta * ta) + (tb * tb));


  // z0 is another big calc

    z0 = ((tab - r_2) * tb) / ((tb * tab) - (r_2 * ta) + (i_2 * tab));


  //  finally generate the two generator matrices
    ma.setMatrix(ta / r_2,   ((ta*tab) - (r_2 * tb) + i_4) / (((r_2*tab) + r_4) * z0),
                 (((ta*tab) - (r_2 * tb) - i_4) * z0) / ((r_2*tab) - r_4), ta / r_2);


    mb.setMatrix((tb - i_2)/ r_2, tb / r_2, tb / r_2, (tb + i_2)/ r_2);

    return;
}
Ejemplo n.º 2
0
complex<double> Mobius::fixedPoint(Matrix m) {

    // the fixed points are found by solving the quadratic formula
    // cz^2 + (d - a)z - b
    return  solveQuadratic(m._c, (m._d-m._a), -m._b);

}
Ejemplo n.º 3
0
//(r⃗ ·r⃗)t2 +2r⃗ ·(r⃗o −cen⃗ter)t+(r⃗o −cen⃗ter)·(r⃗o −cen⃗ter)−R2 =0
bool Sphere::intersect(const Ray& r, const float tmin, float &t_max){
	float t0, t1; // solutions for t if the ray intersects

    // analytic solution
	Vector3D L = r.getOrigin() - center;
	// std::cout << "L " << L << std::endl;
	float a = r.getDir().dot(r.getDir());
	// std::cout << "a " << a << std::endl;
	float b = 2 * r.getDir().dot(L);
	// std::cout << "b " << b << std::endl;
	float c = L.dot(L) - (radius * radius ) ;
	// std::cout << "c " << c << std::endl;

	if (!solveQuadratic(a, b, c, t0, t1)) return false;

	if (t0 > t1) std::swap(t0, t1);
	if (t0 < 0) {
	    t0 = t1; // if t0 is negative, let's use t1 instead
	    if (t0 < 0) 
	    	return false; // both t0 and t1 are negative
	}
	t_max = t0;

	return true;

}
Ejemplo n.º 4
0
// degree == 3
std::vector<double> Polynomial::solveCubic(){
	if(coeffs[3] == 0){
		return solveQuadratic();
	}
	if(coeffs[1] == 0 && coeffs[2] == 0){
		return std::vector<double>(1,cbrt(-coeffs[0]/coeffs[3]));
	}
	if(coeffs[0] == 0){
		std::vector<double> temp;
		temp.push_back(coeffs[1]),temp.push_back(coeffs[2]);
		temp.push_back(coeffs[3]);
		Polynomial p(temp,2);
		std::vector<double> retVal = p.solveQuadratic();
		retVal.push_back(0);
		return retVal;
	}
	double firstRoot = this->newtonRaphson(1.0);
	Polynomial quad = this->syntheticDiv(firstRoot);
	std::vector<double> temp = quad.solveQuadratic();
	std::vector<double> retVal;
	retVal.push_back(temp[0]);
	retVal.push_back(temp[1]);
	retVal.push_back(firstRoot);
	return retVal;
}
Ejemplo n.º 5
0
double distanceMarcher::updatePointOrderOne(int i)
{
    double a,b,c;
    a=b=c=0;
    int naddr=0;
    for (int dim=0; dim<dim_; dim++)
    {
        double value = maxDouble;
        for (int j=-1; j<2; j+=2) // each direction
        {
            naddr = _getN(i,dim,j,Mask);
            if (naddr!=-1 && flag_[naddr]==Frozen)// && (!ignore_mask_ || !ignore_mask_[naddr]))
            {
                if (distance_[naddr]<value)
                {
                    value = distance_[naddr];
                }
            }
        }
        if (value<maxDouble)
        {
            // printf("yay, %f, %f\n", value, maxDouble);
            a+=idx2_[dim];
            b-=idx2_[dim]*2*value;
            c+=idx2_[dim]*pow(value,2);
        }
    }
    return solveQuadratic(i,a,b,c);
}
Ejemplo n.º 6
0
bool Sphere::intersect(const Ray& ray, Intersection& inter)
{
    Vector temp = ray.o - center;
    float a = dot(ray.d, ray.d);
    float b = 2 * dot(temp, ray.d);
    float c = dot(temp, temp) - radius * radius;

    float t1, t2;

    if (solveQuadratic(a, b, c, &t1, &t2)) {
        float t = std::min(t1, t2);

        if (t > EPSILON && t < inter.t) {
            ray.rayEpsilon = 1e-3f * t;
            inter.normal = (temp + ray.d * t) / radius;
            inter.ray = ray;
            inter.t = t;
            inter.hitPoint = ray(t);
            inter.hitObject = true;
            inter.material = getMaterial();

            return true;
        }
    }

    return false;
}
Ejemplo n.º 7
0
std::vector<std::complex<double> >
PolyBase::calcRoots(const double epsilon)
  /**
    Calculate all the roots of the polynominal.
    Uses the GSL which uses a Hessian reduction of the 
    characteristic compainion matrix.
    \f[ A= \left( -a_{m-1}/a_m -a_{m-2}/a_m ... -a_0/a_m \right) \f]
    where the matrix component below A is the Indenty.
    However, GSL requires that the input coefficient is a_m == 1,
    hence the call to this->compress().
    @param epsilon :: tolerance factor (-ve to use default) 
    @return roots (not sorted/uniqued)
  */
{
  compress(epsilon);
  std::vector<std::complex<double> > Out(iDegree);
  // Zero State:
  if (iDegree==0)
    return Out;
  
  // x+a_0 =0 
  if (iDegree==1)
    {
      Out[0]=std::complex<double>(-afCoeff[0]);
      return Out;
    }
  // x^2+a_1 x+c = 0
  if (iDegree==2)
    {
      solveQuadratic(Out[0],Out[1]);
      return Out;
    }

  // x^3+a_2 x^2+ a_1 x+c=0
  if (iDegree==2)
    {
      solveCubic(Out[0],Out[1],Out[2]);
      return Out;
    }
  // THERE IS A QUARTIC / QUINTIC Solution availiable but...
  // WS contains the the hessian matrix if required (eigenvalues/vectors)
  //
  gsl_poly_complex_workspace* WS
    (gsl_poly_complex_workspace_alloc(iDegree+1));
  double* RZ=new double[2*(iDegree+1)];
  gsl_poly_complex_solve(&afCoeff.front(),iDegree+1, WS, RZ);
  for(int i=0;i<iDegree;i++)
    Out[i]=std::complex<double>(RZ[2*i],RZ[2*i+1]);
  gsl_poly_complex_workspace_free (WS);
  delete [] RZ;
  return Out;
}
Ejemplo n.º 8
0
double travelTimeMarcher::updatePointOrderTwo(int i)
{
  double a,b,c;
  a=b=c=0;
  int naddr=0;
  for (int dim=0; dim<dim_; dim++)
  {
    double value1 = maxDouble;
    double value2 = maxDouble;
    for (int j=-1; j<2; j+=2) // each direction
    {
      naddr = _getN(i,dim,j,Mask);
      if (naddr!=-1 && flag_[naddr]==Frozen)
      {
        if (distance_[naddr]<value1)
        {
          value1 = distance_[naddr];
          int naddr2 = _getN(i,dim,j*2,Mask);
          if (naddr2!=-1 &&
              flag_[naddr2]==Frozen &&
              ((distance_[naddr2]<=value1 && value1 >=0) ||
               (distance_[naddr2]>=value1 && value1 <=0)))
          {
            value2=distance_[naddr2];
            if (phi_[naddr2] * phi_[naddr] < 0)
              value2 *= -1;
          }
        }
      }
    }
    if (value2<maxDouble)
    {
      double tp = oneThird*(4*value1-value2);
      a+=idx2_[dim]*aa;
      b-=idx2_[dim]*2*aa*tp;
      c+=idx2_[dim]*aa*pow(tp,2);
    }
    else if (value1<maxDouble)
    {
      a+=idx2_[dim];
      b-=idx2_[dim]*2*value1;
      c+=idx2_[dim]*pow(value1,2);
    }
  }
  return solveQuadratic(i,a,b,c);
}
Ejemplo n.º 9
0
bool VRSim::solveRaycast(const cavr::gfx::Ray& ray, const cavr::math::vec3f& pos, float radius_sq) {
  float t0, t1;

  cavr::math::vec3f L = ray.origin() - pos;
  float a = ray.direction().dot(ray.direction());
  float b = 2 * ray.direction().dot(L);
  float c = L.dot(L) - radius_sq;
  if(!solveQuadratic(a, b, c, t0, t1)) return false;

  if (t0 > t1) std::swap(t0, t1);

  if (t0 < 0) {
    t0 = t1; // if t0 is negative, let's use t1 instead
    if (t0 < 0) return false; // both t0 and t1 are negative
  }

    return true;
}
Ejemplo n.º 10
0
bool Sphere::intersectP(const Ray& ray)
{
    Vector temp = ray.o - center;
    float a = dot(ray.d, ray.d);
    float b = 2 * dot(temp, ray.d);
    float c = dot(temp, temp) - radius * radius;

    float t1, t2;

    if (solveQuadratic(a, b, c, &t1, &t2)) {
        float t = std::min(t1, t2);
        if (t > EPSILON) {
            return true;
        }
    }

    return false;
}
Ejemplo n.º 11
0
tuple solveQuadraticWrapper( double a, double b, double c )
{
	double x[2];
	int s = solveQuadratic( a, b, c, x );
	switch( s )
	{
		case 0 :
			return tuple();
		case 1 :
			return make_tuple( x[0] );
		case 2 :
			return make_tuple( x[0], x[1] );
		default :
			PyErr_SetString( PyExc_ArithmeticError, "Infinite solutions." );
			throw_error_already_set();
			return tuple(); // should never get here
	}
}
Ejemplo n.º 12
0
void computeChromaticTuneLimits(LINE_LIST *beamline)
{
  long i, j, n, p;
  double c1, c2, c3, tuneValue[5], solution[2];
  
  for (i=0; i<2; i++) {
    if (beamline->chromDeltaHalfRange<=0) {
      beamline->tuneChromUpper[i] = beamline->tuneChromLower[i] = beamline->tune[i];
    } else {
      tuneValue[0] = beamline->tune[i];
      /* polynomial coefficients */
      c1 = beamline->chromaticity[i];
      c2 = beamline->chrom2[i]/2.0;
      c3 = beamline->chrom3[i]/6.0;
      tuneValue[1] = beamline->tune[i] + 
        beamline->chromDeltaHalfRange*c1 + 
          sqr(beamline->chromDeltaHalfRange)*c2 +
            ipow(beamline->chromDeltaHalfRange, 3)*c3;
      tuneValue[2] = beamline->tune[i] -
        beamline->chromDeltaHalfRange*c1 + 
          sqr(beamline->chromDeltaHalfRange)*c2 -
            ipow(beamline->chromDeltaHalfRange, 3)*c3;
      p = 3;
      /* find extrema */
      n = solveQuadratic(3*c3, 2*c2, c1, solution);
      for (j=0; j<n; j++) {
        if (fabs(solution[j])>beamline->chromDeltaHalfRange)
          continue;
        tuneValue[p] = beamline->tune[i] +
          solution[j]*c1 + sqr(solution[j])*c2 +
            ipow(solution[j], 3)*c3;
        p += 1;
      }
      find_min_max(beamline->tuneChromLower+i, beamline->tuneChromUpper+i, 
                   tuneValue, p);
    }
  }
}
Ejemplo n.º 13
0
int solveCubic( T a, T b, T c, T d, T result[3] )
{
	if( a == 0 )
		return solveQuadratic( b, c, d, result );

	T f = ((3 * c / a) - ((b * b) / (a * a))) / 3;
	T g = ((2 * b * b * b) / (a * a * a) - (9 * b * c) / (a * a) + (27 * d) / (a)) / 27;
	T h = g * g / 4 + f * f * f / 27;

	if( f == 0 && g == 0 && h == 0 ) {
		result[0] = -math<T>::cbrt( d / a );
		return 1;
	}
	else if( h > 0 ) {
		// 1 root
		T r = -( g / 2 ) + math<T>::sqrt( h );
		T s = math<T>::cbrt( r );
		T t = -(g / 2) - math<T>::sqrt( h );
		T u = math<T>::cbrt( t );

		result[0] = (s + u) - (b / (3 * a));
		return 1;
	}
	else { // 3 roots
		T i = math<T>::sqrt( (g * g / 4) - h );
		T j = math<T>::cbrt( i );
		T k = math<T>::acos( -(g / (2 * i)) );
		T l = -j;
		T m = math<T>::cos( k / 3 );
		T n = math<T>::sqrt(3) * math<T>::sin( k / 3 );
		T p = -b / (3 * a);
		result[0] = 2 * j * math<T>::cos(k / 3) - (b / (3 * a));
		result[1] = l * (m + n) + p;
		result[2] = l * (m - n) + p;
		return 3;
	}
}
Ejemplo n.º 14
0
int HitOutline::Raycast(Point2D p, Vector2D v, Scalar maxTime, 
    Hit* hitArr, int hitArrSize, Scalar sense)
{
	//local data: Bart
	Hit localHitArr[100];
	int localHitArrSize=100;

    int hitCount = 0;

    // TODO: Currently very slow, brute force!
    int lineVertexCount = m_Lines.size();
	int quadVertexCount = m_Quads.size();

    Scalar epsilon = 1e-6;

	Point2D p1 = p;
	Point2D p2 = p+v;
    Point2D orig(0,0);
	Scalar vDv = v.Dot(v);
    Vector2D n = v.Orthogonal();

	// Line-line intersections.
	if( lineVertexCount > 0 )
	{
		Point2D* lines = &m_Lines[0];

		for( int i=0; i<lineVertexCount && hitCount<localHitArrSize; i += 2 )
		{
			Point2D q1 = lines[i+0];
			Point2D q2 = lines[i+1];

			Vector2D ortho = (q2-q1).Orthogonal();
			if( (dot(ortho, v) * sense < 0) || sense==0)
			{
				Scalar time1;
				Scalar time2;
				if( IntersectLines(p1, p2, q1, q2, time1, time2) )
				{
					if( time1 >= 0 && time1 < maxTime &&
						time2 >= 0 && time2 <= 1 )
					{
						Hit hit;
                        hit.Time = time1;
						hit.Point = p + time1 * v;
						hit.Normal = ortho.Normalized();
                        localHitArr[hitCount++] = hit;
					}
				}
			}
		}
	}

	// Line-quadratic intersections.
	if( quadVertexCount > 0 )
	{
		Point2D* quads = &m_Quads[0];
		for( int i=0; i<quadVertexCount && hitCount<localHitArrSize; i += 3 )
		{
			Vector2D q0 = quads[i+0] - p;
			Vector2D q1 = quads[i+1] - p;
			Vector2D q2 = quads[i+2] - p;

            // Hit only possible if:
            // (1) not all points are on same side of ray,
            //     
            // (2) and some points are in front of ray (currently not checked, handled by abc formula)

            Scalar dot_n_q0 = dot(n,q0);
            Scalar dot_n_q1 = dot(n,q1);
            Scalar dot_n_q2 = dot(n,q2);

            if( dot_n_q0 <= 0 && dot_n_q1 <= 0 && dot_n_q2 <= 0 )
                continue;

            if( dot_n_q0 >= 0 && dot_n_q1 >= 0 && dot_n_q2 >= 0 )
                continue;

            Scalar ts[2];
            Scalar a = 2*dot_n_q1-dot_n_q0-dot_n_q2;
            Scalar b = 2*dot_n_q0-2*dot_n_q1;
            Scalar c = -dot_n_q0;
			int n = solveQuadratic(a,b,c,ts);

			for( int j=0; j<n && hitCount < localHitArrSize; ++j )
			{
				Scalar t = ts[j];
				if( t >= 0 && t <= 1 )
				{
					Vector2D diff = (2*(q2-q1)+2*(q0-q1))*t+2*(q1-q0);
					Vector2D ortho = diff.Orthogonal();
					if( (dot(ortho, v) * sense < 0) || sense==0)
					{
						Vector2D h = lerp( lerp(q0,q1,t), lerp(q1,q2,t), t);
						Scalar time = h.Dot(v) / vDv;
						//time >= -maxTime
                        if( time >= 0 && time < maxTime )
                        {
						    Hit hit;
						    hit.Point = p+h;
						    hit.Time = time;
						    hit.Normal = ortho.Normalized();
                            localHitArr[hitCount++] = hit;
                        }
					}
				}
			}
		}
	}

    std::sort(localHitArr, localHitArr+hitCount, sortHitOnTime);
	//Bart
	for( int i=0; i<hitCount && i < hitArrSize; ++i )
	{
		hitArr[i]=localHitArr[i];
	}
    return hitCount;
}
Ejemplo n.º 15
0
static void renderDiskExact(IntegratorT& integrator, V3f p, V3f n, float r)
{
    int faceRes = integrator.res();
    float plen2 = p.length2();
    if(plen2 == 0) // Sanity check
        return;
    // Angle from face normal to edge is acos(1/sqrt(3)).
    static float cosFaceAngle = 1.0f/sqrtf(3);
    static float sinFaceAngle = sqrtf(2.0f/3.0f);
    for(int iface = 0; iface < 6; ++iface)
    {
        // Avoid rendering to the current face if the disk definitely doesn't
        // touch it.  First check the cone angle
        if(sphereOutsideCone(p, plen2, r, MicroBuf::faceNormal(iface),
                             cosFaceAngle, sinFaceAngle))
            continue;
        float dot_pFaceN = MicroBuf::dotFaceNormal(iface, p);
        float dot_nFaceN = MicroBuf::dotFaceNormal(iface, n);
        // If the disk is behind the camera and the disk normal is relatively
        // aligned with the face normal (to within the face cone angle), the
        // disk can't contribute to the face and may be culled.
        if(dot_pFaceN < 0 && fabs(dot_nFaceN) > cosFaceAngle)
            continue;
        // Check whether disk spans the perspective divide for the current
        // face.  Note: sin^2(angle(n, faceN)) = (1 - dot_nFaceN*dot_nFaceN)
        if((1 - dot_nFaceN*dot_nFaceN)*r*r >= dot_pFaceN*dot_pFaceN)
        {
            // When the disk spans the perspective divide, the shape of the
            // disk projected onto the face is a hyperbola.  Bounding a
            // hyperbola is a pain, so the easiest thing to do is trace a ray
            // for every pixel on the face and check whether it hits the disk.
            //
            // Note that all of the tricky rasterization rubbish further down
            // could probably be replaced by the following ray tracing code if
            // I knew a way to compute the tight raster bound.
            integrator.setFace(iface);
            for(int iv = 0; iv < faceRes; ++iv)
            for(int iu = 0; iu < faceRes; ++iu)
            {
                // V = ray through the pixel
                V3f V = integrator.rayDirection(iface, iu, iv);
                // Signed distance to plane containing disk
                float t = dot(p, n)/dot(V, n);
                if(t > 0 && (t*V - p).length2() < r*r)
                {
                    // The ray hit the disk, record the hit
                    integrator.addSample(iu, iv, t, 1.0f);
                }
            }
            continue;
        }
        // If the disk didn't span the perspective divide and is behind the
        // camera, it may be culled.
        if(dot_pFaceN < 0)
            continue;
        // Having gone through all the checks above, we know that the disk
        // doesn't span the perspective divide, and that it is in front of the
        // camera.  Therefore, the disk projected onto the current face is an
        // ellipse, and we may compute a quadratic function
        //
        //   q(u,v) = a0*u*u + b0*u*v + c0*v*v + d0*u + e0*v + f0
        //
        // such that the disk lies in the region satisfying q(u,v) < 0.  To do
        // this, start with the implicit definition of the disk on the plane,
        //
        //   norm(dot(p,n)/dot(V,n) * V - p)^2 - r^2 < 0
        //
        // and compute coefficients A,B,C such that
        //
        //   A*dot(V,V) + B*dot(V,n)*dot(p,V) + C < 0
        float dot_pn = dot(p,n);
        float A = dot_pn*dot_pn;
        float B = -2*dot_pn;
        float C = plen2 - r*r;
        // Project onto the current face to compute the coefficients a0 through
        // to f0 for q(u,v)
        V3f pp = MicroBuf::canonicalFaceCoords(iface, p);
        V3f nn = MicroBuf::canonicalFaceCoords(iface, n);
        float a0 = A + B*nn.x*pp.x + C*nn.x*nn.x;
        float b0 = B*(nn.x*pp.y + nn.y*pp.x) + 2*C*nn.x*nn.y;
        float c0 = A + B*nn.y*pp.y + C*nn.y*nn.y;
        float d0 = (B*(nn.x*pp.z + nn.z*pp.x) + 2*C*nn.x*nn.z);
        float e0 = (B*(nn.y*pp.z + nn.z*pp.y) + 2*C*nn.y*nn.z);
        float f0 = (A + B*nn.z*pp.z + C*nn.z*nn.z);
        // Finally, transform the coefficients so that they define the
        // quadratic function in *raster* face coordinates, (iu, iv)
        float scale = 2.0f/faceRes;
        float scale2 = scale*scale;
        float off = 0.5f*scale - 1.0f;
        float a = scale2*a0;
        float b = scale2*b0;
        float c = scale2*c0;
        float d = ((2*a0 + b0)*off + d0)*scale;
        float e = ((2*c0 + b0)*off + e0)*scale;
        float f = (a0 + b0 + c0)*off*off + (d0 + e0)*off + f0;
        // Construct a tight bound for the ellipse in raster coordinates.
        int ubegin = 0, uend = faceRes;
        int vbegin = 0, vend = faceRes;
        float det = 4*a*c - b*b;
        // Sanity check; a valid ellipse must have det > 0
        if(det <= 0)
        {
            // If we get here, the disk is probably edge on (det == 0) or we
            // have some hopefully small floating point errors (det < 0: the
            // hyperbolic case we've already ruled out).  Cull in either case.
            continue;
        }
        float ub = 0, ue = 0;
        solveQuadratic(det, 4*d*c - 2*b*e, 4*c*f - e*e, ub, ue);
        ubegin = std::max(0, Imath::ceil(ub));
        uend   = std::min(faceRes, Imath::ceil(ue));
        float vb = 0, ve = 0;
        solveQuadratic(det, 4*a*e - 2*b*d, 4*a*f - d*d, vb, ve);
        vbegin = std::max(0, Imath::ceil(vb));
        vend   = std::min(faceRes, Imath::ceil(ve));
        // By the time we get here, we've expended perhaps 120 FLOPS + 2 sqrts
        // to set up the coefficients of q(iu,iv).  The setup is expensive, but
        // the bound is optimal so it will be worthwhile vs raytracing, unless
        // the raster faces are very small.
        integrator.setFace(iface);
        for(int iv = vbegin; iv < vend; ++iv)
        for(int iu = ubegin; iu < uend; ++iu)
        {
            float q = a*(iu*iu) + b*(iu*iv) + c*(iv*iv) + d*iu + e*iv + f;
            if(q < 0)
            {
                V3f V = integrator.rayDirection(iface, iu, iv);
                // compute distance to hit point
                float z = dot_pn/dot(V, n);
                integrator.addSample(iu, iv, z, 1.0f);
            }
        }
    }
}