This is sphere.c in view mode; [Download] [Up]
/* Sphere.c Varun Mitroo March 1, 1991 To compile, type: cc sphere.c -o sphere Options: -r <number> Radius of the sphere. Default 150 -la <number> Number of latitude sections. Default 10 -lo <number> Number of longitude sections. Default 18 -theta <number> Horizontal angle in degrees. Default 30 degrees -phi <number> Vertical angle in degrees. Default 45 degrees -clip Activate hidden-line removal -noclip Deactivate hidden-line removal. On by default -shade Activate shading -noshade Deactivate shading. On by default This program outputs to stdout. Output should be redirected to a file. Example: sphere > test.ps - Creates file test.ps with default settings sphere -clip > test.ps - Same file as above with hidden line removal sphere -shade -la 20 -theta -40 -phi 25 -lo 25 -r 100 > test.ps Above line sets shading on with 20 latitude sections, 25 longitude sections, theta 40 degrees, phi 25 degrees, and a radius of 100. **************************************************************/ #include <stdio.h> #include <math.h> #include <stdlib.h> #define PI (3.14159265) #define TRUE (1) #define FALSE (0) typedef int boolean; typedef char *string; typedef float vector3D[3]; typedef struct PointThreeD { float x,y,z; } PointThreeD; typedef struct PointTwoD { float x,y; } PointTwoD; /***************************************************************/ void CrossXYZ(v1, v2, crossProd) vector3D v1, v2, crossProd; { crossProd[0] = v1[1] * v2[2] - v1[2] * v2[1]; crossProd[1] = v1[2] * v2[0] - v1[0] * v2[2]; crossProd[2] = v1[0] * v2[1] - v1[1] * v2[0]; } boolean ReadParam(); void DrawSphere(); boolean StrEqual (str1, str2) string str1, str2; { return (!strcmp(str1, str2)); } /****************** Global Variables ***************************/ float radius = 150, xMiddle = 0, yMiddle = 0, theta = -PI/6, phi = PI/4, gray; int xSize = 400, ySize = 400, longi = 18, lati = 10; boolean clipFlag = FALSE, shadeFlag = FALSE; float sinTheta, sinPhi, cosTheta, cosPhi; /***************************************************************/ main (argc, argv) int argc; string *argv; { if (ReadParam(argc,argv) == FALSE) DrawSphere(); else exit(1); } /***************************************************************/ boolean ReadParam(argc, argv) int argc; string argv[]; { int count = 1; while (count < argc) { if (StrEqual(argv[count], "-r")) { count++; if (count < argc) radius = atof(argv[count]); count++; } else if (StrEqual(argv[count], "-clip")) { clipFlag = TRUE; count++; } else if (StrEqual(argv[count], "-noclip")) { shadeFlag = FALSE; clipFlag = FALSE; count++; } else if (StrEqual(argv[count], "-shade")) { shadeFlag = TRUE; clipFlag = TRUE; count++; } else if (StrEqual(argv[count], "-noshade")) { shadeFlag = FALSE; count++; } else if (StrEqual(argv[count], "-la")) { count++; if (count < argc) lati = atof(argv[count]); count++; } else if (StrEqual(argv[count], "-lo")) { count++; if (count < argc) longi = atof(argv[count]); count++; } else if (StrEqual(argv[count], "-theta")) { count++; if (count < argc) theta = -atof(argv[count]) / 180 * PI; count++; } else if (StrEqual(argv[count], "-phi")) { count++; if (count < argc) phi = atof(argv[count]) / 180 * PI; count++; } else { printf("Error with arguments: %s [-r] [-la] [-lo] [-theta] [-phi] [-clip/noclip] [-shade/noshade]\n", argv[0]); return (TRUE); exit(1); } } return (FALSE); } /***************************************************************/ void PrintHeader() { printf("%%!PS-Adobe-2.0 EPSF-1.2\n"); printf("%%%%BoundingBox: 0 0 %d %d\n", xSize, ySize); printf("%%%%Creator: Varun Mitroo\n"); printf("%%%%Title: Sphere\n"); printf("%%%%EndComments\n\n"); } /***************************************************************/ void BoundingBox() { printf("0 0 moveto\n"); printf("0 %d lineto\n", ySize); printf("%d %d lineto\n", xSize, ySize); printf("%d 0 lineto\n", xSize); if (shadeFlag==TRUE) printf("closepath gsave .333 setgray fill grestore 0 setgray stroke\n"); else printf("closepath gsave 1 setgray fill grestore 0 setgray stroke\n"); } /***************************************************************/ boolean PolyVisible(poly) PointThreeD *poly; { vector3D v1, v2, cross; v1[0] = poly[0].x - poly[1].x; v1[1] = poly[0].y - poly[1].y; v1[2] = poly[0].z - poly[1].z; v2[0] = poly[2].x - poly[1].x; v2[1] = poly[2].y - poly[1].y; v2[2] = poly[2].z - poly[1].z; if ((v1[0] == 0) && (v1[1] == 0) && (v1[2] == 0)) { v1[0] = poly[3].x - poly[2].x; v1[1] = poly[3].y - poly[2].y; v1[2] = poly[3].z - poly[2].z; } CrossXYZ(v1, v2, cross); if (cross[2] < 0) return (TRUE); else return (FALSE); } /***************************************************************/ boolean CalcLight(poly) PointThreeD *poly; { vector3D v1, v2, cross; v1[0] = poly[0].x - poly[1].x; v1[1] = poly[0].y - poly[1].y; v1[2] = poly[0].z - poly[1].z; v2[0] = poly[2].x - poly[1].x; v2[1] = poly[2].y - poly[1].y; v2[2] = poly[2].z - poly[1].z; if ((v1[0] == 0) && (v1[1] == 0) && (v1[2] == 0)) { v1[0] = poly[3].x - poly[2].x; v1[1] = poly[3].y - poly[2].y; v1[2] = poly[3].z - poly[2].z; } CrossXYZ(v1, v2, cross); gray = -cross[2] / sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]); } /***************************************************************/ void Rotate(px, py, pz) float *px, *py, *pz; { float xt, yt; xt = *pz * sinTheta + *px * cosTheta; *pz = *pz * cosTheta - *px * sinTheta; *px = xt; yt = *py * cosPhi - *pz * sinPhi; *pz = *py * sinTheta + *pz * cosPhi; *py = yt; } /***************************************************************/ void DrawPolygon(curPoly) PointThreeD curPoly[]; { boolean drawFlag; if (shadeFlag==TRUE) CalcLight(curPoly); Rotate(&curPoly[0].x, &curPoly[0].y, &curPoly[0].z); Rotate(&curPoly[1].x, &curPoly[1].y, &curPoly[1].z); Rotate(&curPoly[2].x, &curPoly[2].y, &curPoly[2].z); Rotate(&curPoly[3].x, &curPoly[3].y, &curPoly[3].z); if (clipFlag==TRUE) drawFlag = PolyVisible(curPoly); if ((clipFlag && drawFlag) || (clipFlag == FALSE)) { printf("%0f %0f moveto\n", xMiddle + curPoly[0].x, yMiddle + curPoly[0].y); printf("%0f %0f lineto\n", xMiddle + curPoly[1].x, yMiddle + curPoly[1].y); printf("%0f %0f lineto\n", xMiddle + curPoly[2].x, yMiddle + curPoly[2].y); printf("%0f %0f lineto\n", xMiddle + curPoly[3].x, yMiddle + curPoly[3].y); printf("closepath\n"); if (shadeFlag==FALSE) printf("stroke\n"); else { printf("%0f setgray\n", gray); printf("fill\n"); } } } void DrawPolygon3(curPoly) PointThreeD curPoly[]; { boolean drawFlag; if (shadeFlag==TRUE) CalcLight(curPoly); Rotate(&curPoly[0].x, &curPoly[0].y, &curPoly[0].z); Rotate(&curPoly[1].x, &curPoly[1].y, &curPoly[1].z); Rotate(&curPoly[2].x, &curPoly[2].y, &curPoly[2].z); if (clipFlag==TRUE) drawFlag = PolyVisible(curPoly); if ((clipFlag && drawFlag) || (clipFlag == FALSE)) { printf("%0f %0f moveto\n", xMiddle + curPoly[0].x, yMiddle + curPoly[0].y); printf("%0f %0f lineto\n", xMiddle + curPoly[1].x, yMiddle + curPoly[1].y); printf("%0f %0f lineto\n", xMiddle + curPoly[2].x, yMiddle + curPoly[2].y); printf("closepath\n"); if (shadeFlag==FALSE) printf("stroke\n"); else { printf("%0f setgray\n", gray); printf("fill\n"); } } } /***************************************************************/ void ComputeSphere() { float step1, step2, count1, count2, s1, s2, c1, c2, ts1, ts2, tc1, tc2, x, y, z; PointThreeD curPoly[4]; xMiddle = xSize / 2; yMiddle = ySize / 2; sinTheta = sin(theta); sinPhi = sin(phi); cosTheta = cos(theta); cosPhi = cos(phi); step1 = PI / lati; step2 = PI / longi; /************ Draw Top Row *******************/ c1 = 1; s1 = 0; tc1 = cos(step1); ts1 = sin(step1); for (count2 = 0; count2 < PI * 2; count2 = count2 + step2) { curPoly[0].x=0; curPoly[0].y=radius; curPoly[0].z=0; c2 = cos(count2); s2 = sin(count2); tc2 = cos(count2+step2); ts2 = sin(count2+step2); curPoly[1].x = ts1 * tc2 * radius; curPoly[1].y = tc1 * radius; curPoly[1].z = ts1 * ts2 * radius; curPoly[2].x = ts1 * c2 * radius; curPoly[2].y = tc1 * radius; curPoly[2].z = ts1 * s2 * radius; DrawPolygon3(curPoly); } /************ Draw Body of Sphere *******************/ for (count1 = step1; count1 < (PI-step1); count1 = count1 + step1) { c1 = cos(count1); s1 = sin(count1); tc1 = cos(count1+step1); ts1 = sin(count1+step1); for (count2 = 0; count2 < PI * 2; count2 = count2 + step2) { c2 = cos(count2); s2 = sin(count2); tc2 = cos(count2+step2); ts2 = sin(count2+step2); curPoly[0].x = s1 * c2 * radius; curPoly[0].y = c1 * radius; curPoly[0].z = s1 * s2 * radius; curPoly[1].x = s1 * tc2 * radius; curPoly[1].y = c1 * radius; curPoly[1].z = s1 * ts2 * radius; curPoly[2].x = ts1 * tc2 * radius; curPoly[2].y = tc1 * radius; curPoly[2].z = ts1 * ts2 * radius; curPoly[3].x = ts1 * c2 * radius; curPoly[3].y = tc1 * radius; curPoly[3].z = ts1 * s2 * radius; DrawPolygon(curPoly); } } /************ Draw Bottom Row *******************/ c1 = -1; s1 = 0; tc1 = cos(PI-step1); ts1 = sin(PI-step1); for (count2 = 0; count2 < PI * 2; count2 = count2 + step2) { curPoly[0].x=0; curPoly[0].y=-radius; curPoly[0].z=0; c2 = cos(count2); s2 = sin(count2); tc2 = cos(count2+step2); ts2 = sin(count2+step2); curPoly[1].x = ts1 * c2 * radius; curPoly[1].y = tc1 * radius; curPoly[1].z = ts1 * s2 * radius; curPoly[2].x = ts1 * tc2 * radius; curPoly[2].y = tc1 * radius; curPoly[2].z = ts1 * ts2 * radius; DrawPolygon3(curPoly); } } /***************************************************************/ void DrawSphere() { PrintHeader(); BoundingBox(); ComputeSphere(); printf("showpage\n"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.