void PseudoSpace(struct XYspace *S, /* coordinate space structure to fill out */ double M[2][2]) /* matrix that will become 'tofract.normal' */ { S->type = SPACETYPE; S->flag = ISPERMANENT(ON) + ISIMMORTAL(ON); S->references = 2; /* 3-26-91 added PNM */ S->tofract.normal[0][0] = M[0][0]; S->tofract.normal[1][0] = M[1][0]; S->tofract.normal[0][1] = M[0][1]; S->tofract.normal[1][1] = M[1][1]; FillOutFcns(S); }
void InitSpaces(void) { IDENTITY->type = SPACETYPE; FillOutFcns(IDENTITY); contexts[NULLCONTEXT].normal[1][0] = contexts[NULLCONTEXT].normal[0][1] = contexts[NULLCONTEXT].inverse[1][0] = contexts[NULLCONTEXT].inverse[0][1] = 0.0; contexts[NULLCONTEXT].normal[0][0] = contexts[NULLCONTEXT].normal[1][1] = contexts[NULLCONTEXT].inverse[0][0] = contexts[NULLCONTEXT].inverse[1][1] = 1.0; USER->flag |= ISIMMORTAL(ON); CoerceInverse(USER); }
/* The following macro forces a space to have an inverse: */ #define CoerceInverse(S) if (!HASINVERSE((S)->flag)) { \ MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); } /* :h3.IDENTITY Space IDENTITY space is (logically) the space corresponding to the identity transformation matrix. However, since all our transformation matrices have a common FRACTFLOAT scale factor to convert to 'fractpel's, that is actually what we store in 'tofract' matrix of IDENTITY: */ static struct XYspace identity = { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON) + HASINVERSE(ON), 2, /* added 3-26-91 PNM */ NULL, NULL, NULL, NULL, NULL, NULL, INVALIDID + 1, 0, {{{FRACTFLOAT, 0.0}, {0.0, FRACTFLOAT}}, {{1.0/FRACTFLOAT, 0.0}, {0.0, 1.0/FRACTFLOAT}}}, {{0, 0}, {0, 0}}}; struct XYspace *IDENTITY = &identity; /* */ #define MAXCONTEXTS 16 static struct doublematrix contexts[MAXCONTEXTS];