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);