gpt4 book ai didi

java - 填充四边形

转载 作者:行者123 更新时间:2023-12-01 10:10:57 25 4
gpt4 key购买 nike

我有一些代码可以渲染立方体并在按下箭头键时旋转它。

现在我尝试填充立方体的一侧,一开始效果很好。

但是在我观察了一下之后,我注意到,如果我将立方体旋转一定角度,应该填充的表面会表现得很奇怪。

代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class Cube extends JFrame {
double p[][] = new double[9][4];

int x=1, y=2, z=3;

boolean xRotUp = false;
boolean yRotRight = false;
boolean xRotDown = false;
boolean yRotLeft = false;

double px, py, pz;

double angle_x = 0.02;
double angle_y = 0.0150;
double angle_z = 0.010;


public Cube() {
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

addKeyListener(new KeyListener() {

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case 37:
yRotLeft = false;
break;
case 38:
xRotUp = false;
break;
case 39:
yRotRight = false;
break;
case 40:
xRotDown = false;
break;
}
}

@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case 37:
if (!yRotRight) {
yRotLeft = true;
} else {
yRotRight = false;
}
break;
case 38:
if (!xRotDown) {
xRotUp = true;
} else {
xRotDown = false;
}
break;
case 39:
if (!yRotLeft) {
yRotRight = true;
} else {
yRotLeft = false;
}
break;
case 40:
if (!xRotUp) {
xRotDown = true;
} else {
xRotUp = false;
}
break;
}
}
});
}

public void rotate() {
for (int i=0; i<9;i++) {
px = p[i][x];
py = p[i][y];
pz = p[i][z];
if (xRotUp) {
p[i][y] = py*Math.cos(angle_x)-pz*Math.sin(angle_x);
p[i][z] = py*Math.sin(angle_x)+pz*Math.cos(angle_x);

py = p[i][y];
pz = p[i][z];
}

if (xRotDown) {
p[i][y] = py*Math.cos(-angle_x)-pz*Math.sin(-angle_x);
p[i][z] = py*Math.sin(-angle_x)+pz*Math.cos(-angle_x);

py = p[i][y];
pz = p[i][z];
}

if (yRotRight) {
p[i][x] = px*Math.cos(angle_y)+pz*Math.sin(angle_y);
p[i][z] =-px*Math.sin(angle_y)+pz*Math.cos(angle_y);

px = p[i][x];
}

if (yRotLeft) {
p[i][x] = px*Math.cos(-angle_y)+pz*Math.sin(-angle_y);
p[i][z] =-px*Math.sin(-angle_y)+pz*Math.cos(-angle_y);

px = p[i][x];
}
}
}

public void init() {
setBackground(new Color(0,0,0));

p[1][x] = -100; p[1][y] = -100; p[1][z] = -100;
p[2][x] = +100; p[2][y] = -100; p[2][z] = -100;
p[3][x] = +100; p[3][y] = -100; p[3][z] = +100;
p[4][x] = -100; p[4][y] = -100; p[4][z] = +100;
p[5][x] = -100; p[5][y] = +100; p[5][z] = -100;
p[6][x] = +100; p[6][y] = +100; p[6][z] = -100;
p[7][x] = +100; p[7][y] = +100; p[7][z] = +100;
p[8][x] = -100; p[8][y] = +100; p[8][z] = +100;

/* 8 - - - - - 7
/ | / |
5 - - - - - 6 |
| | | |
| 4 - - - -|- 3
| / | /
1 - - - - - 2
*/
}

Image buffer;
Graphics2D gBuffer;

