程序功能:
使用Graphics2D类draw方法绘制随机四面体(四面体大小、位置、每个面(三角形)的颜色随机设置)。
注:这个程序用到了Java多维数组,比较有意思。
运行结果:
源码:
1. 实体类
//Creating JFrame to display DrawPanel.
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.GeneralPath;
import java.security.SecureRandom;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
/**
* 13.15 (Drawing Tetrahedrons) Write an application that draws a tetrahedron (a
* three-dimensional shape with four triangular faces). Use class GeneralPath
* and method draw of class Graphics2D.
*
* @author Pandenghuang@163.com
* @Date Jan 22, 2019, 23:32:56 PM
*
*/
public class TetrahedronJPanel extends JPanel
{
final SecureRandom rn = new SecureRandom();
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
super.paintComponents(g);
int width = getWidth(); // total width
int height = getHeight(); // total height
int rRed;
int rGreen;
int rBlue;
//画1个四面体
for (int i = 1; i > 0;i--){
boolean triangleFound = false;
//保存随机生成的四面体的四个点的坐标(X坐标保存在第一行,Y坐标保存在第二行)
int[][] triangleCordinates = new int[2][4];
//保存四面体的四个表面三角形的三个点的坐标(四面体编号为第一维)
int[][][] tetrahedronCordinates = new int[4][2][3];
do {
int aX = 1+rn.nextInt(width);
int aY = 1+rn.nextInt(height);
int bX = 1+rn.nextInt(width);
int bY = 1+rn.nextInt(height);
int cX = 1+rn.nextInt(width);
int cY = 1+rn.nextInt(height);
//前三个点确定后,将第一个点的位置随机移动,生成第四个点(四个点互不重合)
int margin = 10; //边距,防止图形太靠边
int dX = Math.min(aX+1+rn.nextInt(width), width-margin);
int dY = Math.min(aY+1+rn.nextInt(height), height-margin);
double abL = Math.sqrt(Math.pow(Math.abs(aX-bX), 2)+Math.pow(Math.abs(aY-bY), 2));
double bcL = Math.sqrt(Math.pow(Math.abs(bX-cX), 2)+Math.pow(Math.abs(bY-cY), 2));
double acL = Math.sqrt(Math.pow(Math.abs(aX-cX), 2)+Math.pow(Math.abs(aY-cY), 2));
triangleCordinates[0][0] = aX; //A点X坐标
triangleCordinates[0][1] = bX; //B点X坐标
triangleCordinates[0][2] = cX; //C点X坐标
triangleCordinates[0][3] = dX; //D点X坐标
triangleCordinates[1][0] = aY; //A点Y坐标
triangleCordinates[1][1] = bY; //B点Y坐标
triangleCordinates[1][2] = cY; //C点Y坐标
triangleCordinates[1][3] = dY; //D点Y坐标
if (abL+bcL>acL && abL+acL>bcL && bcL+acL>abL) //三角形判定法则:任意两边之和大于第三边
triangleFound = true;
} while (!triangleFound); //如果随机生成的坐标无法构成三角形,则继续随机构造
for (int k =0; k<4; k++) { //k表示四个表面三角形的编号,即0-3
for (int m =0; m<2; m++) { //m表示四个顶点的坐标类型(X坐标或Y坐标),0为X坐标簇,1为Y坐标簇
for (int j = 0; j<3; j++) {
/*j表示四个顶点的具体坐标类型对应的坐标值,如k=0,m=0,j=0表示A点X坐标
以下公式基于演算纸上的立体几何分析结果,使用三重循环完成了四个表面三角形的各顶点坐标的赋值。
避免了硬编码,是本程序的灵魂所在!*/
tetrahedronCordinates[k][m][j] = triangleCordinates[m][(j+k)%4];}}}
for (int k =0; k<4; k++) { //依次绘制四个三角形,表达四面体
//Color represented in RGB mode
rRed = rn.nextInt(256);
rGreen = rn.nextInt(256);
rBlue = rn.nextInt(256);
Color color=new Color(rRed, rGreen, rBlue);
g2d.setColor(color); //随机设置颜色
g2d.fill(new GeneralPath(new Polygon(tetrahedronCordinates[k][0],tetrahedronCordinates[k][1],3)));
}
}
}
}
2. 测试类
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class DrawTetrahedron {
static JTextArea statusBar = new JTextArea();
public static void main(String[] args)
{
// create a panel that contains our drawing
TetrahedronJPanel panel = new TetrahedronJPanel();
MouseHandler handler = new MouseHandler();
panel.addMouseMotionListener(handler);
// create a new frame to hold the panel
JFrame application = new JFrame();
application.setTitle("绘制随机四面体");
// set the frame to exit when it is closed
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel,BorderLayout.CENTER); // add the panel to the frame
application.add(statusBar,BorderLayout.SOUTH); // add the statusBar to the frame
application.setSize(460, 360); // set the size of the frame
application.setVisible(true); // make the frame visible
}
static class MouseHandler extends MouseMotionAdapter
{
// handle event when mouse enters area
@Override
public void mouseMoved(MouseEvent event)
{
statusBar.setText(String.format("光标当前坐标:[%d, %d]",
event.getX(), event.getY()));;
}
}
}