File: xray.cmd

package info (click to toggle)
evolver 2.70+ds-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 17,148 kB
  • sloc: ansic: 127,395; makefile: 209; sh: 98
file content (141 lines) | stat: -rw-r--r-- 5,290 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// xray.cmd

// Produces xray image of a 3D wet foam.  Calculates liquid content on
// grid of probe lines.  Plateau borders are detected as bounded by
// facets with less than 2/3 of the maximum facet tension.
// Outputs a PostScript file to stdout with a grid of grayscale pixels.
// Usage: set xgridsize and ygridsize to the desired resolution, 
// i.e. pixels across and down and give the command
//        xray >>> "filename.ps"
// The xray command will calculate the bounding box of the surface itself.
// Works in torus or non-torus mode.  In torus mode, everything will
// automatically be wrapped back to the unit cell, so you don't have
// to worry about that.

// Programmer: Ken Brakke, brakke@susqu.edu, http://www.susqu.edu/brakke

xgridsize := 100  // xgridsize x ygridsize grid
ygridsize := 100  


xray := { 
  local xx,yy,jitterx,jittery,minx,miny,maxx,maxy,tension_cutoff;
  local dx,dy,ax,ay,az,bx,by,bz,cx,cy,cz,hix,hiy,lox,loy,maxi,maxj;
  local mini,minj,fsign,xyarea,ii,jj,area1,area2,area3,maxr,xpts,ypts;
  local results;

  if space_dimension != 3 then
  { errprintf "The 'xray' command must be run in three-dimensional space.\n";
    abort;
  };

  if surface_dimension == 1 then
  { errprintf "The 'xray' command is not meant for the string model.\n";
    abort;
  };

  define results real[xgridsize][ygridsize];
  for ( xx := 1 ; xx <= xgridsize ; xx += 1 )
    for ( yy := 1 ; yy <= ygridsize ; yy += 1 )
      results[xx][yy] := 0.0; // clean out old results
  
  // random offsets to prevent edge effects */
  jitterx := 0.5213414312341;
  jittery := 0.4934129768877;

  /* box to map results to */
  if torus then
  { // assumes orthogonal fundamental region
    minx := 0;
    miny := 0;
    maxx := torus_periods[1][1];
    maxy := torus_periods[2][2];
    tension_cutoff := max(facet,tension)*2/3;  // do only Plateau borders
  }
  else
  { minx := min(vertex,x);
    maxx := max(vertex,x);
    miny := min(vertex,y);
    maxy := max(vertex,y);
    tension_cutoff := 100000; // do all facets
  };

  dx := (maxx-minx)/xgridsize;
  dy := (maxy-miny)/ygridsize;

  foreach facet ff where tension < tension_cutoff do
  { ax := ff.vertex[1].x;
    ay := ff.vertex[1].y;
    az := ff.vertex[1].z;
    bx := ax + ff.edge[1].x;  // let Evolver take care of unwrapping
    by := ay + ff.edge[1].y;
    bz := az + ff.edge[1].z;
    cx := bx + ff.edge[2].x;  // let Evolver take care of unwrapping
    cy := by + ff.edge[2].y;
    cz := bz + ff.edge[2].z;
    // get bounding box to find possible grid points
    hix := (ax > bx) ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx);
    hiy := (ay > by) ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
    lox := (ax < bx) ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx);
    loy := (ay < by) ? (ay < cy ? ay : cy) : (by < cy ? by : cy);
    // compact to integers
    maxi := floor(hix/dx-jitterx);
    maxj := floor(hiy/dy-jittery);
    mini := ceil(lox/dx-jitterx);
    minj := ceil(loy/dy-jittery);
    // loop among possible values
    fsign := ff.z > 0 ? 1 : -1;
    xyarea := 2*abs(ff.z);
    for ( ii := mini ; ii <= maxi ; ii += 1 )
     for ( jj := minj ; jj <= maxj ; jj += 1 )
     { // test inclusion
       xx := ii*dx + dx*jitterx; yy := jj*dy + dy*jittery;
       area1 := fsign*((ax-xx)*(by-yy) - (bx-xx)*(ay-yy));
       area2 := fsign*((bx-xx)*(cy-yy) - (cx-xx)*(by-yy));
       area3 := fsign*((cx-xx)*(ay-yy) - (ax-xx)*(cy-yy));
       if ( (area1 > 0) and (area2 > 0) and (area3 > 0) ) then
       { results[(ii imod xgridsize)+1][(jj imod ygridsize)+1] += 
            fsign*(area1*cz + area2*az + area3*bz)/xyarea;
       }
     } 
  };
  if ( torus ) then
  { // correct results for wrap in z 
    for ( ii := 1 ; ii <= xgridsize ; ii += 1 )
      for ( jj := 1 ; jj <= ygridsize ; jj += 1 )
        results[ii][jj] := results[ii][jj] mod torus_periods[3][3];
  };

  // map to range 0,1
  maxr := 0;
  for ( ii := 1 ; ii <= xgridsize ; ii += 1 )
    for ( jj := 1 ; jj <= ygridsize ; jj += 1 )
      if results[ii][jj] > maxr then maxr := results[ii][jj];
  if maxr > 0 then
    for ( ii := 1 ; ii <= xgridsize ; ii += 1 )
      for ( jj := 1 ; jj <= ygridsize ; jj += 1 )
        results[ii][jj] /= maxr;

  /* output results in postscript format, making low density white */
  xpts := 500; ypts := 500; // point size of image
  // using kludges to get %% stuff to print right on Windows and Unix
  printf "%%!"; printf"PS-Adobe-3.0 EPSF-3.0\n";
  printf "%%%%"; printf"BoundingBox: 0 0 %d %d\n",xpts,ypts;
  printf "%%%%"; printf"Creator: Surface Evolver xray.cmd\n";
  printf "%%%%"; printf"EndComments\n\n";
  printf "%f %f scale\n",xpts/xgridsize,ypts/ygridsize;
  printf "/px { newpath setgray moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto closepath fill} def\n";
  for ( ii := 0 ; ii < xgridsize ; ii += 1 )
    for ( jj := 0 ; jj < ygridsize ; jj += 1 )
    { printf "%f %f %f px\n",ii,jj,(1-results[ii+1][jj+1]);
    };
  printf "\nshowpage\n";
  printf "\n%%"; printf"EOF\n";
}

    
// End xray.cmd

// Usage: set xgridsize and ygridsize to the desired resolution, 
// i.e. pixels across and down and give the command
//        xray >>> "filename.ps"