28 #define WEIGHT_PI_8_FACTOR  3.847759065022573512 
   40     return ((y & 1) == RedY) ?
 
   47 static int IsValidEdge(
int RedX, 
int RedY, 
float Radius,
 
   48     int x1, 
int y1, 
int x2, 
int y2)
 
   50     const int SqrRadius = (int)(Radius*Radius);
 
   58         && (x1*x1 + y1*y1 <= SqrRadius)
 
   60         && (x2*x2 + y2*y2 <= SqrRadius)
 
   62         && ((x1 - x2)*(x1 - x2)
 
   63             + (y1 - y2)*(y1 - y2) <= MaxDistSqr)
 
   71     double DiffX = Edge.
x1 - Edge.
x2;
 
   72     double DiffY = Edge.
y1 - Edge.
y2;
 
   73     return sqrt(DiffX*DiffX + DiffY*DiffY);
 
   83     for(Edge = Stencil.
Head; Edge != NULL; Edge = Edge->
NextEdge)
 
   97         for(j = 0; j < 4; j++)
 
  110     while(EdgeA && EdgeB)
 
  112         if(EdgeA->
x1 != EdgeB->x1 || EdgeA->
y1 != EdgeB->y1
 
  113             || EdgeA->
x2 != EdgeB->x2 || EdgeA->
y2 != EdgeB->y2)
 
  120     return !(EdgeA || EdgeB) ? 1 : 0;
 
  131     const int NeighX[4] = { 1,  1,  0, -1};
 
  132     const int NeighY[4] = { 0, -1, -1, -1};
 
  135     int j, x1, y1, x2, y2, Dist;
 
  158     for(j = 0; j < 4; j++)
 
  162     for(j = 0; j < 4; j++)
 
  163         for(y1 = -(
int)Radius; y1 <= (int)Radius; y1++)
 
  164             for(x1 = -(
int)Radius; x1 <= (int)Radius; x1++)
 
  165                 for(Dist = 1; Dist <= 2; Dist++)
 
  167                     x2 = x1 + Dist*NeighX[j];
 
  168                     y2 = y1 + Dist*NeighY[j];
 
  172                     if(IsValidEdge(RedX, RedY, Radius, x1, y1, x2, y2)
 
  173                         && !
AddEdge(&Stencils[j], x1, y1, x2, y2))
 
  194             2*j, Edge->
x1, Edge->
y1, Edge->
x2, Edge->
y2);
 
  198             Edge->
x1, Edge->
y1, Edge->
x2, Edge->
y2);
 
  205 int main(
int argc, 
char *argv[])
 
  207     double Radius, AxialSum, DiagonalSum;
 
  208     char *TemplateFilename, *OutputFilename;
 
  209     char **Keys = NULL, **Subs = NULL, **Sub;
 
  210     mstencil *GreenStencils = NULL, *RedBlueStencils = NULL;
 
  215         fprintf(stderr, 
"Syntax: gen-mstencil <radius> <template> <output>\n");
 
  218     else if((Radius = atof(argv[1])) <= 0)
 
  219         fprintf(stderr, 
"Radius must be positive.\n");
 
  221     TemplateFilename = argv[2];
 
  222     OutputFilename = argv[3];
 
  232         fprintf(stderr, 
"Assertion failed:\n" 
  233             "RedBlue axial stencils == Green axial stencils\n");
 
  238     AddPair(&Keys, &Subs, 
"RADIUS", 
"%d", (
int)floor(Radius));
 
  243     Sub = 
AddPair(&Keys, &Subs, 
"AXIAL_TVS", 
"");
 
  248     Sub = 
AddPair(&Keys, &Subs, 
"GREEN_DIAGONAL_TVS", 
"");
 
  254         "WEIGHT_AXIAL", 
"%.15e", 1/AxialSum);
 
  258         "WEIGHT_GREEN_MU", 
"%.15e", AxialSum/DiagonalSum);
 
  260         "WEIGHT_GREEN_DIAGONAL", 
"%.15e", 1/DiagonalSum);
 
  265     Sub = 
AddPair(&Keys, &Subs, 
"REDBLUE_DIAGONAL_TVS", 
"");
 
  271         "WEIGHT_REDBLUE_MU", 
"%.15e", AxialSum/DiagonalSum);
 
  273         "WEIGHT_REDBLUE_DIAGONAL", 
"%.15e", 1/DiagonalSum);
 
  276     FillTemplate(OutputFilename, TemplateFilename, Keys, Subs);