Below are images demonstrating refraction.
This is the image created during Wednesday's class. The rays hitting the
sphere are tweaked randomly, and thus produce a fuzzy transparent look.
scratchapixel refraction function
The image below on left "refracts" each ray upon hitting the sphere, using
the refract function provided on the Scratch-a-pixel web page.
The image to the right is a photograph of a real glass ball sitting on my desk.
Note:
To use the Scratch-a-pixel refract() function will be an exercise in refactoring
of source code. Try it yourself, then if you give up I will help you.
Indexes of refraction used in the image above:
 air:   1.000293
 glass: 1.52
 
Here is some code we did in class together.
clipping class
class Clip {
    public:
        Vec center;
        Vec normal;
        double radius;
        bool inside;
        Clip() { radius = 0.0; }
};
//Clip elements in the Object class.
Clip clip[12];
int nclips;
Pokeball bottom sphere definition (yours can differ)
o = &g.object[g.nobjects];
o->type = TYPE_SPHERE;
vecMake(0.0, 0.0, 0.0, o->center);
o->radius = 100.0;
vecMake(1.0, 1.0, 1.0, o->color);
o->specular = true;
vecMake(0.1, 0.1, 0.1, o->spec);
//clipping--------------------------
o->nclips = 0;
vecMake(0, -6., 0, o->clip[0].center);
vecMake(0, 1, 0, o->clip[0].normal);
vecNormalize(o->clip[0].normal);
++o->nclips;
//clip a hole in the sphere
vecMake(0, 0, 100, o->clip[o->nclips].center);
o->clip[o->nclips].radius = 20.0;
++o->nclips;
//----------------------------------
g.nobjects++;
Triangle definition (yours can differ)
o = &.object[g.nobjects];
o->type = TYPE_TRIANGLE;
vecMake(-100, 100,  100, o->tri[0]);
vecMake(-100, -100, 100, o->tri[1]);
vecMake( 100, -100, 100, o->tri[2]);
getTriangleNormal(o->tri, o->norm);
vecMake(0.1, 1.0, 0.1, o->color);
o->surface = SURF_NONE;
g.nobjects++;
Ray/Triangle intersection
int rayTriangleIntersect(Object *o, Ray *ray, Hit *hit)
{
    //Does the ray intersect the triangle's plane?
    if (rayPlaneIntersect(o->tri[0], o->norm, ray, hit)) {
        //Yes.
        double u, v, w;
        if (pointInTriangle(o->tri, hit->p, &u, &v)) {
            w = 1.0 - u - v;
            (void)w;
            return 1;
        }
    }
    return 0;
}
In trace()
case TYPE_TRIANGLE:
    if (rayTriangleIntersect(o, ray, &hit)) {
        if (hit.t < closehit.t) {
            closehit.t = hit.t;
            vecCopy(hit.p, closehit.p);
            vecCopy(o->color, closehit.color);
            vecCopy(o->norm, closehit.norm);
            h=i;
        }
    }
    break;
In raySphereIntersect()
//quadratic solutions...
if (t0 > 0.0) {
    hit->p[0] = ray->o[0] + ray->d[0] * t0;
    hit->p[1] = ray->o[1] + ray->d[1] * t0;
    hit->p[2] = ray->o[2] + ray->d[2] * t0;
    sphereNormal(hit->p, o->center, hit->norm);
    hit->t = t0;
    //Is this clipped?
    for (int i=0; i<o->nclips; i++) {
        Vec v;
        vecSub(hit->p, o->clip[i].center, v);
        if (o->clip[i].radius > 0.0) {
            //sphere clip
            double dist = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
            if (o->clip[i].inside) {
                if (dist <= o->clip[i].radius)
                    goto back_of_sphere;
            } else {
                if (dist > o->clip[i].radius)
                    goto back_of_sphere;
            }
        }
        double dot = vecDotProduct(v, o->clip[i].normal);
        if (dot > 0.0)
            goto back_of_sphere;
    }
    return 1;
}
back_of_sphere:
if (t1 > 0.0) {
    hit->p[0] = ray->o[0] + ray->d[0] * t1;
    hit->p[1] = ray->o[1] + ray->d[1] * t1;
    hit->p[2] = ray->o[2] + ray->d[2] * t1;
    sphereNormal(hit->p, o->center, hit->norm);
    hit->t = t1;
    //Is this clipped?
    for (int i=0; i<o->nclips; i++) {
        Vec v;
        vecSub(hit->p, o->clip[i].center, v);
        if (o->clip[i].radius > 0.0) {
            //sphere clip
            double dist = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
            if (o->clip[i].inside) {
                if (dist <= o->clip[i].radius)
                    return 0;
            } else {
                if (dist > o->clip[i].radius)
                    return 0;
            }
        }
        //plane clip
        double dot = vecDotProduct(v, o->clip[i].normal);
        if (dot > 0.0)
            return 0;
    }
    return 1;
}