public void paint(Graphics g) {
if (buffer==null) {
buffer=createImage(this.getSize().width, this.getSize().height);
gBuffer=(Graphics2D)buffer.getGraphics();
}
gBuffer.clearRect(0,0,this.getSize().width, this.getSize().height);

gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

gBuffer.setColor(Color.LIGHT_GRAY);
gBuffer.drawLine((int)(p[4][x])+200,(int)(p[4][y])+200,(int)(p[6][x])+200,(int)(p[6][y])+200);
gBuffer.drawLine((int)(p[2][x])+200,(int)(p[2][y])+200,(int)(p[8][x])+200,(int)(p[8][y])+200);
gBuffer.drawLine((int)(p[1][x])+200,(int)(p[1][y])+200,(int)(p[7][x])+200,(int)(p[7][y])+200);
gBuffer.drawLine((int)(p[5][x])+200,(int)(p[5][y])+200,(int)(p[3][x])+200,(int)(p[3][y])+200);

gBuffer.setColor(Color.DARK_GRAY);
gBuffer.fillPolygon(new int[] {
(int)p[1][x]+200,
(int)p[2][x]+200,
(int)p[6][x]+200,
(int)p[5][x]+200},
new int[] {
(int)p[1][y]+200,
(int)p[2][y]+200,
(int)p[5][y]+200,
(int)p[6][y]+200
} , 4);
gBuffer.setColor(Color.CYAN);
gBuffer.drawLine((int)(p[1][x])+200,(int)(p[1][y])+200,(int)(p[2][x])+200,(int)(p[2][y])+200);
gBuffer.drawLine((int)(p[2][x])+200,(int)(p[2][y])+200,(int)(p[3][x])+200,(int)(p[3][y])+200);
gBuffer.drawLine((int)(p[3][x])+200,(int)(p[3][y])+200,(int)(p[4][x])+200,(int)(p[4][y])+200);
gBuffer.drawLine((int)(p[4][x])+200,(int)(p[4][y])+200,(int)(p[1][x])+200,(int)(p[1][y])+200);
gBuffer.drawLine((int)(p[5][x])+200,(int)(p[5][y])+200,(int)(p[6][x])+200,(int)(p[6][y])+200);
gBuffer.drawLine((int)(p[6][x])+200,(int)(p[6][y])+200,(int)(p[7][x])+200,(int)(p[7][y])+200);
gBuffer.setColor(Color.RED);
gBuffer.drawLine((int)(p[7][x])+200,(int)(p[7][y])+200,(int)(p[8][x])+200,(int)(p[8][y])+200);
gBuffer.setColor(Color.CYAN);
gBuffer.drawLine((int)(p[8][x])+200,(int)(p[8][y])+200,(int)(p[5][x])+200,(int)(p[5][y])+200);
gBuffer.drawLine((int)(p[1][x])+200,(int)(p[1][y])+200,(int)(p[5][x])+200,(int)(p[5][y])+200);
gBuffer.drawLine((int)(p[2][x])+200,(int)(p[2][y])+200,(int)(p[6][x])+200,(int)(p[6][y])+200);
gBuffer.drawLine((int)(p[3][x])+200,(int)(p[3][y])+200,(int)(p[7][x])+200,(int)(p[7][y])+200);
gBuffer.setColor(Color.BLUE);
gBuffer.drawLine((int)(p[4][x])+200,(int)(p[4][y])+200,(int)(p[8][x])+200,(int)(p[8][y])+200);

g.drawImage (buffer, 0, 0, this);
try {Thread.sleep(20);}
catch (InterruptedException e) {}



//for (int i=1;i<9;i++) {
// Rotation um z-Achse

//p[i][x] = px*Math.cos(angle_z)-py*Math.sin(angle_z);
//p[i][y] = py*Math.cos(angle_z)+px*Math.sin(angle_z);
// }

rotate();

repaint();
}

public void update(Graphics g) {paint(g);}
}

最佳答案

你的“关键”问题是多边形点的顺序......

gBuffer.fillPolygon(new int[]{
(int) p[1][x] + 200,
(int) p[2][x] + 200,
(int) p[6][x] + 200,
(int) p[5][x] + 200},
new int[]{
(int) p[1][y] + 200,
(int) p[2][y] + 200,
(int) p[5][y] + 200,
(int) p[6][y] + 200
}, 4);

你的 x 点的顺序是 1265,但是你的 y点的顺序为 1256,这是错误的

应该是...

gBuffer.fillPolygon(new int[]{
(int) p[1][x] + 200,
(int) p[2][x] + 200,
(int) p[6][x] + 200,
(int) p[5][x] + 200},
new int[]{
(int) p[1][y] + 200,
(int) p[2][y] + 200,
(int) p[6][y] + 200,
(int) p[5][y] + 200
}, 4);

现在,看看 Painting in AWT and SwingPerforming Custom Painting 。一般来说,非常不建议重写paint(或update),尤其是在处理顶级容器时。原因有很多,双缓冲就是其中之一,而且 0x0 实际上位于框架边框下方,这通常是意想不到的。

请记住,绘画是为了绘画,在绘画周期中,您永远不应该以任何方式修改 UI 的状态,并且您永远不应该在绘画方法中直接或间接调用 repaint ,当如果这样做,您的 CPU 可能会很快耗尽,并且您的程序将变得无响应。

如果您需要持续检查输入状态并更新 UI,请考虑使用 Swing Timer

Swing 组件默认情况下是双缓冲的,它也不会像从 JFrame 扩展那样将您锁定为单次使用。

您还应该避免使用KeyListener,主要是因为它们在需要键盘焦点时变化无常。一般来说Key Bindings API将为您提供更强大的 API

例如...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Cube extends JPanel {

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Cube());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

double p[][] = new double[9][4];

int x = 1, y = 2, z = 3;

public enum HorizontalRotation {
LEFT,
RIGHT,
NONE
}
public enum VerticalRotation {
UP,
DOWN,
NONE
}

private HorizontalRotation horizontalRotation = HorizontalRotation.NONE;
private VerticalRotation verticalRotation = VerticalRotation.NONE;

// boolean xRotUp = false;
// boolean yRotRight = false;
// boolean xRotDown = false;
// boolean yRotLeft = false;

double px, py, pz;

double angle_x = 0.02;
double angle_y = 0.0150;
double angle_z = 0.010;

public Cube() {
init();
addKeyBinding("Left", KeyEvent.VK_LEFT, HorizontalRotation.LEFT);
addKeyBinding("Right", KeyEvent.VK_RIGHT, HorizontalRotation.RIGHT);
addKeyBinding("Up", KeyEvent.VK_UP, VerticalRotation.UP);
addKeyBinding("Down", KeyEvent.VK_DOWN, VerticalRotation.DOWN);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}

protected void addKeyBinding(String name, int keyCode, HorizontalRotation rotation) {
addKeyBinding(name + ".pressed", KeyStroke.getKeyStroke(keyCode, 0, false), new HorizontalRotationAction(rotation));
addKeyBinding(name + ".released", KeyStroke.getKeyStroke(keyCode, 0, true), new HorizontalRotationAction(HorizontalRotation.NONE));
}

protected void addKeyBinding(String name, int keyCode, VerticalRotation rotation) {
addKeyBinding(name + ".pressed", KeyStroke.getKeyStroke(keyCode, 0, false), new VerticalRotationAction(rotation));
addKeyBinding(name + ".released", KeyStroke.getKeyStroke(keyCode, 0, true), new VerticalRotationAction(VerticalRotation.NONE));
}

protected void addKeyBinding(String name, KeyStroke keyStroke, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();

im.put(keyStroke, name);
am.put(name, action);
}

public void rotate() {
for (int i = 0; i < 9; i++) {
px = p[i][x];
py = p[i][y];
pz = p[i][z];
if (verticalRotation == VerticalRotation.UP) {
p[i][y] = py * Math.cos(angle_x) - pz * Math.sin(angle_x);
p[i][z] = py * Math.sin(angle_x) + pz * Math.cos(angle_x);

py = p[i][y];
pz = p[i][z];
} else if (verticalRotation == VerticalRotation.DOWN) {
p[i][y] = py * Math.cos(-angle_x) - pz * Math.sin(-angle_x);
p[i][z] = py * Math.sin(-angle_x) + pz * Math.cos(-angle_x);

py = p[i][y];
pz = p[i][z];
}

if (horizontalRotation == HorizontalRotation.RIGHT) {
p[i][x] = px * Math.cos(angle_y) + pz * Math.sin(angle_y);
p[i][z] = -px * Math.sin(angle_y) + pz * Math.cos(angle_y);

px = p[i][x];
} else if (horizontalRotation == HorizontalRotation.LEFT) {
p[i][x] = px * Math.cos(-angle_y) + pz * Math.sin(-angle_y);
p[i][z] = -px * Math.sin(-angle_y) + pz * Math.cos(-angle_y);

px = p[i][x];
}
}
repaint();
}

