Ejemplo n.º 1
0
void gldraw(const std::vector<float3> &verts, const std::vector<int3> &tris)
{
	glBegin(GL_TRIANGLES);
	glColor4f(1, 1, 1, 0.25f);
	for (auto t : tris)
	{
		auto n = TriNormal(verts[t[0]], verts[t[1]], verts[t[2]]);
		glNormal3fv(n); auto vn = vabs(n);
		int k = argmax(&vn.x, 3);
		for (int j = 0; j < 3; j++)
		{
			const auto &v = verts[t[j]];
			glTexCoord2f(v[(k + 1) % 3], v[(k + 2) % 3]);
			glVertex3fv(v);
		}
	}
	glEnd();
}
Ejemplo n.º 2
0
msym_error_t partitionEquivalenceSets(int length, msym_element_t *elements[length], msym_element_t *pelements[length], msym_geometry_t g, int *esl, msym_equivalence_set_t **es, msym_thresholds_t *thresholds) {
    
    int ns = 0, gd = geometryDegenerate(g);
    double *e = calloc(length,sizeof(double));
    double *s = calloc(length,sizeof(double));
    
    int *sp = calloc(length,sizeof(int)); //set partition
    int *ss  = calloc(length,sizeof(int)); //set size
    
    double (*ev)[3] = calloc(length,sizeof(double[3]));
    double (*ep)[3] = calloc(length,sizeof(double[3]));
    
    double (*vec)[3] = calloc(length, sizeof(double[3]));
    double *m = calloc(length, sizeof(double));
    
    for(int i = 0;i < length;i++){
        vcopy(elements[i]->v, vec[i]);
        m[i] = elements[i]->m;
    }

    for(int i=0; i < length; i++){
        for(int j = i+1; j < length;j++){
            double w = m[i]*m[j]/(m[i]+m[j]);
            double dist;
            double v[3];
            double proji[3], projj[3];
            
            vnorm2(vec[i],v);
            vproj_plane(vec[j], v, proji);
            vscale(w, proji, proji);
            vadd(proji,ep[i],ep[i]);
            
            vnorm2(vec[j],v);
            vproj_plane(vec[i], v, projj);
            vscale(w, projj, projj);
            vadd(projj,ep[j],ep[j]);
            
            vsub(vec[j],vec[i],v);
            
            dist = vabs(v);
            
            vscale(w/dist,v,v);
            
            vadd(v,ev[i],ev[i]);
            vsub(ev[j],v,ev[j]);
            
            double dij = w*dist; //This is sqrt(I) for a diatomic molecule along an axis perpendicular to the bond with O at center of mass.
            e[i] += dij;
            e[j] += dij;
            
            s[i] += SQR(dij);
            s[j] += SQR(dij);
        }
        vsub(vec[i],ev[i],ev[i]);
        
    }

    for(int i = 0; i < length; i++){
        
        double v[3];
        double w = m[i]/2.0;
        double dist = vabs(elements[i]->v);
        double dii = w*dist;
        vscale(w,elements[i]->v,v);
        vsub(ev[i],v,ev[i]);
        
        // Plane projection can't really differentiate certain types of structures when we add the initial vector,
        // but not doing so will result in huge cancellation errors on degenerate point groups,
        // also large masses will mess up the eq check when this is 0.
        if(gd) vadd(ep[i],v,ep[i]);
        
        e[i] += dii;
        s[i] += SQR(dii);
    }
    for(int i = 0; i < length; i++){
        if(e[i] >= 0.0){
            sp[i] = i;
            for(int j = i+1; j < length;j++){
                if(e[j] >= 0.0){
                    double vabsevi = vabs(ev[i]), vabsevj = vabs(ev[j]), vabsepi = vabs(ep[i]), vabsepj = vabs(ep[j]);
                    double eep = 0.0, eev = fabs((vabsevi)-(vabsevj))/((vabsevi)+(vabsevj)), ee = fabs((e[i])-(e[j]))/((e[i])+(e[j])), es = fabs((s[i])-(s[j]))/((s[i])+(s[j]));
                    
                    if(!(vabsepi < thresholds->zero && vabsepj < thresholds->zero)){
                        eep = fabs((vabsepi)-(vabsepj))/((vabsepi)+(vabsepj));
                    }
                    
                    double max = fmax(eev,fmax(eep,fmax(ee, es)));
                    
                    if(max < thresholds->equivalence && elements[i]->n == elements[j]->n){
                        e[j] = max > 0.0 ? -max : -1.0;
                        sp[j] = i;
                    }
                }
            }
            e[i] = -1.0;
        }
    }
    
    for(int i = 0; i < length;i++){
        int j = sp[i];
        ns += (ss[j] == 0);
        ss[j]++;
    }

    msym_equivalence_set_t *eqs = calloc(ns,sizeof(msym_equivalence_set_t));
    msym_element_t **lelements = elements;
    msym_element_t **pe = pelements;
    
    if(elements == pelements){
        lelements = malloc(sizeof(msym_element_t *[length]));
        memcpy(lelements, elements, sizeof(msym_element_t *[length]));
    }
    
    for(int i = 0, ni = 0; i < length;i++){
        if(ss[i] > 0){
            int ei = 0;
            eqs[ni].elements = pe;
            eqs[ni].length = ss[i];
            for(int j = 0; j < length;j++){
                if(sp[j] == i){
                    double err = (e[j] > -1.0) ? fabs(e[j]) : 0.0;
                    eqs[ni].err = fmax(eqs[ni].err,err);
                    eqs[ni].elements[ei++] = lelements[j];
                }
            }
            pe += ss[i];
            ni++;
        }
    }

    if(elements == pelements){
        free(lelements);
    }
    free(m);
    free(vec);
    free(s);
    free(e);
    free(sp);
    free(ss);
    free(ev);
    free(ep);
    *es = eqs;
    *esl = ns;
    return MSYM_SUCCESS;
}
Ejemplo n.º 3
0
double LabelPosition::getDistanceToPoint( double xp, double yp )
{
    int i;
    int j;

    double mx[4];
    double my[4];

    double dist_min = DBL_MAX;
    double dist;

    for ( i = 0; i < 4; i++ )
    {
        j = ( i + 1 ) % 4;
        mx[i] = ( x[i] + x[j] ) / 2.0;
        my[i] = ( y[i] + y[j] ) / 2.0;
    }

    if ( vabs( cross_product( mx[0], my[0], mx[2], my[2], xp, yp ) / h ) < w / 2 )
    {
        dist = cross_product( x[1], y[1], x[0], y[0], xp, yp ) / w;
        if ( vabs( dist ) < vabs( dist_min ) )
            dist_min = dist;

        dist = cross_product( x[3], y[3], x[2], y[2], xp, yp ) / w;
        if ( vabs( dist ) < vabs( dist_min ) )
            dist_min = dist;
    }

    if ( vabs( cross_product( mx[1], my[1], mx[3], my[3], xp, yp ) / w ) < h / 2 )
    {
        dist = cross_product( x[2], y[2], x[1], y[1], xp, yp ) / h;
        if ( vabs( dist ) < vabs( dist_min ) )
            dist_min = dist;

        dist = cross_product( x[0], y[0], x[3], y[3], xp, yp ) / h;
        if ( vabs( dist ) < vabs( dist_min ) )
            dist_min = dist;
    }

    for ( i = 0; i < 4; i++ )
    {
        dist = dist_euc2d( x[i], y[i], xp, yp );
        if ( vabs( dist ) < vabs( dist_min ) )
            dist_min = dist;
    }

    if ( nextPart && dist_min > 0 )
        return min( dist_min, nextPart->getDistanceToPoint( xp, yp ) );

    return dist_min;
}