Example #1
0
double Bridge:: find_zeta_max(const double theta)
{
    // a good value
    double zeta_lo = 0.0;
    if( find_alpha(theta, zeta_lo, NULL) < 0 )
    {
        throw exception("Cannot find alpha for zeta=0");
    }

    // a bad balue
    double zeta_up = 1.0;
    while(find_alpha(theta,zeta_up,NULL)>=0)
    {
        zeta_lo = zeta_up;
        zeta_up += 1.0;
    }
    std::cerr << "Looking up between " << zeta_lo << " and " << zeta_up << std::endl;
    const double zeta_ftol = numeric<double>::sqrt_ftol;
    while( Fabs(zeta_up-zeta_lo) >= zeta_ftol * ( Fabs(zeta_lo) + Fabs(zeta_up) ) )
    {
        const double zeta_mid = 0.5*(zeta_lo+zeta_up);
        if(find_alpha(theta,zeta_mid,NULL) < 0 )
        {
            zeta_up = zeta_mid;
        }
        else
        {
            zeta_lo = zeta_mid;
        }
    }

    // highest good value
    return zeta_lo;
}
Example #2
0
void Bubble:: map_peanut( const Vertex &center, Real radius, Real alpha )
{
    assert(lambda>0);
    empty();
    alpha = clamp<Real>(0,Fabs(alpha),1);
    const Real b = Fabs(radius);
    const Real a = alpha * b;
    const Real a2 = a*a;
    const Real b2 = b*b;
    const Real a4 = a2*a2;
    const Real b4 = b2*b2;
    const Real   theta_max = 2 * atan( lambda/(radius+radius) );
    const size_t nmin      = 2*max_of<size_t>(3,size_t( ceil( numeric<Real>::two_pi/theta_max) ));
    const Real   dtheta    = numeric<Real>::two_pi / nmin;
    
    fprintf( stderr, "peanut @(%g,%g), b=%g, a=%g\n", center.x, center.y, b, a ); 
    
    for( size_t i=0; i < nmin; ++i )
    {
        const Real   theta = i * dtheta;;
        const Real   t2    = theta+theta; 
        Tracer      *p     = append();
        const Real   S     = Sin(t2);
        const  Real  c1    = max_of<Real>(0,b4 - a4 * S*S );
        const  Real  C     = max_of<Real>(0,a2 * Cos( t2 ) + Sqrt(c1));
        const  Real  rho   = Sqrt(C);
        p->vertex.x = center.x + rho * Cos( theta );
        p->vertex.y = center.y + rho * Sin( theta );
    }
    raw_initialize();    
}
void gfx_gradient_adapter::init_radial(int spread, scalar x1, scalar y1, scalar radius1,
                                           scalar x2, scalar y2, scalar radius2)
{
    if (!m_wrapper) {
        if ((x1 == x2) && (y1 == y2)) {
            switch (spread) {
                case SPREAD_PAD:
                    m_wrapper = new gfx_gradient<gradient_radial,
                                             gradient_pad_adaptor<gradient_radial> >;
                    break;
                case SPREAD_REPEAT:
                    m_wrapper = new gfx_gradient<gradient_radial,
                                             gradient_repeat_adaptor<gradient_radial> >;
                    break;
                case SPREAD_REFLECT:
                    m_wrapper = new gfx_gradient<gradient_radial,
                                             gradient_reflect_adaptor<gradient_radial> >;
                    break;
            }
        } else {
            switch (spread) {
                case SPREAD_PAD:
                    m_wrapper = new gfx_gradient<gradient_radial_focus,
                                             gradient_pad_adaptor<gradient_radial_focus> >;
                    break;
                case SPREAD_REPEAT:
                    m_wrapper = new gfx_gradient<gradient_radial_focus,
                                             gradient_repeat_adaptor<gradient_radial_focus> >;
                    break;
                case SPREAD_REFLECT:
                    m_wrapper = new gfx_gradient<gradient_radial_focus,
                                             gradient_reflect_adaptor<gradient_radial_focus> >;
                    break;
            }

        }

        if (!m_wrapper)
            return;

        scalar len = Fabs(radius2);
        scalar fx = x1 - x2;
        scalar fy = y1 - y2;

        m_wrapper->init(len, fx, fy);

        if (!len)
            len = FLT_TO_SCALAR(2.0f); // len can not be zero

        gfx_trans_affine mtx;
        mtx.translate(x1 - fx, y1 - fy);


        m_start = Fabs(radius1);
        m_length = len;
        m_matrix = mtx;
    }
}
Example #4
0
//==============================================================================
//! simultaneous tridiagonal system
//==============================================================================
static inline
void vertex_tridiag(const array<Real>   &a,
                    const array<Real>   &b,
                    const array<Real>   &c,
                    const array<Vertex> &r,
                    array<Vertex>       &u,
                    const size_t         n)
{
    const Vertex org(0,0);
    
    assert(n<=a.size());
    assert(n<=b.size());
    assert(n<=c.size());
    assert(n<=r.size());
    assert(n<=u.size());
    assert(Fabs(b[1])>0);
    Vertex         bet;
    vector<Vertex> gam(n,org);
    u[1]=r[1]/(bet.x=bet.y=b[1]);
    for(size_t j=2;j<=n;j++)
    {
        Vertex    &gam_j = gam[j];
        const Real c_jm  = c[j-1];
        gam_j.x = c_jm/bet.x;
        gam_j.y = c_jm/bet.y;
        
        const Real b_j = b[j];
        const Real a_j = a[j];
        
        bet.x = b_j - a_j * gam_j.x;
        bet.y = b_j - a_j * gam_j.y;
        
        if ( Fabs(bet.x) <= 0 || Fabs(bet.y) <= 0 )
            throw exception("Error 2 in tridag");
        
        const Vertex &r_j = r[j];
        Vertex       &u_j = u[j];
        const Vertex &u_jm = u[j-1];
        
        u_j.x = (r_j.x - a_j * u_jm.x) / bet.x;
        u_j.y = (r_j.y - a_j * u_jm.y) / bet.y;
    }
    for(size_t j=(n-1);j>=1;j--)
    {
        Vertex       &u_j    = u[j];
        const Vertex &u_jp   = u[j+1];
        const Vertex &gam_jp = gam[j+1];
        u_j.x -= gam_jp.x * u_jp.x;
        u_j.y -= gam_jp.y * u_jp.y;
    }
    
}
Example #5
0
FLOAT F_mul_F(FLOAT aa, FLOAT bb) {
	uint32_t a, b, sgn;
	unsigned long long res;
	FLOAT ret;
	a = Fabs(aa);
	b = Fabs(bb);
	sgn = (a != aa) ^ (b != bb);
	res = (uint64_t)a * (uint64_t)b;
	res >>= 16;
	res &= 0x7FFFFFFF;
	ret = res;
	return sgn ? -ret : ret;
}
Example #6
0
void Segmenter:: process_spot( const Spot *spot, const Real half )
{
    const Tracer *tracer = spot->handle;
    const Vertex  vertex = tracer->vertex;
    assert( vertex.x >= X[X.lower]);
    assert( vertex.x <  X[X.upper]);
    assert( vertex.y >= Y[Y.lower]);
    assert( vertex.y <  Y[Y.upper]);
    
    //--------------------------------------------------------------------------
    // locate the tracer
    //--------------------------------------------------------------------------
    locate_vertex(vertex, spot->klo, spot->kup);
    
    //--------------------------------------------------------------------------
    // compute the absolute next coordinate
    //--------------------------------------------------------------------------
    Vertex target = vertex + tracer->edge;
    
    //--------------------------------------------------------------------------
    // find junctions
    //--------------------------------------------------------------------------
    compute_junctions(spot, vertex, target, tracer->next);
    const Tracer *prec = tracer->prev;
    if( ! prec->is_spot || Fabs(prec->vertex.y - vertex.y) >= half )
    {
        target = vertex - prec->edge;
        compute_junctions(spot, vertex, target, prec);
    }
}
Example #7
0
/* Return the unit which yields the number with the least figures. */
const AG_Unit *
AG_BestUnit(const AG_Unit ugroup[], double n)
{
	const AG_Unit *unit, *bestunit = NULL;
	double smallest = HUGE_VAL;
	double diff;

	if (n == 0) {
		goto defunit;
	}
	for (unit = &ugroup[0]; unit->key != NULL; unit++) {
		if (n/unit->divider >= 1.0) {
			diff = Fabs(n-unit->divider);
			if (diff < smallest) {
				smallest = diff;
				bestunit = unit;
			}
		}
	}
	if (bestunit == NULL) {
		goto defunit;
	}
	return (bestunit);
defunit:
	for (unit = &ugroup[0]; unit->key != NULL; unit++) {
		if (unit->divider == 1.0)
			break;
	}
	return (unit);
}
Example #8
0
int main() { 
	FLOAT a = computeT(10, f2F(-1.0), f2F(1.0), f);
	FLOAT ans = f2F(0.551222);
	nemu_assert(Fabs(a - ans) < f2F(1e-4));
	HIT_GOOD_TRAP;
	return 0;
}
 int calculate(int x, int y, int) const
 {
     scalar dx = INT_TO_SCALAR(x - m_fx);
     scalar dy = INT_TO_SCALAR(y - m_fy);
     scalar d2 = dx * m_fy - dy * m_fx;
     scalar d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2;
     return iround((dx * m_fx + dy * m_fy + Sqrt(Fabs(d3))) * m_mul);
 }
Example #10
0
FLOAT sqrt(FLOAT x) {
	FLOAT dt, t = int2F(2);

	do {
		dt = F_div_int((F_div_F(x, t) - t), 2);
		t += dt;
	} while(Fabs(dt) > f2F(1e-4));

	return t;
}
Example #11
0
static inline Lisp_Object
_ase_metric_p_1dim_p(Lisp_Object a, Lisp_Object b, unsigned int p)
{
	Lisp_Object tmp = ent_binop(ASE_BINARY_OP_DIFF, a, b);
	Lisp_Object result = ent_binop(ASE_BINARY_OP_POW, tmp, make_int(p));
	if ((p & 1) == 0)
		return result;
	else
		return Fabs(result);
}
Example #12
0
/* Compute the intersection of two circles. */
M_GeomSet2
M_IntersectCircleCircle2(M_Circle2 C1, M_Circle2 C2)
{
	M_GeomSet2 Sint = M_GEOM_SET_EMPTY;
	M_Real d12 = M_VecDistance2(C1.p, C2.p);
	M_Real a, h, b;
	M_Vector2 p;
	M_Geom2 G1, G2;

	if (Fabs(C1.p.x - C2.p.x) <= M_MACHEP &&
	    Fabs(C1.p.x - C2.p.x) <= M_MACHEP &&
	    Fabs(C1.r - C2.r) <= M_MACHEP) {
		G1.type = M_CIRCLE;
		G1.g.circle = C1;
		M_GeomSetAdd2(&Sint, &G1);
		return (Sint);
	}

	if (d12 > (C1.r + C2.r) ||
	    d12 < Fabs(C1.r - C2.r)) {
		return (Sint);
	}

	a = (C1.r*C1.r - C2.r*C2.r + d12*d12) / (2.0*d12);
	h = Sqrt(C1.r*C1.r - a*a);
	p = M_VecLERP2(C1.p, C2.p, a/d12);
	b = h/d12;

	G1.type = M_POINT;
	G1.g.point.x = p.x - b*(C2.p.y - C1.p.y);
	G1.g.point.y = p.y + b*(C2.p.x - C1.p.x);
	G2.type = M_POINT;
	G2.g.point.x = p.x + b*(C2.p.y - C1.p.y);
	G2.g.point.y = p.y - b*(C2.p.x - C1.p.x);

	M_GeomSetAdd2(&Sint, &G1);
	if (M_VecDistance2(G1.g.point, G2.g.point) > M_MACHEP) {
		M_GeomSetAdd2(&Sint, &G2);
	}
	return (Sint);
}
Example #13
0
FLOAT pow(FLOAT x, FLOAT y) {
	/* we only compute x^0.333 */
	FLOAT t2, dt, t = int2F(2);

	do {
		t2 = F_mul_F(t, t);
		dt = (F_div_F(x, t2) - t) / 3;
		t += dt;
	} while(Fabs(dt) > f2F(1e-4));

	return t;
}
Example #14
0
FLOAT F_div_F(FLOAT aa, FLOAT bb) {
	uint32_t a, b, sgn, res;
	FLOAT ret;
	int i;
	a = Fabs(aa);
	b = Fabs(bb);
	sgn = (a != aa) ^ (b != bb);
	nemu_assert(b != 0);
	res = a / b;
	a = a % b;
	for(i=0; i<16; i++) {
		res <<= 1;
		a <<= 1;
		if(a >= b) {
			res |= 1;
			a -= b;
		}
	}
	res &= 0x7FFFFFFF;
	ret = res;
	return sgn ? -ret : ret;
}
Example #15
0
void Tartet::Allocator(void)
{
	if ((dx.data[0] != onex_) || (dx.data[1] != onex_))
		Errmsg("Fatal", "Tartet", " tartet does not support noncubic lattice");
//
// Determine list of occupied sites.
	int curSize = nx * ny;
	ixyz.Dimension(curSize, 3);

	nat0 = 0;
	for(int i=minJx; i<=maxJx; ++i)
	{
		real x = i + xoff;
// YMAX=largest value of Y which can occur for this X value
// YMIN=smallest value of Y which can occur for this X value
// ZMAX0=largest value of Z which can occur for this X value
		real ymax = (real)( shpar[0] * Sqrt(3./16.) - x / Sqrt(twox_));
		real ymin = (real)(-shpar[0] * Sqrt(3./64.) + x / Sqrt(8.));
		real zmax0 = (real)(3. * shpar[0] / 8. - x * Sqrt(3./8.));
		for(int j=minJy; j<=maxJy; ++j)
		{
			real y = j + yoff;
			if ((y >= ymin) && (y <= ymax))
			{
				real fy = (y - ymin) / (ymax - ymin);
				real zmax = (onex_ - fy) * zmax0;				// ! ZMAX=largest value of Z which can occur for this (X,Y)
				for(int k=minJz; k<=maxJz; ++k)
				{
					real z = k + zoff;
					if (Fabs(z) <= zmax)					// ! Site is occupied:
					{
						if (nat0 >= curSize)
						{
							ixyz.Extend(nz);
							curSize = ixyz.GetSize(0);
						}
						ixyz.Fill3(nat0, i, j, k);
						int index = GetLinearAddress(nat0);
						Composer(index, 0);
						iocc[index] = true;
						++nat0;
					}
				}
			}
		}
	}
	ixyz.Close(nat0);
}
Example #16
0
/* multiply the accumulators
 * by the inverse diagonal
 * hessian (hess) 
 */
void 
Hess_acc(weight *nptr)
{
  int i, iend;
  weight *w;

  if (nptr==NULL) {
    w=weightbase;
    iend=weightnombre;
  } else {
    w=nptr;
    iend=1; 
  }
  for ( i=0; i<iend; i++, w++ ) {
    w->Wacc=Fdiv( w->Wacc, Fadd( mu, Fabs(w->Whess)));
  }
}
Example #17
0
/*
 * Compute the shortest line segment connecting two lines in R^3.
 * Adapted from Paul Bourke's example code:
 * http://paulbourke.net/geometry/lineline3d
 */
