📄 paste.java
字号:
import java.awt.*;
public class paste{
public Polygon Paste;
public boolean visible;
public vector normal; // the normal vector with respect to the viewer
public vector realNormal; // the normal vector with respect to the environment
public vector centre;
public vector realCentre;
public vector lightSource;
public vector[] points;
public Color color;
public Color adjustColor;
public Rectangle bound; // 2d boundary of the polygon
public double zMax, zMin;
private int applyLight;
private double intensityFactor;
public paste[] innerPaste;
public boolean wireFrameOn;
public paste(vector[] points, Color color, int applyLight){
this.points = points;
this.color = color;
this.applyLight = applyLight;
realNormal = points[1].subtract(points[0]).cross(points[2].subtract(points[1])).unit();
realCentre = new vector(0,0,0);
lightSource = new vector(-11,2,55);
for(int i = 0; i < points.length; i++)
realCentre = realCentre.add(points[i]);
realCentre = realCentre.scale((double)1/points.length);
if(applyLight == 3)
lightSource = new vector(-2,20,55);
vector lightDirection = lightSource.subtract(realCentre);
if(applyLight == 1)
intensityFactor = (realNormal.unit().dot(lightDirection.unit())+2)/3;
if(applyLight == 0)
intensityFactor = 0.63;
if(applyLight == 2)
intensityFactor = (realNormal.unit().dot(lightDirection.unit())+5)/6;
if(applyLight == 3)
intensityFactor = (realNormal.unit().dot(lightDirection.unit())+1)/2;
adjustColor = new Color((int)(color.getRed()*intensityFactor),
(int)(color.getGreen()*intensityFactor),
(int)(color.getBlue()*intensityFactor) );
testVisibility(); // test whether the viewer can see this polygon;
//now the polygon is visible
if(visible){
Paste = makePolygon();
}
}
private void testVisibility(){
visible = false;
normal = points[1].subtract(points[0]).cross(points[2].subtract(points[1])).unit();
centre = new vector(0,0,0);
for(int i = 0; i < points.length; i++)
centre = centre.add(points[i]);
centre = centre.scale(1.0/points.length);
//test whether all vertix is in front of viwer's plane
for(int i = 0; i < points.length; i++){
if(points[i].z > 0){
visible = true;
break;
}
}
//test whether this polygon is facing toward viewer
if(visible){
if(points[0].scale(-1).dot(normal) <= 0)
visible = false;
}
//test whether this polygon is inside the screen
if(visible){
find_zMax_zMin();
Rectangle screen = new Rectangle(0,0,640, 480);
visible = screen.intersects(bound);
}
//test whether this polygon is too far away
//if(visible) .......
}
public void find_zMax_zMin(){
int xMax = points[0].p.x;
int xMin = xMax;
int yMax = points[0].p.y;
int yMin = yMax;
zMax = points[0].z;
zMin = zMax;
for(int i = 1; i < points.length; i++){
xMax = Math.max(xMax, points[i].p.x);
xMin = Math.min(xMin, points[i].p.x);
yMax = Math.max(yMax, points[i].p.y);
yMin = Math.min(yMin, points[i].p.y);
zMax = Math.max(zMax, points[i].z);
zMin = Math.min(zMin, points[i].z);
}
bound = new Rectangle(xMin, yMin, xMax-xMin, yMax-yMin);
}
private Polygon makePolygon(){
//for some partial visible polygons(e.g may half behind the viwer's plane),
//approximate the unseen points onto the viwer's plane (z = 1)
int visibleCount = 0;
int l = points.length;
vector[] p = new vector[l+1]; // the polygon may have (one)more vertix after being cut by the viwer's plane
for(int i = 0; i < l; i++){ // scan for unseen points
if(points[i].z >= 0){
p[visibleCount] = points[i];
visibleCount++;
} else{
if(points[(i+l - 1)%l].z >= 0){
p[visibleCount] = approximatePoint(points[i], points[(i+l - 1)%l]);
visibleCount++;
}
if(points[(i+1)%l].z >= 0){
p[visibleCount] = approximatePoint(points[i], points[(i+1)%l]);
visibleCount++;
}
}
}
//constract polygon
int[] x = new int[visibleCount];
for(int i = 0; i < visibleCount; i++){
x[i] = p[i].p.x;
}
int[] y = new int[visibleCount];
for(int i = 0; i < visibleCount; i++)
y[i] = p[i].p.y;
return new Polygon(x, y, visibleCount);
}
private vector approximatePoint(vector behindPoint, vector frontPoint){
//find the intersection of the viewer's plane and the line which passes the two points
vector direction = frontPoint.subtract(behindPoint).unit();
return frontPoint.subtract(direction.scale(frontPoint.z/direction.z)).add(new vector(0,0,0.01));
}
//the orientation of the polygon(with respect to the environment) has changed, so need to update
//the color
public void update(vector[] points, vector realNormal, vector realCentre){
this.points = points;
this.realCentre = realCentre;
this.realNormal = realNormal;
testVisibility();
if(visible){
Paste = makePolygon();
vector lightDirection = lightSource.subtract(realCentre);
if(applyLight == 1)
intensityFactor = (realNormal.unit().dot(lightDirection.unit())+3)/4;
if(applyLight == 0)
intensityFactor = 0.63;
adjustColor = new Color((int)(color.getRed()*intensityFactor),
(int)(color.getGreen()*intensityFactor),
(int)(color.getBlue()*intensityFactor) );
}
}
//when only the camera position changed
public void update(vector[] points){
this.points = points;
testVisibility();
if(visible)
Paste = makePolygon();
}
public void draw(Graphics g){
g.setColor(adjustColor);
if(visible){
if(wireFrameOn)
g.drawPolygon(Paste);
else
g.fillPolygon(Paste);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -