Implement polygon scanline renderer
This commit is contained in:
parent
b135fb5408
commit
4b14f30509
BIN
bin/sig/Edge.class
Normal file
BIN
bin/sig/Edge.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
bin/sig/Point.class
Normal file
BIN
bin/sig/Point.class
Normal file
Binary file not shown.
33
src/sig/Edge.java
Normal file
33
src/sig/Edge.java
Normal file
@ -0,0 +1,33 @@
|
||||
package sig;
|
||||
|
||||
public class Edge {
|
||||
Point a,b;
|
||||
int min_y;
|
||||
int max_y;
|
||||
int min_x;
|
||||
int max_x;
|
||||
double x_of_min_y;
|
||||
double inverse_slope;
|
||||
public Edge(Point a, Point b) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
min_y=Math.min(a.y, b.y);
|
||||
max_y=Math.max(a.y, b.y);
|
||||
min_x=Math.min(a.x, b.x);
|
||||
max_x=Math.max(a.x, b.x);
|
||||
if (a.y==min_y) {
|
||||
x_of_min_y=a.x;
|
||||
} else {
|
||||
x_of_min_y=b.x;
|
||||
}
|
||||
|
||||
inverse_slope=(double)(a.x-b.x)/(a.y-b.y);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Edge [a=" + a + ", b=" + b + ", min_y=" + min_y + ", max_y=" + max_y + ", min_x=" + min_x + ", max_x="
|
||||
+ max_x + ", x_of_min_y=" + x_of_min_y + ", inverse_slope=" + inverse_slope + "]";
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,8 @@ import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.MemoryImageSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
@ -17,6 +19,8 @@ public class Panel extends JPanel implements Runnable {
|
||||
private Image imageBuffer;
|
||||
private MemoryImageSource mImageProducer;
|
||||
private ColorModel cm;
|
||||
int scanLine=0;
|
||||
int nextScanLine=0;
|
||||
|
||||
public Panel() {
|
||||
super(true);
|
||||
@ -85,7 +89,101 @@ public class Panel extends JPanel implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
FillPolygon(new Point[] {
|
||||
new Point(135,2),
|
||||
new Point(166,96),
|
||||
new Point(265,97),
|
||||
new Point(185,156),
|
||||
new Point(215,251),
|
||||
new Point(134,192),
|
||||
new Point(54,251),
|
||||
new Point(84,156),
|
||||
new Point(4,97),
|
||||
new Point(103,96),
|
||||
});
|
||||
}
|
||||
|
||||
public void FillPolygon(Point...points) {
|
||||
Edge[] edges = new Edge[points.length];
|
||||
List<Edge> edges_sorted = new ArrayList<Edge>();
|
||||
for (int i=0;i<points.length;i++) {
|
||||
edges[i] = new Edge(points[i],points[(i+1)%points.length]);
|
||||
if (edges_sorted.size()==0) {
|
||||
edges_sorted.add(edges[i]);
|
||||
} else {
|
||||
boolean inserted=false;
|
||||
for (int j=0;j<edges_sorted.size();j++) {
|
||||
Edge e2 = edges_sorted.get(j);
|
||||
if (e2.min_y>edges[i].min_y) {
|
||||
edges_sorted.add(j,edges[i]);
|
||||
inserted=true;
|
||||
break;
|
||||
} else
|
||||
if (e2.min_y==edges[i].min_y){
|
||||
if (e2.min_x>edges[i].min_x) {
|
||||
edges_sorted.add(j,edges[i]);
|
||||
inserted=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!inserted) {
|
||||
edges_sorted.add(edges[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Edge> active_edges = new ArrayList<Edge>();
|
||||
scanLine = edges_sorted.get(0).min_y-1;
|
||||
nextScanLine = scanLine+1;
|
||||
do {
|
||||
if (active_edges.size()%2==0) {
|
||||
for (int i=0;i<active_edges.size();i+=2) {
|
||||
Edge e1 = active_edges.get(i);
|
||||
Edge e2 = active_edges.get(i+1);
|
||||
for (int x=(int)Math.round(e1.x_of_min_y);x<=e2.x_of_min_y;x++) {
|
||||
pixel[scanLine*width+x]=(255<<16)+(0<<8)+0;
|
||||
}
|
||||
}
|
||||
for (int i=0;i<active_edges.size();i++) {
|
||||
Edge e = active_edges.get(i);
|
||||
if (e.max_y==scanLine+1) {
|
||||
active_edges.remove(i--);
|
||||
} else {
|
||||
e.x_of_min_y+=e.inverse_slope;
|
||||
}
|
||||
}
|
||||
scanLine++;
|
||||
GetNextScanLineEdges(edges_sorted, active_edges);
|
||||
}
|
||||
}
|
||||
while (active_edges.size()>0);
|
||||
}
|
||||
|
||||
private void GetNextScanLineEdges(List<Edge> edges_sorted, List<Edge> active_edges) {
|
||||
if (scanLine==nextScanLine) {
|
||||
for (int i=0;i<edges_sorted.size();i++) {
|
||||
Edge e = edges_sorted.get(i);
|
||||
if (e.min_y==scanLine) {
|
||||
e = edges_sorted.remove(i--);
|
||||
boolean inserted=false;
|
||||
for (int j=0;j<active_edges.size();j++) {
|
||||
if (e.x_of_min_y<active_edges.get(j).x_of_min_y) {
|
||||
active_edges.add(j,e);
|
||||
inserted=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!inserted) {
|
||||
active_edges.add(e);
|
||||
}
|
||||
|
||||
} else
|
||||
if (e.min_y>scanLine) {
|
||||
nextScanLine=e.min_y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
32
src/sig/Point.java
Normal file
32
src/sig/Point.java
Normal file
@ -0,0 +1,32 @@
|
||||
package sig;
|
||||
|
||||
public class Point {
|
||||
int x,y;
|
||||
|
||||
public Point(int x, int y) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Point(" + x + "," + y + ")";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user