gpt4 book ai didi

java - 如何在Java中绘制像素完美的旋转矩形?

转载 作者:太空宇宙 更新时间:2023-11-04 13:42:45 25 4
gpt4 key购买 nike

我正在尝试为游戏扩展实现滚动角度,为了模拟它,我最好的方法是围绕屏幕中心旋转矩形。

问题是当我使用简单的旋转函数旋转矩形时,会出现黑色条纹(注意我使用的是 BufferStrategy)。

截图

enter image description here

这是旋转函数:

public void rot(int ai[], int ai1[], int i, int j, int k, int l)
{
if(k != 0)
{
for(int i1 = 0; i1 < l; i1++)
{
int j1 = ai[i1];
int k1 = ai1[i1];
ai[i1] = i + (int)((float)(j1 - i) * cos(k) - (float)(k1 - j) * sin(k));
ai1[i1] = j + (int)((float)(j1 - i) * sin(k) + (float)(k1 - j) * cos(k));
}

}
}
  • ai[] = x 坐标
  • ai1[] = y 坐标
  • i = x 旋转中心点
  • j = y 轴旋转中心点
  • k = 旋转角度
  • l = 两个数组的长度

请注意,矩形数据存储在连续的物质中。

例如。 :第一个矩形的 y 坐标为 [0, 0, 100, 100],第二个矩形的 y 坐标为 [100, 100, 200, 200],依此类推。

我不想使用 Graphics2D.rotate(),因为这对我的目的来说影响了太多的质量,而抗锯齿只会产生相同的条纹,但它们看起来更平滑。

我应该做什么?

编辑:提供测试代码。

主类:

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;

import javax.swing.JOptionPane;

class ReplayViewer extends Canvas implements Runnable
{
private static final long serialVersionUID = 355508539070062621L;
private static boolean running = false;
private Thread thread;
private Graphics g;
private BufferStrategy bs;

Medium medium;

private synchronized void start()
{
if(running)
return;

createBufferStrategy(3);
bs = this.getBufferStrategy();

g = bs.getDrawGraphics();

running = true;
thread = new Thread(this);
thread.start();
}

private synchronized void stop()
{
try
{
thread.join();
g.dispose();
}catch (InterruptedException e)
{
e.printStackTrace();
}
}

public void run()
{
long lastTime = System.nanoTime();
final float numOfTicks = 30F;
float ns = 1000000000 / numOfTicks;
double delta = 0;

while(running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;

if (delta >= 1)
{
updateGameState();
drawToScreen();
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
e.printStackTrace();
}
delta--;
}
}
stop();
}

private void updateGameState()
{

}

private void drawToScreen()
{
medium.d(g);
bs.show();
}

public ReplayViewer()
{
medium = new Medium();
setPreferredSize(new Dimension(medium.w, medium.h));
}

public static void main(String[] args)
{
try
{
final Frame frame = new Frame("NFM Replay Viewer");
ReplayViewer rply = new ReplayViewer();

frame.add(rply);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
running = false;
frame.setVisible(false);
frame.dispose();
System.exit(0);
}
});

rply.start();

} catch (Exception e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Viewer cannot be open!", "Error", 0);
}
}
}

中级:

import java.awt.Color;
import java.awt.Graphics;