public void init() {
setBackground(new Color(0, 0, 0));

p[1][x] = -100;
p[1][y] = -100;
p[1][z] = -100;
p[2][x] = +100;
p[2][y] = -100;
p[2][z] = -100;
p[3][x] = +100;
p[3][y] = -100;
p[3][z] = +100;
p[4][x] = -100;
p[4][y] = -100;
p[4][z] = +100;
p[5][x] = -100;
p[5][y] = +100;
p[5][z] = -100;
p[6][x] = +100;
p[6][y] = +100;
p[6][z] = -100;
p[7][x] = +100;
p[7][y] = +100;
p[7][z] = +100;
p[8][x] = -100;
p[8][y] = +100;
p[8][z] = +100;

/* 8 - - - - - 7
/ | / |
5 - - - - - 6 |
| | | |
| 4 - - - -|- 3
| / | /
1 - - - - - 2
*/
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D gBuffer = (Graphics2D) g.create();

gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

gBuffer.setColor(Color.LIGHT_GRAY);
gBuffer.drawLine((int) (p[4][x]) + 200, (int) (p[4][y]) + 200, (int) (p[6][x]) + 200, (int) (p[6][y]) + 200);
gBuffer.drawLine((int) (p[2][x]) + 200, (int) (p[2][y]) + 200, (int) (p[8][x]) + 200, (int) (p[8][y]) + 200);
gBuffer.drawLine((int) (p[1][x]) + 200, (int) (p[1][y]) + 200, (int) (p[7][x]) + 200, (int) (p[7][y]) + 200);
gBuffer.drawLine((int) (p[5][x]) + 200, (int) (p[5][y]) + 200, (int) (p[3][x]) + 200, (int) (p[3][y]) + 200);

gBuffer.setColor(Color.DARK_GRAY);
gBuffer.fillPolygon(new int[]{
(int) p[1][x] + 200,
(int) p[2][x] + 200,
(int) p[6][x] + 200,
(int) p[5][x] + 200},
new int[]{
(int) p[1][y] + 200,
(int) p[2][y] + 200,
(int) p[6][y] + 200,
(int) p[5][y] + 200
}, 4);
gBuffer.setColor(Color.CYAN);
gBuffer.drawLine((int) (p[1][x]) + 200, (int) (p[1][y]) + 200, (int) (p[2][x]) + 200, (int) (p[2][y]) + 200);
gBuffer.drawLine((int) (p[2][x]) + 200, (int) (p[2][y]) + 200, (int) (p[3][x]) + 200, (int) (p[3][y]) + 200);
gBuffer.drawLine((int) (p[3][x]) + 200, (int) (p[3][y]) + 200, (int) (p[4][x]) + 200, (int) (p[4][y]) + 200);
gBuffer.drawLine((int) (p[4][x]) + 200, (int) (p[4][y]) + 200, (int) (p[1][x]) + 200, (int) (p[1][y]) + 200);
gBuffer.drawLine((int) (p[5][x]) + 200, (int) (p[5][y]) + 200, (int) (p[6][x]) + 200, (int) (p[6][y]) + 200);
gBuffer.drawLine((int) (p[6][x]) + 200, (int) (p[6][y]) + 200, (int) (p[7][x]) + 200, (int) (p[7][y]) + 200);
gBuffer.setColor(Color.RED);
gBuffer.drawLine((int) (p[7][x]) + 200, (int) (p[7][y]) + 200, (int) (p[8][x]) + 200, (int) (p[8][y]) + 200);
gBuffer.setColor(Color.CYAN);
gBuffer.drawLine((int) (p[8][x]) + 200, (int) (p[8][y]) + 200, (int) (p[5][x]) + 200, (int) (p[5][y]) + 200);
gBuffer.drawLine((int) (p[1][x]) + 200, (int) (p[1][y]) + 200, (int) (p[5][x]) + 200, (int) (p[5][y]) + 200);
gBuffer.drawLine((int) (p[2][x]) + 200, (int) (p[2][y]) + 200, (int) (p[6][x]) + 200, (int) (p[6][y]) + 200);
gBuffer.drawLine((int) (p[3][x]) + 200, (int) (p[3][y]) + 200, (int) (p[7][x]) + 200, (int) (p[7][y]) + 200);
gBuffer.setColor(Color.BLUE);
gBuffer.drawLine((int) (p[4][x]) + 200, (int) (p[4][y]) + 200, (int) (p[8][x]) + 200, (int) (p[8][y]) + 200);
gBuffer.dispose();
}

protected class HorizontalRotationAction extends AbstractAction {

private HorizontalRotation rotation;

public HorizontalRotationAction(HorizontalRotation rotation) {
this.rotation = rotation;
}

@Override
public void actionPerformed(ActionEvent e) {
horizontalRotation = rotation;
rotate();
}

}

protected class VerticalRotationAction extends AbstractAction {

private VerticalRotation rotation;

public VerticalRotationAction(VerticalRotation rotation) {
this.rotation = rotation;
}

@Override
public void actionPerformed(ActionEvent e) {
verticalRotation = rotation;
rotate();
}

}

}

关于java - 填充四边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36120343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com