- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想用 Java 画一条“像素化”的线。这是我所说的“像素化”行的示例:
这就是我的代码试图做的事情。假设该行从 (x1, y1)
到 (x2, y2)
并且我想要它们之间有 10 个“ block ”长度的行(我会调用它们是像素,但它们将使用许多像素显示):
(x1, y1)
制作一个矩形作为 (0, 0)
并且宽度 x2 - x1
和高度 y2 - y1
.cOriginal
。网格
。(0, 0)
到左下角,将属于该线的网格空间标记为 true
。我确信我的 Bresenham 算法适用于所有象限和所有情况。这是我有点模糊的部分。目前,我首先定义了 2 个“放大”网格的变量。这些定义如下:
float widthScalingFactor = (float) widthOriginal/(float) newWidth;float heightScalingFactor = (float) heightOriginal/(float) newHeight;
(我不知道为什么那不是格式化......)接下来我遍历 grid
并且如果 grid[i][j]
(是 true
),我在 (x1 + (i * widthScalingFactor), yOffset + (j * heightScalingFactor))
处绘制了一个宽度和高度为 10 的矩形。
这是当前的方法:
public static void drawPixelatedLine(Graphics g, int x1, int y1, int x2, int y2) {
int widthOriginal = x2 - x1;
int heightOriginal = y2 - y1;
if(widthOriginal <= 0 && heightOriginal <= 0){
int temp = x2;
x2 = x1;
x1 = temp;
temp = y2;
y2 = y1;
y1 = temp;
}
double cOriginal = Math.sqrt(widthOriginal * widthOriginal + heightOriginal * heightOriginal);
double shrinkingFactor = 10d / cOriginal;
int newWidth = (int) Math.round(shrinkingFactor * widthOriginal);
int newHeight = (int) Math.round(shrinkingFactor * heightOriginal);
newWidth = (newWidth <= 0 ? 1 : newWidth);
newHeight = (newHeight <= 0 ? 1 : newHeight);
boolean[][] grid = new boolean[newWidth][newHeight];
int rescaledX1 = 0;
int rescaledY1 = 0;
int rescaledX2 = newWidth - 1;
int rescaledY2 = newHeight - 1;
int x = rescaledX1;
int y = rescaledY1;
int dx = Math.abs(rescaledX2 - rescaledX1);
int dy = Math.abs(rescaledY2 - rescaledY1);
int s1 = Utils.sign(rescaledX2 - rescaledX1);
int s2 = Utils.sign(rescaledY2 - rescaledY1);
boolean swap = false;
if (dy > dx) {
int temp = dx;
dx = dy;
dy = temp;
swap = true;
}
int D = 2 * dy - dx;
for (int i = 0; i < dx; i += 1) {
grid[x][y] = true;
while (D >= 0) {
D = D - 2 * dx;
if (swap) {
x += s1;
}
else {
y += s2;
}
}
D = D + 2 * dy;
if (swap) {
y += s2;
}
else {
x += s1;
}
}
int xOffset = x1;
int yOffset = y1;
float widthScalingFactor = (float) widthOriginal / (float) newWidth;
float heightScalingFactor = (float) heightOriginal / (float) newHeight;
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j]){
g.fillRect((int) (xOffset + (i * widthScalingFactor)), (int) (yOffset + (j * heightScalingFactor)), 10, 10);
}
}
}
现在这段代码在任何主要方向以及西北和东南方向绘制时部分起作用,尽管我绘制的矩形的大小似乎是错误的(这可能是因为我试图在一个平面上绘制 10 个大小为 10 的正方形距离可能超过 ~140 像素。但是,当我尝试向东北方向或西南方向绘制一条线时,它只会绘制一条水平线。以下是一些示例。
这是一条向西北方向行驶的线路,运行正常(我可以解决整个拉伸(stretch)/间隙问题)。
这是一条向东北方向的线,如您所见,它只是一条从原点向东到目的地 x 位置的直线。向西南画线时会发生类似的事情,只是它向南走并停在目的地的 y 位置。
目前您可以看到该线是否向西北方向移动,我只是翻转 2 个点,使其向东南方向移动。但是,我觉得我目前的方法不太正确,需要进行大量修改才能适应最后两种情况。
我如何修改我当前的算法或创建一个新算法来绘制“像素化”线条?
最佳答案
此代码演示了一种方法,其中所有坐标都缩放到较低的分辨率,然后以较低的分辨率绘制线,同时在 plot(x, y) 函数中再次放大。
明显的副作用是线条端点会四舍五入(实际上是截断)到较低的分辨率。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BresenhamBlocky {
static class TestPanel extends JPanel {
public TestPanel() {
setPreferredSize(new Dimension(800, 800));
}
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
g.setColor(Color.GRAY);
g.fillRect(0, 0, w, h);
g.setColor(Color.BLUE);
drawLine(g, w >> 1, h >> 1, targetX, targetY, 10);
}
}
public static void main(String[] argv) {
SwingUtilities.invokeLater(() -> { showTest(); });
}
static int targetX, targetY;
static void showTest() {
JFrame frame = new JFrame("Test");
JComponent test = new TestPanel();
test.setFocusable(true);
test.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
targetX = e.getX();
targetY = e.getY();
e.getComponent().repaint();
}
});
frame.setLayout(new BorderLayout());
frame.add(test, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void drawLine(Graphics g, int x0, int y0, int x1, int y1, int blockSize) {
int scaledX0 = x0 / blockSize;
int scaledY0 = y0 / blockSize;
int scaledX1 = x1 / blockSize;
int scaledY1 = y1 / blockSize;
int dx = scaledX1 - scaledX0;
int dy = scaledY1 - scaledY0;
int stepX = Integer.signum(dx);
int stepY = Integer.signum(dy);
dx = Math.abs(dx);
dy = Math.abs(dy);
int dx2 = dx << 1;
int dy2 = dy << 1;
int x = scaledX0;
int y = scaledY0;
int error;
if (dx >= dy) {
error = dy2 - dx;
do {
plot(g, x, y, blockSize);
if (error > 0) {
y += stepY;
error -= dx2;
}
error += dy2;
x += stepX;
} while (x != scaledX1);
} else {
error = dx2 - dy;
do {
plot(g, x, y, blockSize);
if (error > 0) {
x += stepX;
error -= dy2;
}
error += dx2;
y += stepY;
} while (y != scaledY1);
}
}
static void plot(Graphics g, int x, int y, int blockSize) {
int x0 = x * blockSize;
int y0 = y * blockSize;
int w = blockSize;
int h = blockSize;
g.fillRect(x0, y0, w, h);
}
}
(用鼠标点击移动直线的一个端点)
关于java - 如何在 Java 中制作 "Pixelated"行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44417784/
我正在编写一个 cordova 应用程序,需要隔离这些谷歌手机以调整样式 鉴于此: 我很难区分任何一款 Google Pixel 手机。 @media only screen and (min-wid
在 Web 布局中为像素和百分比定义距离的用例是什么? 在多个分辨率方面使用像素有什么缺点吗?它们会正确缩放吗? 最佳答案 百分比布局 这通常称为流体布局。您的元素将占用它们可用总空间的定义百分比。这
我正在处理使用 pixel.getGreen() 方法的作业。我的问题是,当我尝试使用 pixel.getGreen (不带括号)时,我得到的结果与使用带括号的方法时得到的结果不同。两者有什么区别?
我正在寻找 Pixel 2 虚拟设备。我已经更新到最新的 Android Studio RC2 版本,但似乎 Pixel 设备是列表中的最后一个。 我知道我可以创建具有 Pixel 2 分辨率的自定义
我需要降低图片的实际分辨率,使 4 像素矩形中的每个像素都是这 4 个像素的平均值。 即 p1 p2 p6 p7 a1 a1 a2 a2 p3 p4 p8 p9 ... -> a1
我正在尝试使用 Electron 在桌面应用程序中创建一个简单的 javascript Canvas 游戏。我正在使用像素艺术,所以为了让我的像素艺术图像在缩放时保持良好的质量,我使用了以下 CSS:
我想对 ee.Image 逐个像素地执行一些计算,但是,计算的结果必须服从概率高斯分布,因此一些像素将被修改,而另一些则不会。我已经编写了一个概率函数,但我不知道如何将它应用于 GEE 中的每个像素。
这是我的代码: int columns 3; int columnWidth = self.layer.bounds.size.width / 3; for (int c = 1; c < colum
1.将image.jpg加载到数组中2.从数组中随机选择坐标并显示该像素及其所有属性3. 从数组中使用弹出坐标。4. 重复#2 直到数组为空 这将显示一个填充了随机像素的图像。 最终结果始终是原始图像
我正在开发一个从 Wi-Fi 摄像头接收 UPD 广播数据包的应用程序。 在我发现在 Google Pixel 2/Pixel 2 XL 接收 UPD 广播数据包的问题之前,它曾经很好。 为了找出原因
我想将新的 Google 手机添加到 Chrome 开发工具中的模拟设备中。 有人知道 Pixel 3 和 Pixel 3 XL 的正确自定义设备设置吗? 最佳答案 您必须输入 视口(viewport
我在我的 React Native 应用程序中使用 0.5px 边框。这在大多数设备上效果很好,但在 iPhone 6 plus 上,这些边框显得模糊。在阅读了像素比率之后here我决定使用类似下面的
我正在开发一个网站,想看看它在 Google Pixel 和 Google Pixel XL 设备上的运行情况。由于我无权访问这些设备,因此我需要知道这些设备的视口(viewport)宽度、高度和设备
我知道我们是在点而不是像素上操作,在大多数情况下这很方便,但我需要使 UIView 的高度为 1 像素而不是 2 像素。因此,如果您在 Interaface 构建器中拖放一些 UIView(分隔线),
摘要和目标: 我正在尝试制作一个着色器来为游戏编辑器执行简单的窗口效果。该效果将绘制一个具有低值边框颜色和高值突出显示的框架。我尝试了很多方法,但总的来说,我只提出了一种可能的解决方案来使用 GPU
我的代码目前包含加载图像,这是成功的,我认为与问题无关。 然后我继续将彩色图像转换为名为 rgb 的 np.array # convert image into array rgb =
我对使用 Visual C++ 进行图像处理相当陌生,我正在寻找一种方法来读取黑白 TIFF 文件并将图像写入表示 0 或 1 的十六进制值数组,然后获取 0 的位置信息(黑色)或 1(白色)。 经过
WebKit 引入了 -webkit-device-pixel-ratio 媒体功能和 window.devicePixelRatio JavaScript 属性,以允许网络作者检测他们的页面是否正在
我正在执行一项任务,将每个像素有 8 位 (uint8_t) 且每个像素只能为 0 或 1(或 255)的大型二进制标签图像转换为数组uint64_t 数字和 uint64_t 数字中的每一位代表一个
需要能够为不同的设备像素比值指定不同的 css。如何做到这一点 例如, 0 @media (-webkit-max-device-pixel-ratio:1.0) { > .
我是一名优秀的程序员,十分优秀!