- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些代码可以渲染立方体并在按下箭头键时旋转它。
现在我尝试填充立方体的一侧,一开始效果很好。
但是在我观察了一下之后,我注意到,如果我将立方体旋转一定角度,应该填充的表面会表现得很奇怪。
代码:
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 点的顺序是 1
、2
、6
、5
,但是你的 y点的顺序为 1
、2
、5
、6
,这是错误的
应该是...
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 Swing和 Performing 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/
padding:initial 比 padding:0 有什么优势吗?示例: textarea { padding: 0; } Hello, world! 最佳答案 它们的意思是一
我尝试通过按钮填充 JList,然后在先前填充的 Jlist 上使用 DoubleClick 填充 JTextField。 代码: private void extractUsedVariables
我正在尝试做 var width = ($(this).width() + $(this).css('padding-left') + $(this).css('padding-right' ));
我在导航中添加了悬停效果,遗憾的是悬停也影响了上面的文字。如何在不影响文本位置的情况下向导航添加悬停? 可悲的是,我找不到解决这个问题的方法。 HTML 模板:http://projects.help
我是 F# 初学者,下面代码中的 %-5s 和 %5s 有什么作用?我认为它提供了空间填充,但我不确定它是如何填充的? printfn "%-5s %5s" "a" "b" 当我尝试 prin
我需要选择带狗的用户(带 type 等于“狗”的宠物) var User = Waterline.Collection.extend({ identity: 'user', attribute
我一直在尝试让 Excel 在一组列上应用公式,然后将模式扩展到整个行集。 这导致了以下代码: For i = 0 To avgsheetNames.Count - 1 If Contains(CSt
随着 Flutter 2.0 的发布,FlatButton已被替换为 TextButton . 因此,填充属性不再直接可用,而是作为 ButtonStyle属性(property)。 我的问题是,我该
这似乎是一个简单的问题,但我已经尝试了一个小时,似乎无法弄清楚。 我要做的就是用 Canvas 填充 MainWindow。我找不到任何允许这样做的属性,我能想到的唯一方法是设置 Canvas.Wid
这是a website具有移动 View 。 网站宽度为 640 像素,但 iPhone 以 678 像素渲染文档。在 Android 中看起来很棒。 我添加了视口(viewport)元: 主体 C
我正在使用 GridBagLayout到(当前)显示两行。我知道这种布局对于这项任务来说太过分了,但我正在努力学习如何使用它。问题是我已将两个面板添加到两个单独的行中,并且内容周围存在巨大差距(请参见
我有以下代码已传递给我并创建多边形: var map; function initialize() { var myLatlng = new google.maps.LatLng(-36.4
我在 Jpanel 中有一些项目,然后将其推到顶部并用作基本搜索引擎的工具栏。我遇到一个问题,因为没有足够的空间,所以我的最后一个组合框没有显示。但是,左侧有很多空白空间,我需要移动所有内容来填充 J
我创建了带有阈值的二进制图像。如下图所示如何改变白色形状的颜色以使其可索引? 到目前为止,这是我的代码: void threshold() { cv::Mat src_8uc3_img = c
我有一个 JTable,我想知道是否有更好的方法来填充它,这是我的代码: //Metodo para llenar un jtable con datos de la base public stat
我想要做的是裁剪一个卷以删除所有不相关的数据。例如,假设我有一个 100x100x100 的体积,其中填充了 0,但其中的 50x50x50 体积则填充了 1。如何从原始体积中获得裁剪后的 50x50
因此,我正在创建一种对一组数字进行洗牌的方法,其想法是创建这些数字的总体。因此,我创建了一个循环,对数字进行洗牌,然后将其添加到数组列表中,但是经过一些调试语句后,我发现它确实对数字进行洗牌,但只将最
假设我有这两个类: public class A where T : IEntityWithID, new() { private static EntityInfo entityInfo =
我正在尝试添加用户输入的两个大整数作为字符串。当两个输入字符串的长度不同时,我尝试用零填充较短的数字,但它不起作用。因此,如果我输入 456 和 7,它会给出 3,前面有一些随机字符。感谢您的任何建议
这是我将内容打印到表格 View 的代码 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: Index
我是一名优秀的程序员,十分优秀!