⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paste.java

📁 如果对java3D感兴趣的朋友
💻 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 + -