int
M_LineLineShortest3(M_Line3 L1, M_Line3 L2, M_Line3 *Ls)
{
	M_Vector3 p1 = M_LineInitPt3(L1);
	M_Vector3 p2 = M_LineTermPt3(L1);
	M_Vector3 p3 = M_LineInitPt3(L2);
	M_Vector3 p4 = M_LineTermPt3(L2);
	M_Vector3 p13, p43, p21;
	M_Real d1343, d4321, d1321, d4343, d2121;
	M_Real numer, denom;
	M_Real muA, muB;

	p13 = M_VecSub3(p1, p3);
	p43 = M_VecSub3(p4, p3);
	if (Fabs(p43.x) < M_MACHEP &&
	    Fabs(p43.y) < M_MACHEP &&
	    Fabs(p43.z) < M_MACHEP)
		return (0);

	p21 = M_VecSub3(p2, p1);
	if (Fabs(p21.x) < M_MACHEP &&
	    Fabs(p21.y) < M_MACHEP &&
	    Fabs(p21.z) < M_MACHEP)
		return (0);

	d1343 = M_VecDot3p(&p13, &p43);
	d4321 = M_VecDot3p(&p43, &p21);
	d4343 = M_VecDot3p(&p43, &p43);
	d2121 = M_VecDot3p(&p21, &p21);

	denom = d2121*d4343 - d4321*d4321;
	if (Fabs(denom) < M_MACHEP) {
		return (0);
	}
	numer = d1343*d4321 - d1321*d4343;

	muA = numer/denom;
	muB = (d1343 + d4321*muA) / d4343;

	if (Ls != NULL) {
		*Ls = M_LineFromPts3(
		    M_VecAdd3(p1, M_VecScale3(p21,muA)),
		    M_VecAdd3(p3, M_VecScale3(p43,muB)));
	}
	return (1);
}
Example #18
0
int main() {
//	nemu_assert(int2F(1) + F_mul_int(F_mul_F(f2F(-0.8),f2F(-0.8)),25) > int2F(16.9));
//	nemu_assert(int2F(1) + F_mul_int(F_mul_F(f2F(-0.8),f2F(-0.8)),25) < int2F(17));
//	nemu_assert();
//	nemu_assert(F_div_F(int2F(1) , int2F(1) + F_mul_int(F_mul_F(f2F(-0.8),f2F(-0.8)),25)) > f2F(0));
//	nemu_assert(F_div_F(int2F(1) , f2F(17)) > f2F(0.05));
/*	nemu_assert(F_div_int(int2F(2),10) <= f2F(0.2));
	nemu_assert(F_div_int(int2F(2),10) > f2F(0.1999));
	nemu_assert(F_mul_F(f2F(1.0),int2F(25)) == f2F(25));
	nemu_assert(f(int2F(1)) < f2F(0.039));
	nemu_assert(F_mul_int(f2F(0.2),9 ) > f2F(1.7));*/
//	nemu_assert(F_mul_F(f2F(-0.8),f2F(-0.8)) == f2F(0.64));
 // nemu_assert(F_div_F(0x10000,0x10ffcd) == int2F(0));
//	nemu_assert(f(-0.8) > f2F(0.05));
//	nemu_assert(F_mul_F(f2F(0.8),f2F(0.8)) < f2F(0.64));
//	nemu_assert(f(f2F(0.8)) > f2F(0.05));
//	nemu_assert(f(f2F(0.8)) < f2F(0.06));
//	nemu_assert(F_mul_F(f2F(-0.2),f2F(-0.2)) == f2F(0.04));
//	nemu_assert(f(f2F(-0.2)) == int2F(0));
//	nemu_assert(f2F(-1.0) + F_mul_int(f2F(0.2),9) < f2F(0.9));
//	nemu_assert(f(f2F(-1.0) + F_mul_int(f2F(0.2), 9)) > f2F(0.03));
//	nemu_assert(f2F(0.2) == 0x3333);
//	nemu_assert(F_mul_F(f2F(2.756),f2F(0.2)) > f2F(0.55));
//	nemu_assert(F_mul_F(f2F(2.756),f2F(0.2)) < f2F(0.5515));
//	nemu_assert( < f2F(0.05));
//	nemu_assert(f(1.8)<f2F(0.040));
	FLOAT a = computeT(10, f2F(-1.0), f2F(1.0), f);
//	nemu_assert(a > int2F(1));
	FLOAT ans = f2F(0.551222);
	nemu_assert(Fabs(a - ans) < f2F(1e-4));
//	nemu_assert(a < f2F(0.019));
//	FLOAT ans = f2F(2.756);
	//nemu_assert(a <= ans);
//	nemu_assert(a > f2F(0.1));
//	nemu_assert(Fabs(a - ans) < f2F(1e-4));
	HIT_GOOD_TRAP;
	return 0;
}
Example #19
0
void Getmueller(DDscatParameters *param, int ibeta, int iphi, int itheta, PeriodicBoundaryFlag jpbc, real *orderm, real *ordern, real ak1, 
	Vect3<real> *aks_tf, Vect3<real> *ensc_lf, Vect3<real> *ensc_tf, real pyddx, real pzddx, real *sm, real *smori, real *s1111, real *s2121, 
	Complex *cx1121, FourArray *cxfData, SumPackage &sumPackage, Vect3<real> *em1_lf, Vect3<real> *em2_lf, Vect3<real> *em1_tf, Vect3<real> *em2_tf)
{
/* **
 Given:
   IBETA =index specifying rotation of target around axis a1
   IORTH =number of incident polarization states being calculated for
   IPHI  =index specifying phi value for orientation of target axis a1
   ITHETA=index specifying theta value for orientation of target axis a1
   JPBC  = 0 if PBC not used
           1 if PBC used in y direction only
           2 if PBC used in z direction only
           3 if PBC used in both y and z directions
   MXBETA=dimensioning information
   MXSCA =dimensioning information
   MXPHI =dimensioning information
   MXTHET=dimensioning information
   NSCAT =number of scattering directions for evaluation of Mueller matrix
   CMDTRQ='DOTORQ' or 'NOTORQ' depending on whether or not torque calculation is to be carried out
   ENSC_LF(1-3,1-NSCAT)=normalized scattering direction vector in Lab Frame for scattering directions 1-NSCAT
   ENSCR(1-3,1-NSCAT)=normalized scattering direction vector in Target Frame for scattering directions 1-NSCA
   EM1_LF(1-3,1-NSCAT)=unit scattering polarization vector 1 in Lab Frame
   EM2_LF(1-3,1-NSCAT)=unit scattering polarization vector 2 in Lab Frame
   EM1_TF(1-3,1-NSCAT)=unit scattering polarization vector 1 in Target Frame
   EM2_TF(1-3,1-NSCAT)=unit scattering polarization vector 2 in Target Frame
   PHIN(1-NSCAT)=values of PHI for scattering directions 1-NSCAT in Lab Frame [only used if JPBC=0: scattering by finite target]
   AKS_TF(1-3,1-NSCAT)=(kx,ky,kz)*d for NSCAT scattering directions in Target Frame
   ORDERM(1-NSCAT)=scattering order M for case of 1-d or 2-d target
   ORDERN(1-NSCAT)=scattering order N for case of 2-d target
   S1111(1-NSCAT)=weighted sum of |f_11|^2 over previous orientations
   S2121(1-NSCAT)=weighted sum of |f_21|^2 over previous orientations
   CXE01_LF(1-3)    =incident pol state 1 in Lab Frame
   CXE02_LF(1-3)    =                   2
   CXF11(1-NSCAT)=f_11 for current orientation
   CXF12(1-NSCAT)=f_12 for current orientation
   CXF21(1-NSCAT)=f_21 for current orientation
   CXF22(1-NSCAT)=f_22 for current orientation
   QABS(2)       =Q_abs for two incident polarizations
   QABSUM(2)     =weighted sum of Qabs over previous orientations
   QBKSCA(2)     =Q_bk for two incident polarizations
   QBKSUM(2)     =weighted sum of Q_bk over previous orientations
   QEXSUM(2)     =weighted sum of Q_ext over previous orientations
   QEXT(2)       =Q_ext for two incident polarizations
   QPHA(2)       =Q_pha for two incident polarizations
   QPHSUM(2)     =weighted sum of Q_ph over previous orientations
   QSCAG(3,2)    =Q_pr vector for two incident polarizations
   QSCAT(2)      =Q_sca for two incident polarizations
   QSCGSUM(3,2)  =weighted sum of Q_pr vector over prev. orients.
   QSCSUM(2)     =weighted sum of Q_sca over previous orientations
   QTRQAB(3,2)   =absorptive part of Q_gamma for two inc. pols.
   QTRQABSUM(3,2)=weighted sum of Q_gamma over previous orientations
   QTRQSC(3,2)   =scattering part of Q_gamma for two inc. pols.
   QTRQSCSUM(3,2)=weighted sum of Q_gamma over previous orientations
   WGTA(ITHETA,IPHI)=weight factor for theta,phi orientation
   WGTB(IBETA)      =weight factor for beta orientation
   SMORI(1-NSCAT,4,4)=weighted sum of Mueller matrix over previous orientations
 If IORTH=1, returns:
   S1111(1-NSCAT)=updated weighted sum of |f_11|^2 over NSCAT scattering directions
   S2121(1-NSCAT)=updated weighted sum of |f_21|^2
   CX1121(1-NSCAT)=updated weighted summ of f_11*conjg(f_21)

If IORTH=2, returns:
   SM(1-NSCAT,4,4)=Mueller matrix for current orientation, and NSCAT scattering directions
   CXS1(1-NSCAT)=amplitude scattering matrix element S_1 for current orientation
   CXS2(1-NSCAT)=amplitude scattering matrix element S_2 for current orientation
   CXS3(1-NSCAT)=amplitude scattering matrix element S_3 for current orientation
   CXS4(1-NSCAT)=amplitude scattering matrix element S_4 for current orientations
   QABSUM(2)     =updated weighted sum of Q_abs
   QBKSUM(2)     =updated weighted sum of Q_bk
   QEXSUM(2)     =updated weighted sum of Q_ext
   QSCGSUM(3,2)  =updated weighted sum of Q_pr vector
   QSCSUM(2)     =updated weighted sum of Q_sca
   QTRQABSUM(3,2)=updated weighted sum of absorptive contribution to Q_gamma
   QTRQSCSUM(3,2)=updated weighted sum of scattering contribution to Q_gamma

   SMORI(1-NSCAT,4,4)=updated weighted sum of Mueller matrix elements

History:
Fortran versions history removed.

Copyright (C) 1996,1997,1998,2000,2003,2006,2007,2008,2011,2012
              B.T. Draine and P.J. Flatau
This code is covered by the GNU General Public License.
** */

/* **
!*********  Sum scattering properties over orientations ****************
Correspondence to notation of Bohren & Huffman (1983):
Our f_jk correspond to notation of Draine (1988).
For the special case where incident polarization modes 1 and 2 are
arallel and perpendicular to the scattering plane, we have the
relationship between the f_jk and the elements S_j of the amplitude
scattering matrix as defined by Bohren & Huffman (1983) is as follows:
    S_1 = -i*f_22
    S_2 = -i*f_11
    S_3 =  i*f_12
    S_4 =  i*f_21
In this case (incident pol. states parallel,perpendicular to the
scattering plane), the elements of the 4x4 Mueller matrix (see Bohren
Huffman 1983) are related to our f_jk as follows:
    S_11 = [|f_11|^2 + |f_22|^2 + |f_12|^2 + |f_21|^2]/2
    S_12 = [|f_11|^2 + |f_21|^2 - |f_22|^2 - |f_12|^2]/2
    S_13 = -Re[f_11*conjg(f_12) + f_22*conjg(f_21)]
    S_14 =  Im[f_22*conjg(f_21) - f_11*conjg(f_12)]
    S_21 = [|f_11|^2 + |f_12|^2 - |f_22|^2 - |f_21|^2]/2
    S_22 = [|f_11|^2 + |f_22|^2 - |f_21|^2 - |f_12|^2]/2
    S_23 =  Re[f_22*conjg(f_21) - f_11*conjg(f_12)]
    S_24 = -Im[f_11*conjg(f_12) + f_22*conjg(f_21)]
    S_31 = -Re[f_11*conjg(f_21) + f_22*conjg(f_22)]
    S_32 =  Re[f_22*conjg(f_12) - f_22*conjg(f_21)]
    S_33 =  Re[f_22*conjg(f_11) + f_12*conjg(f_21)]
    S_34 =  Im[f_11*conjg(f_22) + f_21*conjg(f_22)]
    S_41 = -Im[f_21*conjg(f_11) + f_22*conjg(f_12)]
    S_42 =  Im[f_22*conjg(f_12) - f_22*conjg(f_11)]
    S_43 =  Im[f_22*conjg(f_11) - f_12*conjg(f_21)]
    S_44 =  Re[f_22*conjg(f_11) - f_12*conjg(f_21)]

Notation internal to this program:
ij.ne.kl: CX_ijkl = \f_ij* \times f_kl  (summed over orientations)
           S_ijij = \f_ij* \times f_ij  (summed over orientations)
4 pure real elements: S1111,S1212,S2121,S2222
8 Complex elements:   CX1112,CX1121,CX1122,CX1221,CX1222,CX2122
4 redundant elts.:    CX1211 = Conjg(CX1112)
                      CX2111 = Conjg(CX1121)
                      CX2112 = Conjg(CX1221)
                      CX2211 = Conjg(CX1122)

In this routine we will carry out fully general calculation of the
4x4 Mueller matrix elements, valid for arbitrary incident polarization
states j=1,2 for which we have the scattering matrix f_ij

First, we compute the amplitude scattering matrix elements S_1,S_2,
S_3,S_4 as defined by Bohren & Huffman:
** */

// Notation:
//        khat_0     = unit vector along incident direction
//        ehat_01    = CXE01 = complex incident polarization vector 1
//        ehat_02    = CXE02 = complex incident polarization vector 2
//        ehat_0perp = incident pol vector perp to scattering plane scattered pol vector perp to scattering plane em2
//        ehat_0para = incident pol vector para to scattering plane
//                   = khat_0 cross ehat_0perp   [conventional def.]
//                   = xhat_LF cross ehat_0perp
//                   = xhat_LF cross [yhat_LF (yhat_LF dot ehat_0perp) + zhat_LF (zhat_LF dot ehat_0perp)]
//                   = - yhat_LF (ehat_0perp dot zhat_LF) + zhat_LF (ehat_0perp dot yhat_LF) - yhat_LF em2_LF(3) + zhat_LF em2_LF(2)
//        em2        = scattered pol vector perp to scattering plane
//        cxa        = conjg(ehat_01) dot yhat_LF
//        cxb        = conjg(ehat_01) dot zhat_LF
//        cxc        = conjg(ehat_02) dot yhat_LF
//        cxd        = conjg(ehat_02) dot zhat_LF
//
// WG=weighting factor for this orientation

	const Complex conei((real)0., (real)1.);
	const real half_ = (real)0.5;
	Complex cxa, cxb, cxc, cxd, cxfac0, cxfac1, cxfac2;
	real fac;
    int nd, k;

	real wg = param->GetOriData()->GetWgtaValue(itheta, iphi) * param->GetOriData()->GetWgtb(ibeta);
	if (param->Iorth() == 2)
	{
		FourArray *myData = new FourArray;
		myData->Alloc(param->Nscat());
		Complex *myS1 = myData->Cxs1();
		Complex *myS2 = myData->Cxs2();
		Complex *myS3 = myData->Cxs3();
		Complex *myS4 = myData->Cxs4();
//
// Compute Complex scattering amplitudes S_1,S_2,S_3,S_4 for this particular target orientation and NSCAT scattering directions:
		switch(jpbc)				// ChB: TODO the code snippets are identical for every jpbc
		{
		case PeriodicNo:
			cxa = param->Cxe01_lf().data[1].conjg();
            cxb = param->Cxe01_lf().data[2].conjg();
            cxc = param->Cxe02_lf().data[1].conjg();
            cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);
			}
			break;

		case PeriodicY:
		case PeriodicZ:
// JPBC = 1 or 2:
// ENSC(1-3,ND) = components of scattering unit vector in Lab Frame
// CXA,CXB = y,z components of incident polarization state 1 in Lab Frame
// CXC,CXD = y,z                                           2 in Lab Frame
			cxa = param->Cxe01_lf().data[1].conjg();
            cxb = param->Cxe01_lf().data[2].conjg();
            cxc = param->Cxe02_lf().data[1].conjg();
            cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);
			}
			break;

		case PeriodicBoth:
