Пример #1
0
/**
 * @brief Find the largest interval of projection coordinates
          if the interval is large then VAC_SPACE.
          If we can find any one are satified in the i dierction, 
          then
             vac[i][0]= 0   
             vac[i][1]= 0   
 * @param pos
 * @param vac (Direct Coordinates)
 */
void FindVac( POSCAR* pos, double vac[3][2])
{
    int i,j,v;
    double post;
    double len[3];
    double *interval=NULL;
    double max_interval=-1;
    POSCAR* posTmp=NULL;

    /*Init*/
    for (i=0; i<3; i++)
        for (j=0; j<2; j++)
            vac[i][j]=0;

    POSCAR_Copy(pos, posTmp);
    POSCAR_C2D(posTmp);
    POSCAR_Confined(posTmp);

    for (i=0; i<3; i++)
    {
        len[i]= dot3D(posTmp->lat->a[i], posTmp->lat->a[i]);
        len[i]= sqrt(len[i]);
    }

    interval= malloc(sizeof(double)*posTmp->natom); 
    if (interval==NULL)
    {
        fprintf(stderr, "POSCAR_FindVac: Memory Allocate Error.\n");
        exit(1);
    }

    for (v=0; v<3; v++)
    {
        insort(&(posTmp->atom_pos[0][0]), posTmp->natom, 3, v, false);
        for (i=0; i<posTmp->natom; i++)
        {
            if (i==posTmp->natom-1)
                post= posTmp->atom_pos[0][v]+1.0; 
            else
                post= posTmp->atom_pos[i+1][v]; 
            interval[i]=(post-posTmp->atom_pos[i][v])*len[v];

            if (interval[i]>max_interval &&  interval[i]>VAC_SPACE)
            {
                vac[v][0]= posTmp->atom_pos[i][v];
                vac[v][1]= post; 
            }
        }
    }

    free(interval);
    POSCAR_Free(posTmp);
}
Пример #2
0
int barycentricProjection(char *path_m,char *path_rm, char *path_bin)
{
    /*
    If the mesh is a smooth mesh (for example, spherical), and given
    a smooth reference mesh (rm) print for each vertex in rm its
    barycentric coordinates within the triangles of the mesh. This
    permits, for example, to map data defined over the vertices of
    the mesh over rm.
    */
    Mesh    m,rm;
    FILE	*fo;
    int     nt;
    int3D   *t;
    int     np_rm;
    float3D *p,*p_rm;
    float   c0,c1;
    int     i,j,result;
    float3D n;
    float   flipTest;
    
    FreeSurfer_load_mesh(path_m,&m);
    FreeSurfer_load_mesh(path_rm,&rm);
    
    // Check whether the meshes are properly oriented
    n=normal3D(0,&m);
    flipTest=dot3D(m.p[m.t[0].a],n);
    if(flipTest<0)
    {
        printf("ERROR: the mesh is mis-oriented\n");
        return 1;
    }
    n=normal3D(0,&rm);
    flipTest=dot3D(rm.p[rm.t[0].a],n);
    if(flipTest<0)
    {
        printf("ERROR: rm is mis-oriented\n");
        return 1;
    }
    
    // Mesh (smooth)
    p=m.p;
    nt=m.nt;
    t=m.t;

    // Reference mesh (smooth)
    np_rm=rm.np;
    p_rm=rm.p;
    
    // Open output file for writing
    fo=fopen(path_bin,"w");
    
    // Write mesh topology
    for(i=0;i<nt;i++)
    {
    	fwrite(&(m.t[i].a),1,sizeof(int),fo);
    	fwrite(&(m.t[i].b),1,sizeof(int),fo);
    	fwrite(&(m.t[i].c),1,sizeof(int),fo);
    }
    printf("Mesh topology written\n");

    // Write barycentric coordinates
    for(i=0;i<np_rm;i++)
    {
        if((int)(100*i/(float)np_rm)<(int)(100*(i+1)/(float)np_rm))
        	printf("%i%%\n",(int)(100*(i+1)/(float)np_rm));
        for(j=0;j<nt;j++)
        {
            result=intersect_VectorTriangle(p_rm[i],j,&c0,&c1,&m);
            if(result==1)
            {
                //printf("%i %f %f\n",j,c0,c1);
                fwrite(&j,1,sizeof(int),fo);
                fwrite(&c0,1,sizeof(float),fo);
                fwrite(&c1,1,sizeof(float),fo);
                break;
            }
        }
        if(j==nt)
        {
            int k,imin=0;
            float   d,dmin=1000;
            printf("ERROR: could not resample point %i of the reference mesh (%f %f %f)\n",i,p_rm[i].x,p_rm[i].y,p_rm[i].z);
            for(k=0;k<m.np;k++)
            {
                d=norm3D(sub3D(m.p[k],p_rm[i]));
                if(d<dmin)
                {
                    dmin=d;
                    imin=k;
                }
            }
            printf("closest vertex %i (%f,%f,%f), dist=%f\n",imin,p[imin].x,p[imin].y,p[imin].z,dmin);

            result=intersect_VectorTriangle(p_rm[i],1984,&c0,&c1,&m);
            printf(">> t[1984] c0,c1: %f, %f\n",c0,c1);
            result=intersect_VectorTriangle(p_rm[i],1920,&c0,&c1,&m);
            printf(">> t[1920] c0,c1: %f, %f\n",c0,c1);

            printf("triangles including vertex %i\n",imin);
            for(k=0;k<nt;k++)
            {
                if(t[k].a==imin||t[k].b==imin||t[k].c==imin)
                {
                    printf("%i. %i,%i,%i\n",k,t[k].a,t[k].b,t[k].c);
                    printf("   %i: %f,%f,%f\n",t[k].a,p[t[k].a].x,p[t[k].a].y,p[t[k].a].z);
                    printf("   %i: %f,%f,%f\n",t[k].b,p[t[k].b].x,p[t[k].b].y,p[t[k].b].z);
                    printf("   %i: %f,%f,%f\n",t[k].c,p[t[k].c].x,p[t[k].c].y,p[t[k].c].z);
                }
            }
            return 1;
        }
    }
    printf("Barycentric coordinates written\n");
        
    fclose(fo);
    
    return 0;
}
Пример #3
0
// Adapted from intersect_RayTriangle()
// Copyright 2001, softSurfer (www.softsurfer.com)
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
//    Input:  vector "x", triangle index "it"
//    Output: *c0, *c1 = the triangle-based coordinates of the intersection (when it exists)
//    Return: -1 = triangle is degenerate (a segment or point)
//             0 = disjoint (no intersect)
//             1 = intersect in unique point I1
//             2 = are in the same plane
int intersect_VectorTriangle(float3D x, int i, float *c0, float *c1, Mesh *m)
{
    float3D *p=m->p;
    int3D   *t=m->t;
    int3D   T=t[i];
    float3D xx;
    float3D u, v, n;             // triangle vectors
    float3D dir,w0, w;               // ray vectors
    float   r, a, b;             // params to calc ray-plane intersect

    u=sub3D(p[T.b],p[T.a]);
    v=sub3D(p[T.c],p[T.a]);
    n=cross3D(u,v);
    if(norm3D(n)<=EPSILON)         // triangle is degenerate, do not deal with this case
        return -1;

    dir=x;
    w0 = sca3D(p[T.a],-1);
    a = dot3D(n,w0);
    b = dot3D(n,dir);
    if (fabs(b) < EPSILON) {        // ray is parallel to triangle plane
        if (a == 0)                 // ray lies in triangle plane
            return 2;
        else
            return 0;              // ray disjoint from plane
    }

    // get intersect point of ray with triangle plane
    r = -a/b;
    if (r < 0.0)                    // ray goes away from triangle
        return 0;                   // => no intersect
    // for a segment, also test if (r > 1.0) => no intersect

    xx = sca3D(dir,r);    // intersect point of ray and plane

    // is I inside T?
    float    uu, uv, vv, wu, wv, D;
    uu = dot3D(u,u);
    uv = dot3D(u,v);
    vv = dot3D(v,v);
    w = sub3D(xx,p[T.a]);
    wu = dot3D(w,u);
    wv = dot3D(w,v);
    D = uv * uv - uu * vv;

    // get and test parametric coords
    *c0 = (uv * wv - vv * wu) / D;
    if(fabs(*c0)<EPSILON)
        *c0=0;
    if(fabs(1-*c0)<EPSILON)
        *c0=1;
    if (*c0 < 0.0 || *c0 > 1.0)        // I is outside T
        return 0;

    *c1 = (uv * wu - uu * wv) / D;
    if(fabs(*c1)<EPSILON)
        *c1=0;
    if(fabs(1-*c1)<EPSILON)
        *c1=1;
    if (*c1 < 0.0 || (*c0 + *c1) > 1.0)  // I is outside T
        return 0;

    return 1;                      // I is in T
}