在 JPanel 中以笛卡尔坐标定义的中心形状
Center shape defined in Cartesian coordinates in JPanel
我有一个在笛卡尔坐标系中定义的形状(例如三角形),我想将该形状平移到 JPanel 的中心。我已经能够翻译 JPanel 的 0,0 方向,但我不知道如何根据 JPanel 的宽度和高度居中。我希望能够将边界矩形定义的任何形状居中。
int tPanelWidth = 200;
int tPanelHeight = 200;
// A triangle in lower right quadrant
Path2D tPath = new Path2D.Double();
tPath.moveTo(25,-25);
tPath.lineTo(50,-75);
tPath.lineTo(75,-25);
tPath.closePath();
// Determine translation distance to 0,0
double tX = Math.abs(Math.min(0,tPath.getBounds().getX()));
double tY = Math.abs(Math.min(0,tPath.getBounds().getY()));
AffineTransform tAt = new AffineTransform();
tAt.translate(tX,tY);
tPath.transform(tAt);
这使 JPanel 左上角的三角形倒置(不需要),有些符合预期。那么为了将三角形平移到中心,它应该在面板宽度和高度的一半左右?然后我将上面的更改为:
// tAt.translate(tX,tY);
tAt.translate(tX+(tPanelWidth/2),tY+(tPanelHeight/2));
现在三角形在JPanel的右下角,宽度和高度的一半太多了。然后我随机尝试 /4 并且它很接近,但不准确并且在数学上不正确或者至少没有意义。当 JPanel 不是方形时,它也不起作用。
那么,问题...
- 有些坐标是负数(您已经补偿了那些)
- 形状的原点不是 0x0,所以它是偏移量
所以,除了“负坐标”变换,你还需要应用“偏移”平移,这样形状的原点就变成了0x0
,就像...
int midX = getWidth() / 2;
int midY = getHeight() / 2;
Rectangle pathBounds = tPath.getBounds();
// Because the x/y position may not be 0/0
int xDelta = pathBounds.x * -1;
int yDelta = pathBounds.y * -1;
int xPos = (midX - (pathBounds.width / 2)) + xDelta;
int yPos = (midY - (pathBounds.height / 2)) + yDelta;
可以产生类似...
(注意:我还渲染了形状的边界作为二次检查)
现在,显然,这只是专注于以形状边界为中心,您可能需要做一些额外的补偿,但这应该给您一个起点。
可运行示例...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Path2D tPath;
public TestPane() {
// A triangle in lower right quadrant
tPath = new Path2D.Double();
tPath.moveTo(25, -25);
tPath.lineTo(50, -75);
tPath.lineTo(75, -25);
tPath.closePath();
// Determine translation distance to 0,0
double tX = Math.abs(Math.min(0, tPath.getBounds().getX()));
double tY = Math.abs(Math.min(0, tPath.getBounds().getY()));
AffineTransform tAt = new AffineTransform();
tAt.translate(tX, tY);
tPath.transform(tAt);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int midX = getWidth() / 2;
int midY = getHeight() / 2;
g2d.setColor(Color.RED);
g2d.drawLine(0, midY, getWidth(), midY);
g2d.drawLine(midX, 0, midX, getHeight());
g2d.setColor(Color.BLACK);
Rectangle pathBounds = tPath.getBounds();
// Because the x/y position may not be 0/0
int xDelta = pathBounds.x * -1;
int yDelta = pathBounds.y * -1;
int xPos = (midX - (pathBounds.width / 2)) + xDelta;
int yPos = (midY - (pathBounds.height / 2)) + yDelta;
g2d.translate(xPos, yPos);
g2d.draw(tPath);
g2d.draw(tPath.getBounds());
g2d.dispose();
}
}
}
nb:我选择在绘画路径的上下文中修改形状,您可以将变换应用于形状本身,但这取决于您的要求,即:是否还有其他依赖是否在原始形状位置
我有一个在笛卡尔坐标系中定义的形状(例如三角形),我想将该形状平移到 JPanel 的中心。我已经能够翻译 JPanel 的 0,0 方向,但我不知道如何根据 JPanel 的宽度和高度居中。我希望能够将边界矩形定义的任何形状居中。
int tPanelWidth = 200;
int tPanelHeight = 200;
// A triangle in lower right quadrant
Path2D tPath = new Path2D.Double();
tPath.moveTo(25,-25);
tPath.lineTo(50,-75);
tPath.lineTo(75,-25);
tPath.closePath();
// Determine translation distance to 0,0
double tX = Math.abs(Math.min(0,tPath.getBounds().getX()));
double tY = Math.abs(Math.min(0,tPath.getBounds().getY()));
AffineTransform tAt = new AffineTransform();
tAt.translate(tX,tY);
tPath.transform(tAt);
这使 JPanel 左上角的三角形倒置(不需要),有些符合预期。那么为了将三角形平移到中心,它应该在面板宽度和高度的一半左右?然后我将上面的更改为:
// tAt.translate(tX,tY);
tAt.translate(tX+(tPanelWidth/2),tY+(tPanelHeight/2));
现在三角形在JPanel的右下角,宽度和高度的一半太多了。然后我随机尝试 /4 并且它很接近,但不准确并且在数学上不正确或者至少没有意义。当 JPanel 不是方形时,它也不起作用。
那么,问题...
- 有些坐标是负数(您已经补偿了那些)
- 形状的原点不是 0x0,所以它是偏移量
所以,除了“负坐标”变换,你还需要应用“偏移”平移,这样形状的原点就变成了0x0
,就像...
int midX = getWidth() / 2;
int midY = getHeight() / 2;
Rectangle pathBounds = tPath.getBounds();
// Because the x/y position may not be 0/0
int xDelta = pathBounds.x * -1;
int yDelta = pathBounds.y * -1;
int xPos = (midX - (pathBounds.width / 2)) + xDelta;
int yPos = (midY - (pathBounds.height / 2)) + yDelta;
可以产生类似...
(注意:我还渲染了形状的边界作为二次检查)
现在,显然,这只是专注于以形状边界为中心,您可能需要做一些额外的补偿,但这应该给您一个起点。
可运行示例...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Path2D tPath;
public TestPane() {
// A triangle in lower right quadrant
tPath = new Path2D.Double();
tPath.moveTo(25, -25);
tPath.lineTo(50, -75);
tPath.lineTo(75, -25);
tPath.closePath();
// Determine translation distance to 0,0
double tX = Math.abs(Math.min(0, tPath.getBounds().getX()));
double tY = Math.abs(Math.min(0, tPath.getBounds().getY()));
AffineTransform tAt = new AffineTransform();
tAt.translate(tX, tY);
tPath.transform(tAt);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int midX = getWidth() / 2;
int midY = getHeight() / 2;
g2d.setColor(Color.RED);
g2d.drawLine(0, midY, getWidth(), midY);
g2d.drawLine(midX, 0, midX, getHeight());
g2d.setColor(Color.BLACK);
Rectangle pathBounds = tPath.getBounds();
// Because the x/y position may not be 0/0
int xDelta = pathBounds.x * -1;
int yDelta = pathBounds.y * -1;
int xPos = (midX - (pathBounds.width / 2)) + xDelta;
int yPos = (midY - (pathBounds.height / 2)) + yDelta;
g2d.translate(xPos, yPos);
g2d.draw(tPath);
g2d.draw(tPath.getBounds());
g2d.dispose();
}
}
}
nb:我选择在绘画路径的上下文中修改形状,您可以将变换应用于形状本身,但这取决于您的要求,即:是否还有其他依赖是否在原始形状位置