//fprintf(stderr, "Getmueller %p\n", cxfData);
//
// JPBC = 3
//     Target is periodic in y and z directions in Lab Frame Allowed scattering directions are identified by scattering order (M,N).  
//     For each allowed (M,N) there is one forward (transmitted) direction and one backward (reflected) direction.
//     Following convention set in subroutine PBCSCAVEC for JPBC=3, it is assumed that NSCAT is even, with the first NSCAT/2 directions 
//     corresponding to transmission, and the remaining NSCAT/2 directions corresponding to reflection
//
// ENSC(1-3,ND) = components of scattering unit vector in Lab Frame
// EM1(1-3,ND) = components of scattering polarization 1 in Lab Frame
// EM2(1-3,ND) = components of scattering polarization 2 in Lab Frame
			cxa = param->Cxe01_lf().data[1].conjg();
			cxb = param->Cxe01_lf().data[2].conjg();
			cxc = param->Cxe02_lf().data[1].conjg();
			cxd = param->Cxe02_lf().data[2].conjg();
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				real cosphi =  em2_lf[nd].data[2];
				real sinphi = -em2_lf[nd].data[1];
				Complex cxaa = cxa * cosphi + cxb * sinphi;
				Complex cxbb = cxb * cosphi - cxa * sinphi;
				Complex cxcc = cxc * cosphi + cxd * sinphi;
				Complex cxdd = cxd * cosphi - cxc * sinphi;
				myS1[nd] = -conei * (cxfData->Cx21(nd) * cxbb + cxfData->Cx22(nd) * cxdd);
				myS2[nd] = -conei * (cxfData->Cx11(nd) * cxaa + cxfData->Cx12(nd) * cxcc);
				myS3[nd] =  conei * (cxfData->Cx11(nd) * cxbb + cxfData->Cx12(nd) * cxdd);
				myS4[nd] =  conei * (cxfData->Cx21(nd) * cxaa + cxfData->Cx22(nd) * cxcc);

//fprintf(stderr, "%lf %lf %lf %lf %lf %lf %lf %lf\n", cxfData->Cx11(nd).re, cxfData->Cx11(nd).im, cxfData->Cx12(nd).re, cxfData->Cx12(nd).im, 
//		 cxfData->Cx21(nd).re, cxfData->Cx21(nd).im, cxfData->Cx22(nd).re, cxfData->Cx22(nd).im);
//fprintf(stderr, "%lf %lf %lf %lf %lf %lf %lf %lf\n", myS1[nd].re, myS1[nd].im, myS2[nd].re, myS2[nd].im, myS3[nd].re, myS3[nd].im, myS4[nd].re, myS4[nd].im);

			}
			break;

		default:
			break;
		}
//
// if JPBC=1,2,3 (target periodic in y, z, or y and z directions):
// Check for special case: JPBC=3 (2-d target) and forward scattering wit
// ORDERM=ORDERN=0.  For this case we need to add incident wave to
// S_1 and S_2.
// Note that S_1 and S_2 are defined such that for M=N=0 we change
// iS_1 -> iS_1 +1  and iS_2 -> iS_2 +1
//  S_1 ->  S_1 -i       S_2 ->  S_2 -i
// note that CXS1 and CXS2 have yet to be multiplied by factor
// 2*pi/(ak1*aksr(1,nd)*pyddx*pzddx)
		if (jpbc == PeriodicBoth)
		{
			for(nd=0; nd<param->Nscat() / 2; ++nd)
			{
				if ((nint_(orderm[nd]) == 0) && (nint_(ordern[nd]) == 0))
				{
// Zero-degree forward-scattering need to add incident wave to radiated wave
// 2012.04.26 (BTD) change
// !                  CXFAC0=AKS_TF(1,ND)*AK1*PYDDX*PZDDX/(2._WP*PI)
					cxfac0 = Complex(Fabs(aks_tf[nd].data[0]) * ak1 * pyddx * pzddx / TwoPi, (real)0.);
// ! 2012.04.25 (BTD): for reasons not understood, incident wave added for S2 has different sign from S1
// !                   ... does this indicate a sign mistake in calculation of either S1 or S2?
// !                   ... is it possible that there is an error in eq. 68 of Draine & Flatau 2008?. Something like this could
// 							arise from a 180deg shift in directions between
// !                       the incident and scattered "parallel" basis vectors, or between the incident and scattered "perpendicular" basis vectors (should check for this in output files!)
// !                   This appears to indicate that for JPBC=3 the
// !                   sign of either CXS1 or CXS2 is incorrect
// !                   The Mueller matrix elements S11, S22, S12, and S21 appear
// !                   to be correct, but they would not be affected by
// !                   a sign error in either CXS1 or CXS2
// !                   Elements S13,S14,S23,S24,S31,S32,S33,S34,S41,S42,S43,S44
// !                   would be sensitive to a sign error, and it would be
// !                   a good idea to find a way to test them.
					myS1[nd] -= cxfac0;
					myS2[nd] += cxfac0;

//fprintf(stderr, "%d %lf %lf\n", nd, cxfac0.re, cxfac0.im);

				}
			}
		}
//
// Calculation of scattering amplitudes CXS1, CXS2, CXS3, CXS4 is complete. 
// Now compute Mueller matrix elements for this particular target orientation:

		int index;
		for(nd=0; nd<param->Nscat(); ++nd)
		{
			index = 16 * nd;
			sm[index +  0] = half_ * (myS1[nd] * myS1[nd].conjg() + myS2[nd] * myS2[nd].conjg() + myS3[nd] * myS3[nd].conjg() + myS4[nd] * myS4[nd].conjg()).re;
			sm[index +  1] = half_ * (myS2[nd] * myS2[nd].conjg() - myS1[nd] * myS1[nd].conjg() + myS4[nd] * myS4[nd].conjg() - myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  2] =         (myS2[nd] * myS3[nd].conjg() + myS1[nd] * myS4[nd]).re;
			sm[index +  3] =         (myS2[nd] * myS3[nd].conjg() - myS1[nd] * myS4[nd]).im;
			sm[index +  4] = half_ * (myS2[nd] * myS2[nd].conjg() - myS1[nd] * myS1[nd].conjg() - myS4[nd] * myS4[nd].conjg() + myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  5] = half_ * (myS2[nd] * myS2[nd].conjg() + myS1[nd] * myS1[nd].conjg() - myS4[nd] * myS4[nd].conjg() - myS3[nd] * myS3[nd].conjg()).re;
			sm[index +  6] =         (myS2[nd] * myS3[nd].conjg() - myS1[nd] * myS4[nd].conjg()).re;
			sm[index +  7] =         (myS2[nd] * myS3[nd].conjg() + myS1[nd] * myS4[nd].conjg()).im;
			sm[index +  8] =         (myS2[nd] * myS4[nd].conjg() + myS1[nd] * myS3[nd].conjg()).re;
			sm[index +  9] =         (myS2[nd] * myS4[nd].conjg() - myS1[nd] * myS3[nd].conjg()).re;
			sm[index + 10] =         (myS1[nd] * myS2[nd].conjg() + myS3[nd] * myS4[nd].conjg()).re;
			sm[index + 11] =         (myS2[nd] * myS1[nd].conjg() + myS4[nd] * myS3[nd].conjg()).im;
			sm[index + 12] =         (myS4[nd] * myS2[nd].conjg() + myS1[nd] * myS3[nd].conjg()).im;
			sm[index + 13] =         (myS4[nd] * myS2[nd].conjg() - myS1[nd] * myS3[nd].conjg()).im;
			sm[index + 14] =         (myS1[nd] * myS2[nd].conjg() - myS3[nd] * myS4[nd].conjg()).im;
			sm[index + 15] =         (myS1[nd] * myS2[nd].conjg() - myS3[nd] * myS4[nd].conjg()).re;
		}
//
		real fac0 = (real)0.;
		if (jpbc != PeriodicNo)
		{
			switch(jpbc)
			{
			case PeriodicY:							// Prepare to calculate S^{(1d)} for target with 1-d periodicity in y
				fac0 = TwoPi / (ak1 * pyddx * pyddx);
				break;

			case PeriodicZ:							// Prepare to calculate S^{(1d)} for target with 1-d periodicity in z
				fac0 = TwoPi / (ak1 * pzddx * pzddx);
				break;

			case PeriodicBoth:						// Prepare to calculate S^{(2d)} for target with periodicity in y and z
				fac0 = TwoPi / (ak1 * pyddx * pzddx);
				fac0 = fac0 * fac0;
				break;

			default:
				break;
			}
//
// k*sin(alpha_s)=component of k_s perpendicular to target
			for(nd=0; nd<param->Nscat(); ++nd)
			{
				switch(jpbc)
				{
				case PeriodicY:
					fac = fac0 / Sqrt(aks_tf[nd].data[0] * aks_tf[nd].data[0] + aks_tf[nd].data[2] * aks_tf[nd].data[2]);
					break;

				case PeriodicZ:
					fac = fac0 / Sqrt(aks_tf[nd].data[0] * aks_tf[nd].data[0] + aks_tf[nd].data[1] * aks_tf[nd].data[1]);
					break;

				case PeriodicBoth:
					fac = fac0 / (aks_tf[nd].data[0] * aks_tf[nd].data[0]);
					break;

				default:
					Errmsg("Fatal", "Getmueller", " invalid jpbc");
					break;
				}
               
				index = 16 * nd;
				for(k=0; k<16; ++k)
				{
					sm[index + k] *= fac;
				}
			}
		}
