bool TTetrahedron::IsInner(const TPoint& P) const { TVector N, U1(X1, X2), U2(X1, X3), U3(X1, X4), U4(X2, X3), U5(X2, X4), U6(X2, X1); TVector Up1(X1, P), Up2(X2, P); N = Cross(U1, U2); //X4 is on opposite side of plain X1,X2,X3 than P if (Dot(N, U3) * Dot(N, Up1) < 0) { return false; } N = Cross(U1, U3); //X3 x P if (Dot(N, U2) * Dot(N, Up1) < 0) { return false; } N = Cross(U2, U3); //X2 x P if (Dot(N, U1) * Dot(N, Up1) < 0) { return false; } N = Cross(U4, U5); //X1 x P if (Dot(N, U6) * Dot(N, Up2) < 0) { return false; } return true; }
/* * E4. [Let people out, in.] If anyone in the ELEVATOR list has OUT == FLOOR, send * the user of this type who has most recently entered immediately to step U6, * wait 25 units, and repeat step E4. If no such users exist, but QUEUE[FLOOR] * is not empty, send the front person of that queue immediately to step U5 * instead of U4, wait 25 units, and repeat step E4. But if QUEUE[FLOOR] * is empty, set D1 <-- 0, make D3 nonzero, and wait for some other activity * to initiate further action. (Step E5 will send us to E6, or step U2 will * restart E4.) */ void E4(void) { USER_NODE * p = ELEVATOR.ER; for (; p != &ELEVATOR; p = p->ER) { int out = p->uinfo->OUT; if (out == FLOOR) { xlog(LOG_E, "E4(). %s is sent to U6().\n", p->uinfo->name); U6(p->uinfo); in_WAIT(TIME + 25, E4, NO_ARG); /** empty the elevator */ return; } } p = QUEUE[FLOOR].ER; if (p != &QUEUE[FLOOR]) { /** QUEUE[FLOOR] is not empty */ xlog(LOG_E, "E4(). %s is sent to U5().\n", p->uinfo->name); out_WAIT(U4, p->uinfo); /** fortunately the elevator comes */ /** the sequence of these two lines cannot be exchanged, because * it should be guarranteed that ``E5'' in this line (called in U5): * in_WAIT(TIME + 25, E5, NO_ARG); * should be scheduled after ``E4'' of in the following in_WAIT(): */ in_WAIT(TIME + 25, E4, NO_ARG); /** fill the elevator */ U5(p->uinfo); } else { D1 = 0; D3 = 1; xlog(LOG_E, "E4(). Nobody is here. " "wait for some other activity to initiate further action\n"); return; } }