/* Public domain */ /* * This program uses FreeSG to plot the Lorenz attractor. */ #include #include #include M_Real r = 28.0; M_Real sigma = 10.0; M_Real b = 8.0/3.0; M_Real h = 0.01; M_Real spinI = 0.0, spinJ = 0.0005, spinK = 0.0; SG_Node *node; int iter = 1, iteriter = 10; SG_NodeClass LorenzAttractorClass; static void LorenzDraw(void *pNode, SG_View *sgv) { SG_Node *node = pNode; M_Vector3 p = M_VecGet3(0.0, 1.0, -1.0); M_Color color; int i; GL_Begin(GL_LINE_STRIP); for (i = 0; i < iter; i++) { color.b = color.g = 0.2 + 0.8*(M_Real)i/(M_Real)iter; color.r = 1.0; GL_Color3v(&color); p.x += h*(sigma*(p.y - p.x)); p.y += h*(p.x*(r - p.z) - p.y); p.z += h*(p.x*p.y - b*p.z); GL_Vertex3v(&p); } GL_End(); SG_RotateI(node, spinI); SG_RotateJ(node, spinJ); SG_RotateK(node, spinK); iter += iteriter; } /* Create the user dialog for editing parameters. */ AG_Window * CreateParametersWindow(void) { AG_Window *win; AG_Numerical *num; win = AG_WindowNew(0); AG_WindowSetCaptionS(win, "Parameters"); AG_WindowSetPosition(win, AG_WINDOW_MIDDLE_LEFT, 0); AG_NumericalNewInt(win, 0, NULL, "Iterations:", &iter); AG_NumericalNewInt(win, 0, NULL, "Iterations':", &iteriter); num = M_NumericalNewReal(win, 0, NULL, "r:", &r); AG_NumericalSetIncrement(num, 0.001); num = M_NumericalNewReal(win, 0, NULL, "sigma:", &sigma); AG_NumericalSetIncrement(num, 0.001); num = M_NumericalNewReal(win, 0, NULL, "h:", &h); AG_NumericalSetIncrement(num, 0.001); num = M_NumericalNewReal(win, 0, NULL, "b:", &b); AG_NumericalSetIncrement(num, 0.01); num = M_NumericalNewReal(win, 0, "deg", "Pitch:", &spinI); AG_NumericalSetIncrement(num, 0.0001); num = M_NumericalNewReal(win, 0, "deg", "Yaw:", &spinJ); AG_NumericalSetIncrement(num, 0.0001); num = M_NumericalNewReal(win, 0, "deg", "Roll:", &spinK); AG_NumericalSetIncrement(num, 0.0001); AG_WindowShow(win); } int main(int argc, char *argv[]) { AG_Window *win; SG_View *sv; SG_Node *plot; SG *sg; if (AG_InitCore("lorenz-demo", 0) == -1) { fprintf(stderr, "%s\n", AG_GetError()); return (1); } if (AG_InitGraphics("") == -1) { fprintf(stderr, "%s\n", AG_GetError()); return (-1); } SG_InitSubsystem(); AG_BindGlobalKey(AG_KEY_ESCAPE, AG_KEYMOD_ANY, AG_Quit); AG_BindGlobalKey(AG_KEY_F8, AG_KEYMOD_ANY, AG_ViewCapture); agColors[WINDOW_BG_COLOR] = AG_ColorRGB(0,0,0); CreateParametersWindow(); /* Create the scene. */ sg = SG_New(NULL, "scene", 0); /* Create an instance of our plot object. */ AG_RegisterClass(&LorenzAttractorClass); plot = AG_Malloc(sizeof(SG_Node)); AG_ObjectInit(plot, &LorenzAttractorClass); AG_ObjectSetName(plot, "MyLorenzAttractor"); AG_ObjectAttach(sg->root, plot); /* Create a window with a SG_View. Disable lighting. */ win = AG_WindowNew(0); AG_WindowSetCaptionS(win, "Lorenz Attractor"); sv = SG_ViewNew(win, sg, SG_VIEW_EXPAND|SG_VIEW_NO_LIGHTING); AG_WindowSetGeometryAlignedPct(win, AG_WINDOW_MC, 60, 40); AG_WindowShow(win); /* Reposition the default camera. */ SG_Translate(sv->cam, 10.0, 0.0, -20.0); SG_Rotatevd(sv->cam, 180.0, M_VecI3()); AG_EventLoop(); AG_Destroy(); return (0); } /* Define a new node class for our plot. */ SG_NodeClass LorenzAttractorClass = { { "SG_Node:LorenzAttractor", sizeof(SG_Node), { 0,0 }, NULL, /* init */ NULL, /* destroy */ NULL, /* load */ NULL, /* save */ NULL, /* edit */ }, NULL, /* menuInstance */ NULL, /* menuClass */ LorenzDraw, NULL /* edit */ };