- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试为游戏扩展实现滚动角度,为了模拟它,我最好的方法是围绕屏幕中心旋转矩形。
问题是当我使用简单的旋转函数旋转矩形时,会出现黑色条纹(注意我使用的是 BufferStrategy)。
截图
这是旋转函数:
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));
}
}
}
请注意,矩形数据存储在连续的物质中。
例如。 :第一个矩形的 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/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!