//
// Augment Mueller matrix for orientational average
		index = 16 * param->Nscat();
		for(nd=0; nd<index; ++nd)
		{
			smori[nd] += sm[nd] * wg;
		}
		delete myData;
	}
	else
	{
// 
// When IORTH=1, cannot compute full Mueller matrix. Compute three scattering properties:
		for(nd=0; nd<param->Nscat(); ++nd)
		{
			s1111[nd]  += (cxfData->Cx11(nd).conjg() * cxfData->Cx11(nd)).re * wg;
			s2121[nd]  += (cxfData->Cx21(nd).conjg() * cxfData->Cx21(nd)).re * wg;
			cx1121[nd] += (cxfData->Cx11(nd).conjg() * cxfData->Cx21(nd)) * wg;
		}
	}
// 
// Now augment sums of QABS,QBKSCA,QEXT,QSCA,G*QSCA over incident directions and polarizations.
	for(int jo=0; jo<param->Iorth(); ++jo)
	{
		sumPackage.Qext().Qsum1()[jo]  += sumPackage.Qext().Q()[jo] * wg;
		sumPackage.Qabs().Qsum1()[jo]  += sumPackage.Qabs().Q()[jo] * wg;
		sumPackage.Qbksca().Qsum1()[jo] += sumPackage.Qbksca().Q()[jo] * wg;
		sumPackage.Qpha().Qsum1()[jo] += sumPackage.Qpha().Q()[jo] * wg;
		sumPackage.Qsca().Qsum1()[jo] += sumPackage.Qsca().Q()[jo] * wg;
		sumPackage.Qscag2().Qsum1()[jo] += sumPackage.Qscag2().Q()[jo] * wg;
        sumPackage.Qscag().Qsum1()[jo] += sumPackage.Qscag().Q()[jo] * wg;
		if (DDscatParameters::GetInstance()->Cmdtrq() == TorqMethod_DOTORQ)
		{
			sumPackage.Qtrqab().Qsum1()[jo] += sumPackage.Qtrqab().Q()[jo] * wg;
			sumPackage.Qtrqsc().Qsum1()[jo] += sumPackage.Qtrqsc().Q()[jo] * wg;
		}
	}
}
Example #20
0
static inline Lisp_Object
_ase_metric_euclidean_1dim_fast(Lisp_Object a, Lisp_Object b)
{
	return Fabs(ent_binop(ASE_BINARY_OP_DIFF, a, b));
}
Example #21
0
    virtual void solve(int steps = 100000, T tolerance = (T)1e-6){
      cgfassert(this->mat->getWidth() == this->b->getSize());
      cgfassert(this->mat->getWidth() == this->mat->getHeight());
      cgfassert(this->mat->getWidth() == this->x->getSize());

      this->iterations = 0;

      for(int i=0;i<this->mat->getHeight();i++){
        (*C)[i] = (T)1.0/Sqrt(Fabs((*this->mat)[i][i]));
      }

      /*r = Ax*/
      spmv(*r, *(this->mat), *(this->x));

      /*r = b - r*/;
      Vector<T>::sub(*r, *(this->b), *r);

      /*w = C * r*/
      Vector<T>::mul(*w, *C, *r);

      /*v = C * w*/
      Vector<T>::mul(*v, *C, *w);

      /*s1 = w * w*/
      Vector<T>::mul(*scratch1, *w, *w);
      T alpha;

      /*alpha = sum(s1)*/
      alpha = scratch1->sum();

      int k=0;

      while(k<steps){
        /*s1 = v * v*/
        this->iterations++;
        Vector<T>::mul(*scratch1, *v, *v);
        T residual;

        residual = scratch1->sum();
        if(Sqrt(Fabs(residual)) < (tolerance*bnorm /*+ tolerance*/)){
          warning("CG::Success in %d iterations, %10.10e, %10.10e", k, residual, Sqrt(residual));
          return;
        }

        /*u = A*v*/
        spmv(*u, *(this->mat), *v);

        /*s1 = v * u*/
        Vector<T>::mul(*scratch1, *v, *u);
        T divider;

        /*divider = sum(s1)*/
        divider = scratch1->sum();

        T t = alpha/divider;

        /*x = x + t*v*/
        /*r = r - t*u*/
        /*w = C * r*/
        Vector<T>::mfadd(*(this->x),  t, *v, *(this->x));
        Vector<T>::mfadd(*r, -t, *u, *r);
        Vector<T>::mul  (*w, *C, *r);

        /*s1 = w*w*/
        Vector<T>::mul(*scratch1, *w, *w);

        /*beta = sum(s1)*/
        T beta = scratch1->sum();
#if 1
        if(beta < (tolerance*bnorm + tolerance)){
          T rl = r->length2();
          if(Sqrt(rl)<(tolerance*bnorm + tolerance)){
            warning("CG::Success in %d iterations, %10.10e, %10.10e", k, rl,
                    Sqrt(Fabs(rl)));
            return;
          }
        }
#endif

        T s = beta/alpha;

        /*s1 = C * w*/
        Vector<T>::mul(*scratch1, *C, *w);
        /*v = s1 + s * v*/
        Vector<T>::mfadd(*v, s, *v, *scratch1);
        alpha = beta;
        k++;
      }
      message("Unsuccesfull");
      throw new SolutionNotFoundException(__LINE__, __FILE__,
                                          "Number of iterations exceeded.");

    }
