2D游戏引擎中的旋转,平移和放缩的几何知识

来源:互联网 发布:文章cms评测 编辑:程序博客网 时间:2024/06/09 18:51

最近看了一下APEgine的相关源代码,对于物体的旋转,平移和缩放有所理解,然后想自己写一个小程序来演示

这些功能,后来知道需要线性代数的知识,随后把线性代数复习了一遍,随后写下了以下代码,这段代码只是演示

一个长方形在某一固定点旋转。关键的线性代数知识是一个旋转矩阵:

sinA cosA
-cosA sinA

 

这是两个正交向量的基地,并且是单位向量,用此矩阵是顺时针转动,逆时针转动为:

 sinA   cosA

 cosA  -sinA  


package test.com;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;


import javax.swing.JFrame;
import javax.swing.JPanel;


import org.w3c.dom.css.Rect;


import Matrix.com.Matrix;


public class MatrixTest extends JFrame {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MatrixTest test = new MatrixTest();
test.setTitle("Matrix test");
test.setLocationRelativeTo(null);
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(450, 450);
test.setVisible(true);
}


public MatrixTest() {
add(new PaintPanel());
}


}


class PaintPanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawGrids(g);
}


private void drawGrids(Graphics g) {
int gridH = 20;
int gridW = 20;
Graphics2D dg = (Graphics2D) g;
dg.setStroke(new BasicStroke(2));
// 画水平线
dg.setColor(Color.black);
for (int i = 1; i < 400 / gridH; i++) {
dg.drawLine(20, i * gridH, 380, i * gridH);
}
// 画垂直线
dg.setColor(Color.red);
for (int j = 1; j < 400 / gridW; j++) {
dg.drawLine(j * gridW, 20, j * gridW, 380);
}


// 画原点
dg.setColor(Color.RED);
dg.fillOval(190, 190, 20, 20);


// 画长方形
dg.setColor(Color.blue);
drawRectangle(dg);

//画旋转以后的长方形
dg.setColor(Color.green);
drawRotateRect(dg);
}


private void drawRectangle(Graphics2D g) {
Rectangle rect = new Rectangle(200, 200, 80, 80);
drawObject(g, rect);
}


private void drawObject(Graphics2D g, Rectangle rect) {
g.drawRect(rect.x, rect.y, rect.width, rect.height);
}
private void drawRotateRect(Graphics2D g) {
Rectangle rect = new Rectangle(200, 200, 80, 80);
Matrix matrix = new Matrix();
matrix.rotate(40);


float points[] = { 0, 0, rect.width, 0, rect.width, rect.height, 0,
rect.height };
for(int j=0;j<2;j++){
float newPoints[] = matrix.getRotateMatrix().pointTransfer(points);

int i=0;
for (; i < newPoints.length-2; i += 2) {
g.drawLine((int) newPoints[i]+200, (int) newPoints[i + 1]+200,
(int) newPoints[i + 2]+200, (int) newPoints[i + 3]+200);


}
g.drawLine((int) newPoints[i]+200, (int) newPoints[i +1]+200,
(int) newPoints[0]+200, (int) newPoints[1]+200);

points=newPoints.clone();
}
}
}

package Matrix.com;


public class Matrix {
private RotateMatrix rMatrix=null;
public Matrix(){
rMatrix=new RotateMatrix();
}
public void rotate(int angle){
rMatrix.rotate(angle);
}
public RotateMatrix getRotateMatrix(){
return rMatrix;
}
}



package Matrix.com;


public class RotateMatrix {
private int rotateAngle=0;
private int centerX=0;
private int centerY=0;
private float matrix[]=new float[4];
public RotateMatrix(){

}
public void rotate(int angle){
double pAngle=(angle*1.0)/180*Math.PI;
matrix[0]=(float) Math.cos(pAngle);
matrix[1]=(float) Math.sin(pAngle);
matrix[2]=(float) -Math.sin(pAngle);
matrix[3]=(float) Math.cos(pAngle);
}


public float[] getRotateMatrix(){
return matrix;
}
public float[] pointTransfer(float []point){
float newPoint[]=new float[point.length];
for(int i=0;i<point.length;i+=2){
newPoint[i]=point[i]*matrix[0]+point[i+1]*matrix[2];
newPoint[i+1]=point[i]*matrix[1]+point[i+1]*matrix[3];
}
return newPoint;
}
}

结果1:




结果2:


原创粉丝点击