CIRCLE_RENDERER(step_x) (SDL_Surface *pTarget, int iCenterX, int iCenterY, int iRadius, Uint32 iColour) { int iRadiusSqr = iRadius * iRadius; for(int iX = 0; iX <= iRadius; ++iX) { int iY = (int)(sqrt((double)(iRadiusSqr - iX*iX)) + 0.5f); // circle formula; y^2 = r^2 - x^2 PlotPixel(pTarget, iCenterX + iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX + iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY - iY, iColour); } } CIRCLE_RENDERER(step_x_better) (SDL_Surface *pTarget, int iCenterX, int iCenterY, int iRadius, Uint32 iColour) { int iRadiusSqr = iRadius * iRadius; int iY = 0; for(int iX = 0; iX <= iY; ++iX) { iY = (int)(sqrt((double)(iRadiusSqr - iX*iX)) + 0.5f); // circle formula; y^2 = r^2 - x^2 PlotPixel(pTarget, iCenterX + iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX + iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX + iY, iCenterY + iX, iColour); PlotPixel(pTarget, iCenterX + iY, iCenterY - iX, iColour); PlotPixel(pTarget, iCenterX - iY, iCenterY + iX, iColour); PlotPixel(pTarget, iCenterX - iY, iCenterY - iX, iColour); } } CIRCLE_RENDERER(step_theta) (SDL_Surface *pTarget, int iCenterX, int iCenterY, int iRadius, Uint32 iColour) { double fRadius = (double)iRadius; double fStep = 1.0f / fRadius; double fLimit = PI / 2.0f; for(double fTheta = 0; fTheta < fLimit; fTheta += fStep) { int iX = (int)(cos(fTheta) * fRadius + 0.5f); int iY = (int)(sin(fTheta) * fRadius + 0.5f); PlotPixel(pTarget, iCenterX + iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX + iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY - iY, iColour); } } CIRCLE_RENDERER(step_theta_smaller) (SDL_Surface *pTarget, int iCenterX, int iCenterY, int iRadius, Uint32 iColour) { double fRadius = (double)iRadius; double fStep = 0.5f / fRadius; double fLimit = PI / 2.0f; for(double fTheta = 0; fTheta < fLimit; fTheta += fStep) { int iX = (int)(cos(fTheta) * fRadius + 0.5); int iY = (int)(sin(fTheta) * fRadius + 0.5); PlotPixel(pTarget, iCenterX + iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX + iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY - iY, iColour); } } CIRCLE_RENDERER(rotate_point) (SDL_Surface *pTarget, int iCenterX, int iCenterY, int iRadius, Uint32 iColour) { // Start with a point at the top of the circle double fX = 0; double fY = (double)iRadius; // Calculate sin(0.5 / radius), sin(x) can be approximated to x for small x double fSin = 0.5f / fY; // Given that cos(x)^2 + sin(x)^2 = 1, estimate cos(0.5 / radius) using Newton's method double fTmp = fSin * fSin * 0.5 - 0.5; double fCos = 1 - fSin; fCos -= (fCos * fCos * 0.5 + fTmp) / (fSin + fCos); fCos -= (fCos * fCos * 0.5 + fTmp) / (fSin + fCos); // Repeat until rotated by 45 degrees (which is 1/8th of a circle, and 8 points are plotted per iteration) while(fX < fY) { // Convert X and Y to integers (rounding to nearest by adding 0.5 and rounding down) int iX = (int)(fX + 0.5f); int iY = (int)(fY + 0.5f); // Plot (X,Y) and the reflections of this in x and y PlotPixel(pTarget, iCenterX + iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX + iX, iCenterY - iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY + iY, iColour); PlotPixel(pTarget, iCenterX - iX, iCenterY - iY, iColour); // Rotate (X,Y) by 90 degrees and repeat (i.e. plot (Y,-X)) PlotPixel(pTarget, iCenterX + iY, iCenterY + iX, iColour); PlotPixel(pTarget, iCenterX + iY, iCenterY - iX, iColour); PlotPixel(pTarget, iCenterX - iY, iCenterY + iX, iColour); PlotPixel(pTarget, iCenterX - iY, iCenterY - iX, iColour); // Rotate the point clockwise by (0.5 / radius) radians fTmp = fCos * fX + fSin * fY; fY = fCos * fY - fSin * fX; fX = fTmp; } // Note that not sin() nor cos() nor sqrt() are called (albiet sqrt() is estimated once) }