Java examples for 2D Graphics:Polygon
Fills a triangle using the scan line algorithm and the z-buffer algorithm
//package com.java2s; import java.awt.*; public class Main { /**// ww w . j a v a2s .c om * Fills a triangle using the scan line algorithm and the z-buffer algorithm * @param gr graphic object * @param x x coordinates for all 3 vertexes * @param y y coordinates for all 3 vertexes * @param z z coordinates for all 3 vertexes * @param zbuffer z depth buffer */ public static void fillTriangle(Graphics gr, int[] x, int[] y, int[] z, int[][] zbuffer) { /** * sort the arrays according the y value * y[0]=min * y[2]=max */ if (y[0] > y[1]) { //swap values using xor y[0] ^= y[1]; y[1] ^= y[0]; y[0] ^= y[1]; //swap values using xor x[0] ^= x[1]; x[1] ^= x[0]; x[0] ^= x[1]; //swap values using xor z[0] ^= z[1]; z[1] ^= z[0]; z[0] ^= z[1]; } if (y[1] > y[2]) { //swap values using xor y[1] ^= y[2]; y[2] ^= y[1]; y[1] ^= y[2]; //swap values using xor x[1] ^= x[2]; x[2] ^= x[1]; x[1] ^= x[2]; //swap values using xor z[1] ^= z[2]; z[2] ^= z[1]; z[1] ^= z[2]; } if (y[0] > y[1]) { //swap values using xor y[0] ^= y[1]; y[1] ^= y[0]; y[0] ^= y[1]; //swap values using xor x[0] ^= x[1]; x[1] ^= x[0]; x[0] ^= x[1]; //swap values using xor z[0] ^= z[1]; z[1] ^= z[0]; z[0] ^= z[1]; } int p1x, p2x, p1z, p2z; //intersection points with the triangle edges int py; //y and z coordinates of the current scan line int dif1X, dif2X, dif1Y, dif2Y, dif1Z, dif2Z; if (y[0] == y[1]) { //pre-calculate some values that don't change during the cycle //for optimization purposes dif1X = x[2] - x[0]; dif2X = x[2] - x[1]; dif1Y = y[2] - y[0]; dif1Z = z[2] - z[0]; dif2Z = z[2] - z[1]; for (py = y[1] + 1; py <= y[2]; py++) { //calculate intersection points dif2Y = y[2] - py; p1x = x[2] - (dif1X * dif2Y) / dif1Y; p2x = x[2] - (dif2X * dif2Y) / dif1Y; p1z = z[2] - (dif1Z * dif2Y) / dif1Y; p2z = z[2] - (dif2Z * dif2Y) / dif1Y; //start z-buffer drawHorizontalLine(gr, py, p1x, p1z, p2x, p2z, zbuffer); //end z-buffer } } else if (y[1] == y[2]) { //pre-calculate some values that don't change during the cycle //for optimization purposes dif1X = x[2] - x[0]; dif2X = x[1] - x[0]; dif1Y = y[1] - y[0]; dif1Z = z[2] - z[0]; dif2Z = z[1] - z[0]; for (py = y[0]; py <= y[1]; py++) { //calculate intersection points p1x = x[2] - (dif1X * (y[2] - py)) / dif1Y; p2x = x[1] - (dif2X * (y[1] - py)) / dif1Y; p1z = z[2] - (dif1Z * (y[2] - py)) / dif1Y; p2z = z[1] - (dif2Z * (y[1] - py)) / dif1Y; //start z-buffer drawHorizontalLine(gr, py, p1x, p1z, p2x, p2z, zbuffer); //end z-buffer } } else { //pre-calculate some values that don't change during the cycle //for optimization purposes dif1X = x[2] - x[0]; dif2X = x[1] - x[0]; dif1Y = y[2] - y[0]; dif2Y = y[1] - y[0]; dif1Z = z[2] - z[0]; dif2Z = z[1] - z[0]; for (py = y[0]; py <= y[1]; py++) { //calculate intersection points p1x = x[2] - (dif1X * (y[2] - py)) / dif1Y; p2x = x[1] - (dif2X * (y[1] - py)) / dif2Y; p1z = z[2] - (dif1Z * (y[2] - py)) / dif1Y; p2z = z[1] - (dif2Z * (y[1] - py)) / dif2Y; //start z-buffer drawHorizontalLine(gr, py, p1x, p1z, p2x, p2z, zbuffer); //end z-buffer } //re-calculate what changes in the second cycle dif2X = x[2] - x[1]; dif2Y = y[2] - y[1]; dif2Z = z[2] - z[1]; for (py = y[1] + 1; py <= y[2]; py++) { //calculate intersection points p1x = x[2] - (dif1X * (y[2] - py)) / dif1Y; p2x = x[2] - (dif2X * (y[2] - py)) / dif2Y; p1z = z[2] - (dif1Z * (y[2] - py)) / dif1Y; p2z = z[2] - (dif2Z * (y[2] - py)) / dif2Y; //start z-buffer drawHorizontalLine(gr, py, p1x, p1z, p2x, p2z, zbuffer); //end z-buffer } } } /** * Draws a line using the z-buffer algorithm * @param gr graphic object * @param y y coordinate * @param x1 x coordinate of the first vertex * @param z1 z coordinate of the first vertex * @param x2 x coordinate of the second vertex * @param z2 z coordinate of the second vertex * @param zbuffer z depth buffer */ public static void drawHorizontalLine(Graphics gr, int y, int x1, int z1, int x2, int z2, int[][] zbuffer) { int dimX = zbuffer.length; int dimY = zbuffer[0].length; int difX, difZ; int px, pz; if (x1 > 0 && x1 < dimX && y > 0 && y < dimY && zbuffer[x1][y] >= z1) { zbuffer[x1][y] = z1; gr.fillRect(x1, y, 1, 1); } difX = x2 - x1; difZ = z2 - z1; if (x1 > x2) { for (px = x2 + 1; px < x1; px++) { pz = z1 + ((px - x1) * difZ / difX); if (px > 0 && px < dimX && y > 0 && y < dimY && zbuffer[px][y] >= pz) { zbuffer[px][y] = pz; gr.fillRect(px, y, 1, 1); } } } else { for (px = x1 + 1; px < x2; px++) { pz = z1 + ((px - x1) * difZ / difX); if (px > 0 && px < dimX && y > 0 && y < dimY && zbuffer[px][y] >= pz) { zbuffer[px][y] = pz; gr.fillRect(px, y, 1, 1); } } } if (x2 > 0 && x2 < dimX && y > 0 && y < dimY && zbuffer[x2][y] >= z2) { zbuffer[x2][y] = z2; gr.fillRect(x2, y, 1, 1); } } }