State collideObjects(PhysicsObject* a, PhysicsObject* b){
	State state;
	state.deltaAngVel = 0;
	state.deltaPosition = pointMake(0, 0);
	state.deltaVel = pointMake(0, 0);
	
	CollisionPair pairs[2*PHYSICS_OBJECT_MAXIMUM_POINTS];
	if(!coarseCollision(a, b)){
		return state;
	}
	
	//if a coarse collision happened, we will search for a refined one in each of A's edges.
	//in this step we try to find every point where B has hitted A and A has hitted B
	int Acurrent, Anext, Abefore, Bcurrent, Bnext, pairCount=0;
	
	//first case---------------------------------------------------------------------------
	/* 
	 PA1     PA3
	 \      /
	  \    /
  PB2---------PB1
	    \/
		PA2
	 
	V=A --=B
	*/
	for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a);
		Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a);
		Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a);
		Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);

		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) {
			/*for each edge of B, we will find if any of the edges are hitted by both
			 edges defined before, if thats the case, then A hitted B on that point
			 If both edges of A hitted more than one edge of B, we will keep the highest
			 depth*/
			Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1;
			Point PB1 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b);
			Point PB2 = worldPosition(b->format.polygonInfo.points[Bnext], *b);
			Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y);
			Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossBI1 = B.x*I1.y-B.y*I1.x;
			float crossBI2 = B.x*I2.y-B.y*I2.x;
			float crossAI1 = A1.x*I1.y-A1.y*I1.x;
			float crossAI2 = A2.x*I2.y-A2.y*I2.x;
			float crossBA1 = B.x*A1.y-B.y*A1.x;
			float crossBA2 = B.x*A2.y-B.y*A2.x;
			
			crossBA1=crossBA1==0?0.0001:crossBA1;
			crossBA2=crossBA2==0?0.0001:crossBA2;
			
			float t1 = crossAI1/crossBA1;
			float w1 = crossBI1/crossBA1;
			float t2 = crossAI2/crossBA2;
			float w2 = crossBI2/crossBA2;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				
				Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5);
				float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y;
				depth = -depth;
				if(Fabs(depth)>Fabs(pairs[pairCount].depth)){
					pairs[pairCount].depth = depth;
					pairs[pairCount].normal = normal;
					pairs[pairCount].location=collisionPoint;
				}
			}
		}
		if(Fabs(pairs[pairCount].depth)>0){
			pairCount++;
		}
	}
	
	//second case---------------------------------------------------------------------------
	/*
	 PA1     PA3
	 \      /
	  \    /
  PB2---------PB1
	    \/
		PA2
	 
	 V=B --=A
	 */
	//Although we did not change the names, A variables now refers to B while B variables refer to A
	for (Acurrent=0; Acurrent<b->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==b->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?b->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(b->format.polygonInfo.points[Abefore],*b);
		Point PA2 = worldPosition(b->format.polygonInfo.points[Acurrent],*b);
		Point PA3 = worldPosition(b->format.polygonInfo.points[Anext],*b);
		Vector A1 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A2 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);
		
		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<a->format.polygonInfo.count; Bcurrent++) {
			/*for each edge of A, we will find if any of the edges are hitted by both
			 edges defined before, if thats the case, then A hitted B on that point
			 If both edges of B hitted more than one edge of A, we will keep the highest
			 depth*/
			Bnext = Bcurrent==a->format.polygonInfo.count-1?0:Bcurrent+1;
			Point PB1 = worldPosition(a->format.polygonInfo.points[Bcurrent], *a);
			Point PB2 = worldPosition(a->format.polygonInfo.points[Bnext], *a);
			Vector B = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector I1 = pointMake(PB1.x-PA1.x, PB1.y-PA1.y);
			Vector I2 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossBI1 = B.x*I1.y-B.y*I1.x;
			float crossBI2 = B.x*I2.y-B.y*I2.x;
			float crossAI1 = A1.x*I1.y-A1.y*I1.x;
			float crossAI2 = A2.x*I2.y-A2.y*I2.x;
			float crossBA1 = B.x*A1.y-B.y*A1.x;
			float crossBA2 = B.x*A2.y-B.y*A2.x;
			
			crossBA1=crossBA1==0?0.0001:crossBA1;
			crossBA2=crossBA2==0?0.0001:crossBA2;
			
			float t1 = crossAI1/crossBA1;
			float w1 = crossBI1/crossBA1;
			float t2 = crossAI2/crossBA2;
			float w2 = crossBI2/crossBA2;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				
				Vector normal = rotateVector(B, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake(((PA1.x+w1*A1.x)+(PA2.x+w2*A2.x))*0.5, ((PA1.y+w1*A1.y)+(PA2.y+w2*A2.y))*0.5);
				float depth = (PA2.x-collisionPoint.x)*normal.x+(PA2.y-collisionPoint.y)*normal.y;
				if(Fabs(depth)>Fabs(pairs[pairCount].depth)){
					pairs[pairCount].depth = depth;
					pairs[pairCount].normal = normal;
					pairs[pairCount].location=collisionPoint;
				}
			}
		}
		if(Fabs(pairs[pairCount].depth)>0){
			pairCount++;
		}
	}
	
	//third case---------------------------------------------------------------------------
	/*
	PA1     PA3
	 \  PB2 /
	  \ /\ /
       X  X
	  / \/ \
	 /  PA2 \
   PB3      PB1
	 
	 V=A /\=B
	 */
	int Bbefore;
	for (Acurrent=0; Acurrent<a->format.polygonInfo.count; Acurrent++) {
		/*Given 3 sequenced vertex, we create two vectors, one from the
		 first to the second vertex and other from the second to the
		 third vertex.*/
		Anext = Acurrent==a->format.polygonInfo.count-1?0:Acurrent+1;
		Abefore = Acurrent==0?a->format.polygonInfo.count-1:Acurrent-1;
		Point PA1 = worldPosition(a->format.polygonInfo.points[Abefore],*a);
		Point PA2 = worldPosition(a->format.polygonInfo.points[Acurrent],*a);
		Point PA3 = worldPosition(a->format.polygonInfo.points[Anext],*a);
		Vector A12 = pointMake(PA2.x-PA1.x, PA2.y-PA1.y);
		Vector A23 = pointMake(PA3.x-PA2.x, PA3.y-PA2.y);
		
		pairs[pairCount].depth = 0;
		pairs[pairCount].normal = pointMake(0, 0);
		for (Bcurrent = 0; Bcurrent<b->format.polygonInfo.count; Bcurrent++) {
			/*for each pair of edge of B, we will find if any of the edges are hitted as shown above*/
			Bnext = Bcurrent==b->format.polygonInfo.count-1?0:Bcurrent+1;
			Bbefore = Bcurrent==0?b->format.polygonInfo.count-1:Bcurrent-1;
			Point PB1 = worldPosition(b->format.polygonInfo.points[Bbefore], *b);
			Point PB2 = worldPosition(b->format.polygonInfo.points[Bcurrent], *b);
			Point PB3 = worldPosition(b->format.polygonInfo.points[Bnext], *b);
			Vector B12 = pointMake(PB2.x-PB1.x, PB2.y-PB1.y);
			Vector B23 = pointMake(PB3.x-PB2.x, PB3.y-PB2.y);
			Vector IA12B23 = pointMake(PB2.x-PA1.x, PB2.y-PA1.y);
			Vector IA23B12 = pointMake(PB1.x-PA2.x, PB1.y-PA2.y);
			
			float crossB12I = B12.x*IA23B12.y-B12.y*IA23B12.x;
			float crossB23I = B23.x*IA12B23.y-B23.y*IA12B23.x;
			float crossA12I = A12.x*IA12B23.y-A12.y*IA12B23.x;
			float crossA23I = A23.x*IA23B12.y-A23.y*IA23B12.x;
			float crossB12A23 = B12.x*A23.y-B12.y*A23.x;
			float crossB23A12 = B23.x*A12.y-B23.y*A12.x;
			
			crossB23A12=crossB23A12==0?0.0001:crossB23A12;
			crossB12A23=crossB12A23==0?0.0001:crossB12A23;
			
			float t1 = crossA12I/crossB23A12;
			float w1 = crossB23I/crossB23A12;
			float t2 = crossA23I/crossB12A23;
			float w2 = crossB12I/crossB12A23;
			
			if(t1>0 && t1<1 && w1>0 && w1<1 && t2>0 && t2<1 && w2>0 && w2<1){
				//we do have a collision
				Point collision1 = pointMake((PA1.x+w1*A12.x), (PA1.y+w1*A12.y));
				Point collision2 = pointMake((PA2.x+w2*A23.x), (PA2.y+w2*A23.y));
				Vector c12 = pointMake(collision2.x-collision1.x, collision2.y-collision1.y);
				Vector normal = rotateVector(c12, -PI*0.5); //rotate the edge by -90 degrees, so that it points outside
				normalizePoint(&normal);
				Point collisionPoint=pointMake((collision1.x+collision2.x)*0.5, (collision1.y+collision2.y)*0.5);
				float depth = (PA2.x-PB2.x)*normal.x+(PA2.y-PB2.y)*normal.y;
				depth = -depth;
				pairs[pairCount].depth = depth;
				pairs[pairCount].normal = normal;
				pairs[pairCount].location=collisionPoint;
				pairCount++;
			}
		}
	}
	
	int currentCollision;
	//solves the physics part ot the collision for each collision that has happened

	for (currentCollision =0; currentCollision<pairCount; currentCollision++) {
		State st = physicsResolution(a,b,pairs[currentCollision]);
		state.deltaAngVel += st.deltaAngVel;
		state.deltaPosition=pointMake(st.deltaPosition.x+state.deltaPosition.x, st.deltaPosition.y+state.deltaPosition.y);
		state.deltaVel=pointMake(st.deltaVel.x+state.deltaVel.x, st.deltaVel.y+state.deltaVel.y);
	}
	state.deltaAngVel += a->angularVelocity;
	state.deltaVel = pointMake(a->linearVelocity.x+state.deltaVel.x, a->linearVelocity.y+state.deltaVel.y);
	state.deltaPosition = pointMake(a->position.x+state.deltaPosition.x, a->position.y+state.deltaPosition.y);
	
	return state;
}
Example #23
0
)
*
0.5f
;
v3Extent
.
z
=
Fabs
(
llllll\
ll\
l\

.
z
-
lO\
OOOOOOO\
O\

.
z
)
*
0.5f
;
}
AABB
AABB
::
operator\
Example #24
0
// determine centroid XCM,YCM,ZCM
// If A/d_x is near an odd int, XCM=0, even, 0.5
// If B/d_y is near an odd int, YCM=0, even, 0.5
// If B/d_z is near an odd int, ZCM=0, even, 0.5
void Tarcyl::PreSizer(int jx, int jy, int jz)
{
	xcm = (jx%2) ? zero_ : half_;
	ycm = (jy%2) ? zero_ : half_;
	zcm = (jz%2) ? zero_ : half_;

	real r2 = (real)0.25 * shpar[1] * shpar[1];
	minJx =  jx + 1;
	maxJx = -jx;
	minJy =  jy + 1;
	maxJy = -jy;
	minJz =  jz + 1;
	maxJz = -jz;

	switch((int)shpar[2])
	{
		case 1:
			for(int x=-jx; x<=jx+1; ++x)
			{
				real rx2 = twox_ * Fabs(x * dx.data[0] - xcm);
				if (rx2 <= shpar[0])
				{
					for(int y=-jy; y<=jy+1; ++y)
					{
						real ry2 = y * dx.data[1] - ycm;
						ry2 = ry2 * ry2;
						for(int z=-jz; z<=jz+1; ++z)
						{
							real rz2 = z * dx.data[2] - zcm;
							rz2 = rz2 * rz2;
							if (ry2 + rz2 <= r2)
							{
								InternalMinMax(x, y, z);
							}
						}
					}
				}
			}
			break;

		case 2:
			for(int x=-jx; x<=jx+1; ++x)
			{
				real rx2 = x * dx.data[0] - xcm;
				rx2 = rx2 * rx2;
				for(int y=-jy; y<=jy+1; ++y)
				{
					real ry2 = twox_ * Fabs(y * dx.data[1] - ycm);
					if (ry2 <= shpar[0])
					{
						for(int z=-jz; z<=jz+1; ++z)
						{
							real rz2 = z * dx.data[2] - zcm;
							rz2 = rz2 * rz2;
							if (rx2 + rz2 <= r2)
							{
								InternalMinMax(x, y, z);
							}
						}
					}
				}
			}
			break;

		case 3:
			for(int x=-jx; x<=jx+1; ++x)
			{
				real rx2 = x * dx.data[0] - xcm;
				rx2 = rx2 * rx2;
				for(int y=-jy; y<=jy+1; ++y)
				{
					real ry2 = y * dx.data[1] - ycm;
					ry2 = ry2 * ry2;
					if (rx2 + ry2 <= r2)
					{
						for(int z=-jz; z<=jz+1; ++z)
						{
							real rz2 = twox_ * Fabs(z * dx.data[2] - zcm);
							if (rz2 <= shpar[0])
							{
								InternalMinMax(x, y, z);
							}
						}
					}
				}
			}
			break;

		default:
			break;
	}
}
/*
 * Gauss-Sidel smoother for vector:
 *
 * As GS: 
 *   1. exchange off proc data
 *   2. smooth local dof
 *
 * Assumption:
 *   1. unknow dof is vector of dim 3
 *   2. Matrix block for vector is 
 *      | a1  -b   0 |
 *      |  b  a2   0 |
 *      |  0   0  a3 |
 * 
 *  */
