This is the general source code for rendering a poker chip
sitting on a checkerboard, using lab3.cpp.

This is a pixel-first rendering.

This would be considered ray casting with no perspective (orthographic).

The code below assumes you have implemented the Image class from lab1.cpp.
You should use your own photograph of a poker chip, and the chip should be
centered in the image.

note:
Generally in this course, do not use any images that are copyrighted or
have a watermark of any kind. Take your own photos.


The code below was written by your instructor on Thursday after lab 9/19/2019.
The coding style is important, and you should try to emulate it when writing
all your code in this course, and all your courses in CSUB Computer Science.


//--------------------------------
//Inside the check_keys function
//--------------------------------
case XK_c:
    g.mode = 16;
    //set the width and height scale for the checkerboard.
    g.scale[0] = 110.0;
    g.scale[1] = 110.0;
    //set the center of the poker chip
    g.center[0] = rnd() * g.xres;
    g.center[1] = rnd() * g.yres;
    //radius of the poker chip
    g.radius = rnd() * 10.0 + 150.0;
    x11.clear_screen();
    break;


//--------------------------
//Inside the render function
//--------------------------
case 16:
{
    //checkerboard
    int rgb1[3] = {100,  80,  40}; //color 1
    int rgb2[3] = {200, 160,  80}; //color 2
    int rgb3[3] = {210, 200, 180}; //color of gap between checkers
    //
    //determine the color of this pixel on the checkerboard.
    //
    x11.setColor3i(rgb1[0], rgb1[1], rgb1[2]);
    //Is this pixel inside the gap area?
    if (x/g.scale[0] - (int)(x/g.scale[0]) < 0.03 ||
            y/g.scale[1] - (int)(y/g.scale[1]) < 0.03)
        //yes. set gap color.
        x11.setColor3i(rgb3[0], rgb3[1], rgb3[2]);
    else
        //not inside gap.
        if ((int)(x/g.scale[0])%2 == (int)(y/g.scale[1])%2)
            //set color of a checker
            x11.setColor3i(rgb2[0], rgb2[1], rgb2[2]);
    //-------------------------------------------------------------------
    //poker chip shadow
    //The shadow is another circle, but colored with checkerboard colors.
    //-------------------------------------------------------------------
    //Is the pixel inside the shadow circle?
    Flt xdiff = x - g.center[0];
    Flt ydiff = y - g.center[1];
    Flt dist = sqrt(xdiff*xdiff + ydiff*ydiff);
    if (dist <= g.radius) {
        //yes, inside the shadow (checkerboard)
        float shad = 0.75; //<------darkness of shadow
        x11.setColor3i(rgb1[0]*shad, rgb1[1]*shad, rgb1[2]*shad);
        if (x/g.scale[0] - (int)(x/g.scale[0]) < 0.03 ||
                y/g.scale[1] - (int)(y/g.scale[1]) < 0.03)
            x11.setColor3i(rgb3[0]*shad, rgb3[1]*shad, rgb3[2]*shad);
        else if ((int)(x/g.scale[0])%2 == (int)(y/g.scale[1])%2)
            x11.setColor3i(rgb2[0]*shad, rgb2[1]*shad, rgb2[2]*shad);
    }
    //----------
    //poker chip
    //----------
    Flt shadow_offset = 20.0;
    Flt newcentx = g.center[0] - shadow_offset;
    Flt newcenty = g.center[1] - shadow_offset;
    xdiff = x - newcentx;
    ydiff = y - newcenty;
    dist = sqrt(xdiff*xdiff + ydiff*ydiff);
    if (dist <= g.radius) {
        //
        //inside the chip
        //pixel distance from center of circle
        //
        xdiff = x - newcentx;
        ydiff = y - newcenty;
        Flt radius = sqrt(xdiff*xdiff + ydiff*ydiff);
        //
        //angle from center to pixel
        //
        Flt ang = atan2(ydiff, xdiff);
        //
        //assert statement for debugging
        //if (ang < -3.14159265 || ang > 3.14159265)
        //   printf("angle: %lf\n", ang);
        //
        //relative distance along radius
        //
        Flt rad_portion = radius / g.radius;
        //
        //assert statement for debugging
        //if (rad_portion >= 1.0)
        //  printf("rad_portion: %lf\n", rad_portion);
        //
        //radius of image
        //
        Flt radimg = img.width * 0.5 * 0.95;
        radimg *= rad_portion;
        //
        //get x,y on the image
        //
        Flt imgx = cos(ang) * radimg;
        Flt imgy = sin(ang) * radimg;
        //printf("imgx: %lf %lf\n", imgx, imgy); //for debugging
        //
        //offset x,y by the image center
        //
        imgx += (img.width / 2);
        imgy += (img.height / 2);
        //the code above can be optimized.
        //
        //assert statement for debugging
        //if (imgx > img.width-1 || imgy > img.height-1)
        //  printf("imgx: %lf %lf\n", imgx, imgy);
        //
        //----------------------------------------------
        //Get the pixel color from the image data stream
        //----------------------------------------------
        //
        unsigned char *p = img.data;
        //
        //Pointer is currently at the start of the data stream.
        //Offset the data pointer (pointer arithmetic).
        //Notice the y and x must be integer values.
        //
        //move down y rows
        //
        p += (int)imgy * img.width * 3;
        //
        //move across x columns
        //
        p += (int)imgx * 3;
        //
        //Set the poker chip RGB color at this pixel.
        //
        x11.setColor3i(*p, *(p+1), *(p+2));
    }
    break;
}