#include <stdlib.h> #include "GoTorus.h" #define PI 3.14159265358979324 GoTorus::GoTorus(double radius, int slices, double ringRadius, int ringSlices) { this->radius = radius; this->slices = slices; this->ringRadius = ringRadius; this->ringSlices = ringSlices; solidDirty = true; wireDirty = true; } void GoTorus::renderSolid(Go *go) { int i; if(solidDirty) updateSolid(); go->push(Go::FLAGS); go->enable(Go::CULL); for(i = 0; i < ringSlices; i++) { go->render(dataSolid[i]); } go->pop(Go::FLAGS); } void GoTorus::renderWire(Go *go) { int i; if(wireDirty) updateWire(); for(i = 0; i < ringSlices + slices + 1; i++) { go->render(dataWire[i]); } } void GoTorus::renderWireSlices(Go *go) { int i; if(wireDirty) updateWire(); for(i = ringSlices; i < ringSlices + slices + 1; i++) { go->render(dataWire[i]); } } void GoTorus::updateSolid(void) { int i, j; // // Create the data. // double d[slices + 1][ringSlices + 1][3]; double c[slices + 1][ringSlices + 1][3]; double ringSliceAngleInc = 2.0 * PI / ringSlices; double ringSliceAngle = 0.0; for(i = 0; i <= ringSlices; i++) { d[0][i][0] = radius + ringRadius * cos(ringSliceAngle);; d[0][i][1] = 0; d[0][i][2] = ringRadius * sin(ringSliceAngle); c[0][i][0] = radius; c[0][i][1] = 0; c[0][i][2] = 0; ringSliceAngle += ringSliceAngleInc; } double sliceAngleInc = 2.0 * PI / slices; double sliceAngle = sliceAngleInc; for(i = 1; i <= slices; i++) { for(j = 0; j <= ringSlices; j++) { d[i][j][0] = d[0][j][0] * cos(sliceAngle); d[i][j][1] = d[0][j][0] * sin(sliceAngle); d[i][j][2] = d[0][j][2]; c[i][j][0] = c[0][j][0] * cos(sliceAngle); c[i][j][1] = c[0][j][0] * sin(sliceAngle); c[i][j][2] = c[0][j][2]; } sliceAngle += sliceAngleInc; } // // Create the triangle strips. // dataSolid = new GoTriangleStrip *[ringSlices]; for(i = 0; i < ringSlices; i++) { dataSolid[i] = new GoTriangleStrip((slices + 1) * 2, Go::NORMAL); for(j = 0; j <= slices; j++) { dataSolid[i]->xyz(j*2, d[j][i+1][0], d[j][i+1][1], d[j][i+1][2]); dataSolid[i]->xyz(j*2+1, d[j][i][0], d[j][i][1], d[j][i][2]); dataSolid[i]->ijk(j*2, d[j][i+1][0] - c[j][i+1][0], d[j][i+1][1] - c[j][i+1][1], d[j][i+1][2] - c[j][i+1][2]); dataSolid[i]->ijk(j*2+1, d[j][i][0] - c[j][i][0], d[j][i][1] - c[j][i][1], d[j][i][2] - c[j][i][2]); } } solidDirty = false; } void GoTorus::updateWire(void) { int i, j; // // Create the data. // double d[slices + 1][ringSlices + 1][3]; double ringSliceAngleInc = 2.0 * PI / ringSlices; double ringSliceAngle = 0.0; for(i = 0; i <= ringSlices; i++) { d[0][i][0] = radius + ringRadius * cos(ringSliceAngle);; d[0][i][1] = 0; d[0][i][2] = ringRadius * sin(ringSliceAngle); ringSliceAngle += ringSliceAngleInc; } double sliceAngleInc = 2.0 * PI / slices; double sliceAngle = sliceAngleInc; for(i = 1; i <= slices; i++) { for(j = 0; j <= ringSlices; j++) { d[i][j][0] = d[0][j][0] * cos(sliceAngle); d[i][j][1] = d[0][j][0] * sin(sliceAngle); d[i][j][2] = d[0][j][2]; } sliceAngle += sliceAngleInc; } // // Create the line loops. // dataWire = new GoLineLoop *[ringSlices + slices + 1]; int count = 0; for(i = 0; i < ringSlices; i++) { dataWire[count] = new GoLineLoop(slices); for(j = 0; j < slices; j++) { dataWire[count]->xyz(j, d[j][i][0], d[j][i][1], d[j][i][2]); } count++; } for(j = 0; j <= slices; j++) { dataWire[count] = new GoLineLoop(ringSlices); for(i = 0; i < ringSlices; i++) { dataWire[count]->xyz(i, d[j][i][0], d[j][i][1], d[j][i][2]); } count++; } wireDirty = false; }