void 
mg_GaussSidel_vec(MAT *A, VEC *x, VEC *b, int nsmooth, void *ctx)
{
    INT i, j, k, l, n, *pc, *pc0, *pc_offp, nlocal;
    FLOAT *pd, *pd0, *pd_offp, *vx, *vb;
    size_t *ps; 
    FLOAT sum[Dim], omega = _p->smooth_damp;
#if USE_MPI
    FLOAT *offp_data = NULL;
#endif	/* USE_MPI */

    MagicCheck(VEC, x);
    MagicCheck(VEC, b);
    assert(x == NULL || x->nvec == 1);
    assert(b == NULL || b->nvec == 1);
    if (x != NULL && !x->assembled)
	phgVecAssemble(x);
    if (b != NULL && !b->assembled)
	phgVecAssemble(b);
    
    assert(A->type != PHG_DESTROYED);
    if (!A->assembled)
	phgMatAssemble(A);
    assert(A->type != PHG_MATRIX_FREE);
    phgMatPack(A);

#if USE_MPI
    if (A->cmap->nprocs > 1) {
	offp_data = phgAlloc(A->cinfo->rsize * sizeof(*offp_data));
    }
#endif	/* USE_MPI */

    if (A->cmap->nlocal != A->rmap->nlocal ||
	A->cmap->nlocal != x->map->nlocal  ||
	A->cmap->nlocal != b->map->nlocal)
	phgError(1, "%s:%d: inconsistent matrix-vector.", __FILE__,
		 __LINE__);

    if (A->cmap->nlocal % Dim != 0)
	phgError(1, "%s: assume vector dof of dim 3!\n", __FUNCTION__);

#if USE_MPI
    if (A->cmap->nprocs > 1) {
	phgMapScatterBegin(A->cinfo, x->nvec, x->data, offp_data);
	phgMapScatterEnd(A->cinfo, x->nvec, x->data, offp_data);
    }
#endif	/* USE_MPI */

    /* iteration */
    for (l = 0; l < nsmooth; l++) {
	INT i_start, i_add;

	/* multiply with local data */
	vx = x->data;
	vb = b->data;
	pc0 = A->packed_cols;
	pd0 = A->packed_data;
	ps = A->packed_ind;
	nlocal = A->rmap->nlocal;

	/*
	 * lexicographic order: low to high
	 * Note: low->high and high->low alternatively does not help.
	 * */
	if (TRUE || l % 2 == 0) {
	    i_start = 0;
	    i_add = Dim;
	} else {
	    i_start = nlocal - Dim;
	    i_add = -Dim;
	}

	//for (i = i_start; i < A->rmap->nlocal && i >= 0;  i += i_add) {
	for (i = 0; i < nlocal ;  i += Dim) {
	    INT jcol;
	    FLOAT aa[Dim][Dim], det, dx[Dim];

	    memset(aa, 0, sizeof(aa));
	    sum[0] = vb[i  ];
	    sum[1] = vb[i+1];
	    sum[2] = vb[i+2];

	    /* local data */
	    pc = pc0 + PACK_COL(ps, i);
	    pd = pd0 + PACK_DAT(ps, i);
	    for (k = 0; k < Dim; k++) {
		if ((n = *(pc++)) != 0) {
		    for (j = 0; j < n; j++) {
			jcol = *(pc++);
			if (jcol < i || jcol > i+2) {
			    sum[k] -= *(pd++) * vx[jcol];
			} else { /* offD, jcol = i,i+1,i+2 */
			    aa[k][jcol - i] = *(pd++);
			}
		    }
		}
	    }

	    /* remote data */
	    if (A->cmap->nprocs > 1) {
		pc_offp = pc0 + PACK_COL_OFFP(ps, i, nlocal);
		pd_offp = pd0 + PACK_DAT_OFFP(ps, i, nlocal);
		for (k = 0; k < Dim; k++) {
		    if ((n = *(pc_offp++)) != 0) {
			for (j = 0; j < n; j++) {
			    jcol = *(pc_offp++);
			    sum[k] -= *(pd_offp++) * offp_data[jcol];
			}
		    }
		}
	    }

	    /* solve */
	    det = (aa[0][0] * aa[1][1] - aa[0][1] * aa[1][0]);
	    assert(Fabs(det) > 1e-12);
	    det = 1. / det;
	    dx[0] = (aa[1][1] * sum[0] - aa[0][1] * sum[1]) * det - vx[i  ];
	    dx[1] = (aa[0][0] * sum[1] - aa[1][0] * sum[1]) * det - vx[i+1];
	    dx[2] = (1./aa[2][2] * sum[2]) - vx[i+2];
	    vx[i  ] += omega * dx[0];
	    vx[i+1] += omega * dx[1];
	    vx[i+2] += omega * dx[2];
	}

#if USE_MPI
	if (A->cmap->nprocs > 1) {
	    phgMapScatterBegin(A->cinfo, x->nvec, x->data, offp_data);
	    phgMapScatterEnd(A->cinfo, x->nvec, x->data, offp_data);
	}
#endif	/* USE_MPI */
    }


#if USE_MPI
    phgFree(offp_data);
#endif	/* USE_MPI */

    return;
}
Example #26
0
//------------------------------------------------------------------------
void curve3_div::recursive_bezier(scalar x1, scalar y1, scalar x2, scalar y2, scalar x3, scalar y3, unsigned int level)
{
    if (level > curve_recursion_limit) {
        return;
    }

    // Calculate all the mid-points of the line segments
    //----------------------
    scalar x12   = (x1 + x2) / 2;
    scalar y12   = (y1 + y2) / 2;
    scalar x23   = (x2 + x3) / 2;
    scalar y23   = (y2 + y3) / 2;
    scalar x123  = (x12 + x23) / 2;
    scalar y123  = (y12 + y23) / 2;

    scalar dx = x3-x1;
    scalar dy = y3-y1;
    scalar d = Fabs(((x2 - x3) * dy - (y2 - y3) * dx));
    scalar da;

    if (d > curve_collinearity_epsilon) {
        // Regular case
        //-----------------
        if (d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            // If the curvature doesn't exceed the distance_tolerance value
            // we tend to finish subdivisions.
            //----------------------
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x123, y123));
                return;
            }

            // Angle & Cusp Condition
            //----------------------
            da = Fabs(Atan2(y3 - y2, x3 - x2) - Atan2(y2 - y1, x2 - x1));
            if (da >= PI)
                da = _2PI - da;

            if (da < m_angle_tolerance) {
                // Finally we can stop the recursion
                //----------------------
                m_points.add(vertex_s(x123, y123));
                return;
            }
        }
    } else {
        // Collinear case
        //------------------
        da = dx*dx + dy*dy;
        if (da == 0) {
            d = calc_sq_distance(x1, y1, x2, y2);
        } else {
            d = ((x2 - x1)*dx + (y2 - y1)*dy) / da;
            if (d > 0 && d < 1) {
                // Simple collinear case, 1---2---3
                // We can leave just two endpoints
                return;
            }

            if (d <= 0)
                d = calc_sq_distance(x2, y2, x1, y1);
            else if (d >= 1)
                d = calc_sq_distance(x2, y2, x3, y3);
            else
                d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy);
        }

        if (d < m_distance_tolerance_square) {
            m_points.add(vertex_s(x2, y2));
            return;
        }
    }

    // Continue subdivision
    //----------------------
    recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1);
    recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1);
}
Example #27
0
void Tarcyl::Allocator(void) // A=cylinder length/d, B=cylinder diameter/d
{
	int jlo, jhi;
	int curSize  = nx * ny;
	ixyz.Dimension(curSize, 3);
	real r2 = (real)0.25 * shpar[1] * shpar[1];
//
	switch((int)shpar[2])
	{
		case 1:
			jlo = maxJx;
			jhi = minJx;
			nat0 = 0;
			for(int jx=minJx; jx<=maxJx; ++jx)
			{
				real rx2 = twox_ * Fabs(jx * dx.data[0] - xcm);
				if (rx2 <= shpar[0])
				{
					for(int jy=minJy; jy<=maxJy; ++jy)
					{
						real ry2 = jy * dx.data[1] - ycm;
						ry2 = ry2 * ry2;
						for(int jz=minJz; jz<=maxJz; ++jz)
						{
							real rz2 = jz * dx.data[2] - zcm;
							rz2 = rz2 * rz2;
							if (ry2 + rz2 <= r2)
							{
								if (nat0 >= curSize)
								{
									ixyz.Extend(nz);
									curSize = ixyz.GetSize(0);
								}
								ixyz.Fill3(nat0, jx, jy, jz);
								int index = GetLinearAddress(nat0);
								Composer(index, 0);
								iocc[index] = true;
								if (jx < jlo) 
									jlo = jx;
								if (jx > jhi) 
									jhi = jx;
								++nat0;
							}
						}
					}
				}
			}
			break;

		case 2:
			jlo = maxJy;
			jhi = minJy;
			nat0 = 0;
			for(int jx=minJx; jx<=maxJx; ++jx)
			{
				real rx2 = jx * dx.data[0] - xcm;
				rx2 = rx2 * rx2;
				for(int jy=minJy; jy<=maxJy; ++jy)
				{
					real ry2 = twox_ * Fabs(jy * dx.data[1] - ycm);
					if (ry2 <= shpar[0])
					{
						for(int jz=minJz; jz<=maxJz; ++jz)
						{
							real rz2 = jz * dx.data[2] - zcm;
							rz2 = rz2 * rz2;
							if (rx2 + rz2 <= r2)
							{
								if (nat0 >= curSize)
								{
									ixyz.Extend(nz);
									curSize = ixyz.GetSize(0);
								}
								ixyz.Fill3(nat0, jx, jy, jz);
								int index = GetLinearAddress(nat0);
								Composer(index, 0);
								iocc[index] = true;
								if (jy < jlo)
									jlo = jy;
								if (jy > jhi) 
									jhi = jy;
								++nat0;
							}
						}
					}
				}
			}
			break;

		case 3:
			jlo = maxJz;
			jhi = minJz;
			nat0 = 0;
			for(int jx=minJx; jx<=maxJx; ++jx)
			{
				real rx2 = jx * dx.data[0] - xcm;
				rx2 = rx2 * rx2;
				for(int jy=minJy; jy<=maxJy; ++jy)
				{
					real ry2 = jy * dx.data[1] - ycm;
					ry2 = ry2 * ry2;
					if (rx2 + ry2 <= r2)
					{
						for(int jz=minJz; jz<=maxJz; ++jz)
						{
							real rz2 = twox_ * Fabs(jz * dx.data[2] - zcm);
							if (rz2 <= shpar[0])
							{
								if (nat0 >= curSize)
								{
									ixyz.Extend(nz);
									curSize = ixyz.GetSize(0);
								}
								ixyz.Fill3(nat0, jx, jy, jz);
								int index = GetLinearAddress(nat0);
								Composer(index, 0);
								iocc[index] = true;
								if (jz < jlo) 
									jlo = jz;
								if (jz > jhi) 
									jhi = jz;
			                    ++nat0;
							}
						}
					}
				}
			}
			break;

		default:
			break;
	}
	int nlay = jhi - jlo + 1;
	ixyz.Close(nat0);
//
// NLAY = number of layers in cylinder
// NFAC = number of atoms in slice
	int nfac = nat0 / nlay;
//
// REFF2=effective radius**2 of disk
	real reff2 = (real)nfac / Pi;
//
// ASPR=aspect ratio (length/diameter)
	real aspr = half_ * (real)nlay / Sqrt(reff2);
//
// Description
	sprintf(freeDescr, " Cyl.prism, NAT=%7d NFAC=%4d NLAY=%4d asp.ratio=%lf", nat0, nfac, nlay, aspr);
}
Example #28
0
void curve4_div::recursive_bezier(scalar x1, scalar y1, scalar x2, scalar y2, scalar x3, scalar y3, scalar x4, scalar y4, unsigned int level)
{
    if (level > curve_recursion_limit) {
        return;
    }

    // Calculate all the mid-points of the line segments
    //----------------------
    scalar x12   = (x1 + x2) / 2;
    scalar y12   = (y1 + y2) / 2;
    scalar x23   = (x2 + x3) / 2;
    scalar y23   = (y2 + y3) / 2;
    scalar x34   = (x3 + x4) / 2;
    scalar y34   = (y3 + y4) / 2;
    scalar x123  = (x12 + x23) / 2;
    scalar y123  = (y12 + y23) / 2;
    scalar x234  = (x23 + x34) / 2;
    scalar y234  = (y23 + y34) / 2;
    scalar x1234 = (x123 + x234) / 2;
    scalar y1234 = (y123 + y234) / 2;


    // Try to approximate the full cubic curve by a single straight line
    //------------------
    scalar dx = x4-x1;
    scalar dy = y4-y1;

    scalar d2 = Fabs(((x2 - x4) * dy - (y2 - y4) * dx));
    scalar d3 = Fabs(((x3 - x4) * dy - (y3 - y4) * dx));
    scalar da1, da2, k;

    switch((int(d2 > curve_collinearity_epsilon) << 1) + int(d3 > curve_collinearity_epsilon))
    {
    case 0:
        // All collinear OR p1==p4
        //----------------------
        k = dx*dx + dy*dy;
        if (k == 0) {
            d2 = calc_sq_distance(x1, y1, x2, y2);
            d3 = calc_sq_distance(x4, y4, x3, y3);
        } else {
            k   = 1 / k;
            da1 = x2 - x1;
            da2 = y2 - y1;
            d2  = k * (da1*dx + da2*dy);
            da1 = x3 - x1;
            da2 = y3 - y1;
            d3  = k * (da1*dx + da2*dy);
            if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) {
                // Simple collinear case, 1---2---3---4
                // We can leave just two endpoints
                return;
            }

            if (d2 <= 0)
                d2 = calc_sq_distance(x2, y2, x1, y1);
            else if(d2 >= 1)
                d2 = calc_sq_distance(x2, y2, x4, y4);
            else
                d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy);

            if (d3 <= 0)
                d3 = calc_sq_distance(x3, y3, x1, y1);
            else if(d3 >= 1)
                d3 = calc_sq_distance(x3, y3, x4, y4);
            else
                d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy);
        }

        if (d2 > d3) {
            if (d2 < m_distance_tolerance_square) {
                m_points.add(vertex_s(x2, y2));
                return;
            }
        } else {
            if (d3 < m_distance_tolerance_square) {
                m_points.add(vertex_s(x3, y3));
                return;
            }
        }
        break;

    case 1:
        // p1,p2,p4 are collinear, p3 is significant
        //----------------------
        if (d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle Condition
            //----------------------
            da1 = Fabs(Atan2(y4 - y3, x4 - x3) - Atan2(y3 - y2, x3 - x2));
            if (da1 >= PI)
                da1 = _2PI - da1;

            if (da1 < m_angle_tolerance) {
                m_points.add(vertex_s(x2, y2));
                m_points.add(vertex_s(x3, y3));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x3, y3));
                    return;
                }
            }
        }
        break;

    case 2:
        // p1,p3,p4 are collinear, p2 is significant
        //----------------------
        if (d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle Condition
            //----------------------
            da1 = Fabs(Atan2(y3 - y2, x3 - x2) - Atan2(y2 - y1, x2 - x1));
            if (da1 >= PI)
                da1 = _2PI - da1;

            if (da1 < m_angle_tolerance) {
                m_points.add(vertex_s(x2, y2));
                m_points.add(vertex_s(x3, y3));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x2, y2));
                    return;
                }
            }
        }
        break;

    case 3:
        // Regular case
        //-----------------
        if ((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) {
            // If the curvature doesn't exceed the distance_tolerance value
            // we tend to finish subdivisions.
            //----------------------
            if (m_angle_tolerance < curve_angle_tolerance_epsilon) {
                m_points.add(vertex_s(x23, y23));
                return;
            }

            // Angle & Cusp Condition
            //----------------------
            k   = Atan2(y3 - y2, x3 - x2);
            da1 = Fabs(k - Atan2(y2 - y1, x2 - x1));
            da2 = Fabs(Atan2(y4 - y3, x4 - x3) - k);
            if (da1 >= PI)
                da1 = _2PI - da1;
            if (da2 >= PI)
                da2 = _2PI - da2;

            if (da1 + da2 < m_angle_tolerance) {
                // Finally we can stop the recursion
                //----------------------
                m_points.add(vertex_s(x23, y23));
                return;
            }

            if (m_cusp_limit != 0.0) {
                if (da1 > m_cusp_limit) {
                    m_points.add(vertex_s(x2, y2));
                    return;
                }

                if (da2 > m_cusp_limit) {
                    m_points.add(vertex_s(x3, y3));
                    return;
                }
            }
        }
        break;
    }

    // Continue subdivision
    //----------------------
    recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1);
    recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
}
Example #29
0
void AbstractTarget::Dsyevj3(Matc3<real> &a, Matc3<real> &q, Vect3<real> &w)
{
/* ** 
----------------------------------------------------------------------
Numerical diagonalization of 3x3 matrcies
Copyright (C) 2006  Joachim Kopp
----------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-13
----------------------------------------------------------------------

----------------------------------------------------------------------
Calculates the eigenvalues and normalized eigenvectors of a symmetric
matrix A using the Jacobi algorithm.
The upper triangular part of A is destroyed during the calculation,
the diagonal elements are read but not destroyed, and the lower
triangular elements are not referenced at all.
----------------------------------------------------------------------
Parameters:
  A: The symmetric input matrix
  Q: Storage buffer for eigenvectors
  W: Storage buffer for eigenvalues
----------------------------------------------------------------------
C++ version was created by Choliy V., 2012.
** */
	const int n = 3;
//
// Initialize Q to the identitity matrix 
// --- This loop can be omitted if only the eigenvalues are desired -
	q.Unity();
//
// Initialize W to diag(A)
	int x, y;
	for(x=0; x<n; ++x)
		w.data[x] = a.Data(x, x);
//
// Calculate SQR(tr(A))
	real sd = zero_;
	for(x=0; x<n; ++x)
		sd += Fabs(w.data[x]);
	sd = sd*sd;
//
// Main iteration loop
	int i;
	for(i=0; i<50; ++i)
	{
//
// Test for convergence
		real so = zero_;
		for(x=0; x<n; ++x)
			for(y=x+1; y<n; ++y)
				so += Fabs(a.Data(x, y));
		if (so == zero_)
		{
			fprintf(stderr, "Dsyevj3 converged.\n");
			return;
		}

		real thresh = (i < 3) ? (real)0.2*so/(n*n) : zero_;
//        
// Do sweep
		real t, theta;
		for(x=0; x<n; ++x)
		{
			for(y=x+1; y<n; ++y)
			{
				real g = (real)100.0*(Fabs(a.Data(x,y)));
				if ((i > 3) && (Fabs(w.data[x])+g == Fabs(w.data[x])) && (Fabs(w.data[y])+g == Fabs(w.data[y])))
					a.Data(x,y) = zero_;
				else
				{
					if (Fabs(a.Data(x,y)) > thresh)							// Calculate Jacobi transformation
					{
						real h = w.data[y] - w.data[x];
						if (Fabs(h)+g == Fabs(h))
							t = a.Data(x,y) / h;
						else
						{
							theta = half_*h/a.Data(x,y);
							t = (theta < zero_) ? -(real)1./(Sqrt((real)1. + theta*theta) - theta) : (real)1./(sqrt((real)1. + theta*theta) + theta);
						}
						real c = (real)1./Sqrt((real)1. + t*t);
						real s = t*c;
						real z = t*a.Data(x,y);
// Apply Jacobi transformation
						a.Data(x,y) = zero_;
						w.data[x] -= z;
						w.data[y] += z;
						int r;
						for(r=0; r<x; ++r)
						{
							t = a.Data(r, x);
							a.Data(r, x) = c*t - s*a.Data(r, y);
							a.Data(r, y) = s*t + c*a.Data(r, y);
						}
						for(r=x+1; r<y; ++r)
						{
							t = a.Data(x, r);
							a.Data(x, r) = c*t - s*a.Data(r, y);
							a.Data(r, y) = s*t + c*a.Data(r, y);
						}
						for(r=y+1; r<n; ++r)
						{
							t = a.Data(x, r);
							a.Data(x, r) = c*t - s*a.Data(y, r);
							a.Data(y, r) = s*t + c*a.Data(y, r);
						}
// Update eigenvectors
// --- This loop can be omitted if only the eigenvalues are desired
						for(r=0; r<n; ++r)
						{
							t = q.Data(r,x);
							q.Data(r,x) = c*t - s*q.Data(r,y);
							q.Data(r,y) = s*t + c*q.Data(r,y);
						}
					}
				}
			}
		}
	}
	fprintf(stderr, ">DSYEVJ3: No convergence.\n");
}
 static int calculate(int x, int y, int d)
 {
     return uround(Fabs(Atan2(INT_TO_SCALAR(y), INT_TO_SCALAR(x))) * INT_TO_SCALAR(d) * _1divPI);
 }