protected void renderLineVertices(float[] a, float[] b) {
    // 2D hack added by ewjordan 6/13/07
    // Offset coordinates by a little bit if drawing 2D graphics.
    // http://dev.processing.org/bugs/show_bug.cgi?id=95

    // This hack fixes a bug caused by numerical precision issues when
    // applying the 3D transformations to coordinates in the screen plane
    // that should actually not be altered under said transformations.
    // It will not be applied if any transformations other than translations
    // are active, nor should it apply in OpenGL mode (PGraphicsOpenGL
    // overrides render_lines(), so this should be fine).
    // This fix exposes a last-pixel bug in the lineClipCode() function
    // of PLine.java, so that fix must remain in place if this one is used.

    // Note: the "true" fix for this bug is to change the pixel coverage
    // model so that the threshold for display does not lie on an integer
    // boundary. Search "diamond exit rule" for info the OpenGL approach.

    /*
      // removing for 0149 with the return of P2D
      if (drawing2D() && a[Z] == 0) {
        a[TX] += 0.01;
        a[TY] += 0.01;
        a[VX] += 0.01*a[VW];
        a[VY] += 0.01*a[VW];
        b[TX] += 0.01;
        b[TY] += 0.01;
        b[VX] += 0.01*b[VW];
        b[VY] += 0.01*b[VW];
      }
     */
    // end 2d-hack

    if (a[SW] > 1.25f || a[SW] < 0.75f) {
      float ox1 = a[TX];
      float oy1 = a[TY];
      float ox2 = b[TX];
      float oy2 = b[TY];

      // TODO strokeWeight should be transformed!
      float weight = a[SW] / 2; 

      // when drawing points with stroke weight, need to extend a bit
      if (ox1 == ox2 && oy1 == oy2) {
        oy1 -= weight;
        oy2 += weight;
      }

      float dX = ox2 - ox1 + EPSILON;
      float dY = oy2 - oy1 + EPSILON;
      float len = (float) Math.sqrt(dX*dX + dY*dY);

      float rh = weight / len;

      float dx0 = rh * dY;
      float dy0 = rh * dX;
      float dx1 = rh * dY;
      float dy1 = rh * dX;

      float ax1 = ox1+dx0;
      float ay1 = oy1-dy0;

      float ax2 = ox1-dx0;
      float ay2 = oy1+dy0;

      float bx1 = ox2+dx1;
      float by1 = oy2-dy1;

      float bx2 = ox2-dx1;
      float by2 = oy2+dy1;

      if (smooth) {
        smoothTriangle.reset(3);
        smoothTriangle.smooth = true;
        smoothTriangle.interpARGB = true;  // ?

        // render first triangle for thick line
        smoothTriangle.setVertices(ax1, ay1, a[TZ],
                                   bx2, by2, b[TZ],
                                   ax2, ay2, a[TZ]);
        smoothTriangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
                                      b[SR], b[SG], b[SB], b[SA],
                                      a[SR], a[SG], a[SB], a[SA]);
        smoothTriangle.render();

        // render second triangle for thick line
        smoothTriangle.setVertices(ax1, ay1, a[TZ],
                                   bx2, by2, b[TZ],
                                   bx1, by1, b[TZ]);
        smoothTriangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
                                      b[SR], b[SG], b[SB], b[SA],
                                      b[SR], b[SG], b[SB], b[SA]);
        smoothTriangle.render();

      } else {
        triangle.reset();

        // render first triangle for thick line
        triangle.setVertices(ax1, ay1, a[TZ],
                             bx2, by2, b[TZ],
                             ax2, ay2, a[TZ]);
        triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
                                b[SR], b[SG], b[SB], b[SA],
                                a[SR], a[SG], a[SB], a[SA]);
        triangle.render();

        // render second triangle for thick line
        triangle.setVertices(ax1, ay1, a[TZ],
                             bx2, by2, b[TZ],
                             bx1, by1, b[TZ]);
        triangle.setIntensities(a[SR], a[SG], a[SB], a[SA],
                                b[SR], b[SG], b[SB], b[SA],
                                b[SR], b[SG], b[SB], b[SA]);
        triangle.render();
      }

    } else {
      line.reset();

      line.setIntensities(a[SR], a[SG], a[SB], a[SA],
                          b[SR], b[SG], b[SB], b[SA]);

      line.setVertices(a[TX], a[TY], a[TZ],
                       b[TX], b[TY], b[TZ]);

        /*
        // Seems okay to remove this because these vertices are not used again,
        // but if problems arise, this needs to be uncommented because the above
        // change is destructive and may need to be undone before proceeding.
        if (drawing2D() && a[MZ] == 0) {
          a[X] -= 0.01;
          a[Y] -= 0.01;
          a[VX] -= 0.01*a[VW];
          a[VY] -= 0.01*a[VW];
          b[X] -= 0.01;
          b[Y] -= 0.01;
          b[VX] -= 0.01*b[VW];
          b[VY] -= 0.01*b[VW];
        }
        */

      line.draw();
    }
  }