public class Medium
{
int focus_point;
int ground;
int skyline;
int fade[] = { 3000, 4500, 6000, 7500, 9000, 10500, 12000, 13500, 15000, 16500, 18000, 19500, 21000, 22500, 24000, 25500 };
int cldd[] = { 210, 210, 210, 1, -1000 };
int clds[] = { 210, 210, 210 };
int osky[] = { 170, 220, 255 };
int csky[] = { 170, 220, 255 };
int ogrnd[] = { 205, 200, 200 };
int cgrnd[] = { 205, 200, 200 };
int texture[] = { 0, 0, 0, 50 };
int cpol[] = { 215, 210, 210 };
int crgrnd[] = { 205, 200, 200 };
int cfade[] = { 255, 220, 220 };
int snap[] = { 0, 0, 0 };
int fogd;
boolean loadnew;
boolean lightson;
boolean darksky;
int lightn;
int lilo;
boolean lton;
int noelec;
int trk;
boolean crs;
int cx;
int cy;
int cz;
int xz;
int zy;
int x;
int y;
int z;
int iw;
int ih;
int w;
int h;
int nsp;
int spx[];
int spz[];
int sprad[];
int adv;
float tcos[];
float tsin[];
int lastmaf;
int checkpoint;
boolean lastcheck;
float elecr;
boolean cpflik;
boolean nochekflk;
int cntrn;
boolean diup[] = { false, false, false };
int rand[] = { 0, 0, 0 };
int trn;
int hit;
int ogpx[][];
int ogpz[][];
float pvr[][];
int cgpx[];
int cgpz[];
int pmx[];
float pcv[];
int sgpx;
int sgpz;
int nrw;
int ncl;
int noc;
int clx[];
int clz[];
int cmx[];
int clax[][][];
int clay[][][];
int claz[][][];
int clc[][][][];
int nmt;
int mrd[];
int nmv[];
int mtx[][];
int mty[][];
int mtz[][];
int mtc[][][];
int nst;
int stx[];
int stz[];
int stc[][][];
boolean bst[];
int twn[];
int resdown;
int xy;

public float sin(int i)
{
for(; i >= 360; i -= 360) { }
for(; i < 0; i += 360) { }
return tsin[i];
}

public float cos(int i)
{
for(; i >= 360; i -= 360) { }
for(; i < 0; i += 360) { }
return tcos[i];
}

public int ys(int i, int j)
{
if (j < 10)
j = 10;
return ((j - focus_point) * (cy - i)) / j + i;
}

public void d(Graphics graphics2d)
{
nsp = 0;
int loops = 0;
if (xz > 360)
{
xz -= 360;
}
if (xz < 0)
{
xz += 360;
}
for(; zy >= 90; zy -= 180) { loops++; }
for(; zy < -90; zy += 180) { loops--; }
ground = 250 - y;
int ai[] = new int[4];
int ai1[] = new int[4];
int i = cgrnd[0];
int j = cgrnd[1];
int k = cgrnd[2];
int l = crgrnd[0];
int i1 = crgrnd[1];
int j1 = crgrnd[2];
int k1;

if(loops % 2 == 0)
k1 = h + cx;
else
k1 = ih - cx;

for (int l1 = 0; l1 < 16; l1++)
{
int j2 = fade[l1];
int l2;

if(loops % 2 == 0)
{
l2 = ground;
if (zy != 0)
{
l2 = cy + (int) ((ground - cy) * cos(zy) - (fade[l1] - cz) * sin(zy));
j2 = cz + (int) ((ground - cy) * sin(zy) + (fade[l1] - cz) * cos(zy));
}
} else
{
l2 = -ground + h;
if(zy != 0)
{
l2 = cy + (int)((float)(-ground + h - cy) * cos(zy) - (float)(fade[l1] - cz) * sin(zy));
j2 = cz + (int)((float)(-ground + h - cy) * sin(zy) + (float)(fade[l1] - cz) * cos(zy));
}
}
ai[0] = iw;
ai1[0] = ys(l2, j2);
if (ai1[0] < ih - cx)
{
ai1[0] = ih - cx;
}
if (ai1[0] > h + cx)
{
ai1[0] = h + cx;
}
ai[1] = iw - cx;
ai1[1] = k1;
ai[2] = w + cx;
ai1[2] = k1;
ai[3] = w + cx;
ai1[3] = ai1[0];
k1 = ai1[0];
if (l1 > 0)
{
l = (l * 7 + cfade[0]) / 8;
i1 = (i1 * 7 + cfade[1]) / 8;
j1 = (j1 * 7 + cfade[2]) / 8;
if (l1 < 3)
{
i = (i * 7 + cfade[0]) / 8;
j = (j * 7 + cfade[1]) / 8;
k = (k * 7 + cfade[2]) / 8;
} else
{
i = l;
j = i1;
k = j1;
}
}
rot(ai, ai1, cx, cy, xy, 4);
graphics2d.setColor(new Color(i, j, k));
graphics2d.fillPolygon(ai, ai1, 4);
}
if (lightn != -1 && lton)
{
if (lightn < 16)
{
if (lilo > lightn + 217)
{
lilo -= 3;
} else
{
lightn = (int) (16F + 16F * random());
}
} else if (lilo < lightn + 217)
{
lilo += 7;
} else
{
lightn = (int) (16F * random());
}
csky[0] = (int) (lilo + lilo * (snap[0] / 100F));
if (csky[0] > 255)
{
csky[0] = 255;
}
if (csky[0] < 0)
{
csky[0] = 0;
}
csky[1] = (int) (lilo + lilo * (snap[1] / 100F));
if (csky[1] > 255)
{
csky[1] = 255;
}
if (csky[1] < 0)
{
csky[1] = 0;
}
csky[2] = (int) (lilo + lilo * (snap[2] / 100F));
if (csky[2] > 255)
{
csky[2] = 255;
}
if (csky[2] < 0)
{
csky[2] = 0;
}
}
i = csky[0];
j = csky[1];
k = csky[2];
int i2 = i;
int k2 = j;
int i3 = k;

int j3;
int k3;

if(loops % 2 == 0)
{
j3 = cy + (int) ((skyline - 700 - cy) * cos(zy) - (7000 - cz) * sin(zy));
k3 = cz + (int) ((skyline - 700 - cy) * sin(zy) + (7000 - cz) * cos(zy));
} else
{
j3 = cy + (int) ((-skyline + 700 + h - cy) * cos(zy) - (7000 - cz) * sin(zy));
k3 = cz + (int) ((-skyline + 700 + h - cy) * sin(zy) + (7000 - cz) * cos(zy));
}

j3 = ys(j3, k3);

int l3;

if(loops % 2 == 0)
l3 = ih - cx;
else
l3 = h + cx;

for (int i4 = 0; i4 < 16; i4++)
{
int k4 = fade[i4];
int i5;

if (loops % 2 == 0)
{
i5 = skyline;
if (zy != 0)
{
i5 = cy + (int) ((skyline - cy) * cos(zy) - (fade[i4] - cz) * sin(zy));
k4 = cz + (int) ((skyline - cy) * sin(zy) + (fade[i4] - cz) * cos(zy));
}
} else
{
i5 = -skyline + h;
if (zy != 0)
{
i5 = cy + (int) ((-skyline + h - cy) * cos(zy) - (fade[i4] - cz) * sin(zy));
k4 = cz + (int) ((-skyline + h - cy) * sin(zy) + (fade[i4] - cz) * cos(zy));
}
}

ai[0] = iw - cx;
ai1[0] = ys(i5, k4);
if (ai1[0] < ih - cx)
{
ai1[0] = ih - cx;
}
if (ai1[0] > h + cx)
{
ai1[0] = h + cx;
}
ai[1] = iw - cx;
ai1[1] = l3;
ai[2] = w + cx;
ai1[2] = l3;
ai[3] = w + cx;
ai1[3] = ai1[0];
l3 = ai1[0];
if (i4 > 0)
{
i = (i * 7 + cfade[0]) / 8;
j = (j * 7 + cfade[1]) / 8;
k = (k * 7 + cfade[2]) / 8;
}
rot(ai, ai1, cx, cy, xy, 4);
graphics2d.setColor(new Color(i, j, k));
graphics2d.fillPolygon(ai, ai1, 4);
}
ai[0] = iw - cx;
ai1[0] = l3;
ai[1] = iw - cx;
ai1[1] = k1;
ai[2] = w + cx;
ai1[2] = k1;
ai[3] = w + cx;
ai1[3] = l3;

float f = (Math.abs(y) - 250F) / (fade[0] * 2);
if (f < 0.0F)
{
f = 0.0F;
}
if (f > 1.0F)
{
f = 1.0F;
}
i = (int) ((i * (1.0F - f) + l * (1.0F + f)) / 2.0F);
j = (int) ((j * (1.0F - f) + i1 * (1.0F + f)) / 2.0F);
k = (int) ((k * (1.0F - f) + j1 * (1.0F + f)) / 2.0F);
rot(ai, ai1, cx, cy, xy, 4);
graphics2d.setColor(new Color(i, j, k));
graphics2d.fillPolygon(ai, ai1, 4);

if (resdown != 2)
{
for (int j4 = 1; j4 < 20; j4++)
{
int l4 = 7000;
int j5;

if (loops % 2 == 0)
{
j5 = skyline - 700 - j4 * 70;
if (zy != 0 && j4 != 19)
{
j5 = cy + (int) ((skyline - 700 - j4 * 70 - cy) * cos(zy) - (7000 - cz) * sin(zy));
l4 = cz + (int) ((skyline - 700 - j4 * 70 - cy) * sin(zy) + (7000 - cz) * cos(zy));
}
} else
{
j5 = -skyline + 700 + j4 * 70 + h;
if (zy != 0 && j4 != 19)
{
j5 = cy + (int) ((-skyline + 700 + j4 * 70 + h - cy) * cos(zy) - (7000 - cz) * sin(zy));
l4 = cz + (int) ((-skyline + 700 + j4 * 70 + h - cy) * sin(zy) + (7000 - cz) * cos(zy));
}
}

ai[0] = iw - cx;
if (j4 != 19)
{
ai1[0] = ys(j5, l4);
if (ai1[0] > h + cx)
{
ai1[0] = h + cx;
}
if (ai1[0] < ih - cx)
{
ai1[0] = ih - cx;
}
} else
{
if (loops % 2 == 0)
ai1[0] = ih - cx;
else
ai1[0] = h + cx;
}
ai[1] = iw - cx;
ai1[1] = j3;
ai[2] = w + cx;
ai1[2] = j3;
ai[3] = w + cx;
ai1[3] = ai1[0];
j3 = ai1[0];
i2 = (int) (i2 * 0.99099999999999999D);
k2 = (int) (k2 * 0.99099999999999999D);
i3 = (int) (i3 * 0.998D);
rot(ai, ai1, cx, cy, xy, 4);
graphics2d.setColor(new Color(i2, k2, i3));
graphics2d.fillPolygon(ai, ai1, 4);
}
}
zy += 180 * loops;
zy++;
xy++;
}

public float random()
{
if (cntrn == 0) {
int i = 0;
do {
rand[i] = (int) (10D * Math.random());
if (Math.random() > Math.random())
diup[i] = false;
else
diup[i] = true;
} while (++i < 3);
cntrn = 20;
} else {
cntrn--;
}
int j = 0;
do
if (diup[j]) {
rand[j]++;
if (rand[j] == 10)
rand[j] = 0;
} else {
rand[j]--;
if (rand[j] == -1)
rand[j] = 9;
}
while (++j < 3);
trn++;
if (trn == 3)
trn = 0;
return rand[trn] / 10F;
}

public Medium()
{
focus_point = 400;
ground = 250;
skyline = -300;
fogd = 7;
loadnew = false;
lightson = false;
darksky = false;
lightn = -1;
lilo = 217;
lton = false;
noelec = 0;
trk = 0;
crs = false;
cx = 400;
cy = 225;
cz = 50;
xz = 0;
zy = 0;
x = 0;
y = -1000;
z = 0;
iw = 0;
ih = 0;
w = 800;
h = 450;
nsp = 0;
spx = new int[7];
spz = new int[7];
sprad = new int[7];
adv = 500;
tcos = new float[360];
tsin = new float[360];
lastmaf = 0;
checkpoint = -1;
lastcheck = false;
elecr = 0.0F;
cpflik = false;
nochekflk = false;
cntrn = 0;
trn = 0;
hit = 45000;
ogpx = null;
ogpz = null;
pvr = null;
cgpx = null;
cgpz = null;
pmx = null;
pcv = null;
sgpx = 0;
sgpz = 0;
nrw = 0;
ncl = 0;
noc = 0;
clx = null;
clz = null;
cmx = null;
clax = null;
clay = null;
claz = null;
clc = null;
nmt = 0;
mrd = null;
nmv = null;
mtx = null;
mty = null;
mtz = null;
mtc = null;
nst = 0;
stx = null;
stz = null;
stc = null;
bst = null;
twn = null;
resdown = 0;
for (int i = 0; i < 360; i++)
{
tcos[i] = (float) Math.cos(i * 0.017453292519943295D);
}
for (int j = 0; j < 360; j++)
{
tsin[j] = (float) Math.sin(j * 0.017453292519943295D);
}
xy = 0;
}

public void rot(int ai[], int ai1[], int i, int j, int k, int l)
{
if(k != 0)
{
for(int i1 = 0; i1 < l; i1++)
{
int j1 = ai[i1];
int k1 = ai1[i1];
ai[i1] = i + (int)((float)(j1 - i) * cos(k) - (float)(k1 - j) * sin(k));
ai1[i1] = j + (int)((float)(j1 - i) * sin(k) + (float)(k1 - j) * cos(k));
}

}
}
}

最佳答案

旋转和其他矩阵变换实际上很难正确执行。您看到的伪像可能是由于旋转代码中的逻辑错误或浮点精度错误造成的(您是否尝试过使用double而不是float?)。

但好消息是您实际上不需要重新实现这个轮子。 Java 提供了AffineTransform类正是为了这个目的。本质上,您改变的是图形对象的状态,而不是您正在绘制的元素本身。这是Java tutorial ,还有无数related questions .

关于java - 如何在Java中绘制像素完美的旋转矩形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31107813/

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