Java 窗口 绘制图形 #3
写在前面:
高数下学到第二章,突发奇想要写一个程序画二元函数图像
思路分了三层:
①抽象层:
因变量z,自变量x、y,坐标原点x0、y0、z0
②投影实现层:
屏幕投影坐标px、py,x轴与屏幕水平方向夹角theta1,z轴与屏幕铅直方向夹角theta2,缩放变量S
分两种情况考虑了:
1)单纯以z轴为旋转轴
yp=S*z
xp=S*(-x*sintheta1 + y*costheta2)
2)以原点为定点旋转
yp=S*(x*costheta1*sintheta2+y*sintheta1+z*costheta2)
xp=S*(-x*sintheta1 + y*costheta2)
③操作层:演草纸上写的和实际程序写的不一样,略
运行效果:
可以缩放、平移,各角度旋转
代码如下:
1 package my_package; 2 3 import java.awt.*; 4 import java.awt.event.MouseAdapter; 5 import java.awt.event.MouseEvent; 6 import java.awt.event.MouseMotionAdapter; 7 import java.awt.event.MouseWheelEvent; 8 import java.awt.event.MouseWheelListener; 9 import java.io.*; 10 import javax.swing.JFrame; 11 import javax.swing.JPanel; 12 13 public class PonysAlgorithm2 extends JFrame 14 { 15 private static final long serialVersionUID = 1L; 16 static int pony_winx=800,pony_winy=600;//窗口的长和宽 17 static int pony_scale=20,pony_scale_tmp=40;//视图缩放变量 18 static int theta1=0,theta2=0;//水平旋转角度,铅直旋转角度 19 static int pony_square=250;//绘制xy正方形区域趋边长的一半 20 static int pony_px=pony_winx/2,pony_py=pony_winy/2;//屏幕投影变量px和py 21 22 static int pony_framex_ori,pony_framey_ori;//鼠标移动辅助变量 23 static int pony_theta1_tmp,pony_theta2_tmp;//角度随鼠标移动变化辅助变量 24 static int pony_px_tmp,pony_py_tmp;//屏幕投影量随鼠标移动变化辅助变量 25 static int pony_project_x_tmp,pony_project_y_tmp;//屏幕投影量计算辅助变量 26 static double pony_z_tmp;//保存计算出的z的辅助变量 27 static float pony_precision=40.0f;//绘制精度,但绘制点数只受pony_square影响,不受精度影响 28 static int pony_mouse=0;//辅助判断鼠标按键 29 30 static double pony_project_x(double x, double y){//计算在屏幕上的投影px 31 return (y*Math.cos(theta1/180.0f)-x*Math.sin(theta1/180.0f))*pony_scale; 32 } 33 static double pony_project_y(double z, double x, double y){//计算在屏幕上的投影py 34 return (z*Math.cos(theta2/180.0f)+(y*Math.sin(theta1/180.0f)+x*Math.cos(theta1/180.0f))*Math.sin(theta2/180.0f))*pony_scale; 35 } 36 static double pony_z(double x, double y){//计算函数值 37 return x*x+y*y; 38 } 39 40 public static void main(String[] args) throws Exception 41 { 42 JFrame ponyFrame=new JFrame("Pony's Algorithm II"); 43 ponyFrame.setLayout(null); 44 JPanel ponyJPanel=new JPanel(){ 45 private static final long serialVersionUID = 1L; 46 public void paint(Graphics g){ 47 super.paint(g); 48 for(int y=-pony_square;y<=pony_square;++y) 49 { 50 for(int x=-pony_square;x<=pony_square;++x) 51 { 52 pony_project_x_tmp=pony_px+(int)pony_project_x(x/pony_precision,y/pony_precision); 53 pony_z_tmp=pony_z(x/pony_precision,y/pony_precision); 54 pony_project_y_tmp=pony_py+(int)pony_project_y(pony_z_tmp,x/pony_precision,y/pony_precision); 55 56 g.setColor(Color.getHSBColor(0.54f+0.2f*(y+pony_square)/(pony_square*2.0f), 1.0f, 1.0f)); 57 g.drawLine(pony_project_x_tmp, pony_project_y_tmp, pony_project_x_tmp, pony_project_y_tmp); 58 } 59 } 60 } 61 }; 62 63 /*Whole*/ 64 ponyFrame.setSize(pony_winx,pony_winy); 65 ponyFrame.setResizable(false); 66 ponyFrame.setLocationRelativeTo(null); 67 ponyFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 68 69 /*ICON*/ 70 File directory = new File(""); 71 ponyFrame.setIconImage(Toolkit.getDefaultToolkit().getImage(directory.getCanonicalPath()+"\\icons\\2.png")); 72 73 /*DRAW*/ 74 ponyJPanel.setBounds(0, 0, pony_winx, pony_winy); 75 ponyFrame.add(ponyJPanel); 76 77 /*MOUSE*/ 78 ponyFrame.addMouseListener(new MouseAdapter() { 79 @Override 80 public void mousePressed(MouseEvent e) {//当任意鼠标键按下时,记录变量 81 pony_framex_ori=e.getXOnScreen(); 82 pony_framey_ori=e.getYOnScreen(); 83 pony_theta1_tmp=theta1; 84 pony_theta2_tmp=theta2; 85 pony_px_tmp=pony_px; 86 pony_py_tmp=pony_py; 87 if(e.getButton()==MouseEvent.BUTTON1){pony_mouse=1;} 88 else if(e.getButton()==MouseEvent.BUTTON3){pony_mouse=3;} 89 } 90 public void mouseReleased(MouseEvent e) { 91 pony_mouse=0; 92 } 93 }); 94 ponyFrame.addMouseMotionListener(new MouseMotionAdapter() {//当鼠标键按下并移动时,记录变量 95 @Override 96 public void mouseDragged(MouseEvent e) {//两个角度的改变 97 if(pony_mouse==1){ 98 theta1=pony_theta1_tmp-(e.getXOnScreen()-pony_framex_ori)/2; 99 theta2=pony_theta2_tmp-(e.getYOnScreen()-pony_framey_ori)/2; 100 } 101 else if(pony_mouse==3){//两个投影坐标的改变 102 pony_px=pony_px_tmp+(e.getXOnScreen()-pony_framex_ori)/1; 103 pony_py=pony_py_tmp+(e.getYOnScreen()-pony_framey_ori)/1; 104 } 105 106 ponyJPanel.repaint(); 107 } 108 }); 109 ponyFrame.addMouseWheelListener(new MouseWheelListener() { 110 @Override 111 public void mouseWheelMoved(MouseWheelEvent e) { 112 if(e.getWheelRotation()==1) { 113 if(pony_scale_tmp>2) { 114 pony_scale_tmp-=1; 115 pony_scale=pony_scale_tmp/2; 116 ponyJPanel.repaint(); 117 } 118 else {pony_scale_tmp=2;} 119 } 120 else if(e.getWheelRotation()==-1) { 121 pony_scale_tmp+=1; 122 pony_scale=pony_scale_tmp/2; 123 ponyJPanel.repaint(); 124 } 125 } 126 }); 127 128 ponyFrame.setVisible(true); 129 return; 130 } 131 }
十分良心加了注释哈哈
附件:
*jar所在目录*\\icons\\
2.png