我需要能夠通過 Swing 為圖形繪制非常擁擠的點。例如:讓我們看看以下幾點:
p1=(35.19589389346247,32.10152879327731),
p2 = (35.20319591121872,32.10318254621849),
p3 = (35.20752617756255,32.1025646605042),
p4 = (35.21007339305892,32.10107446554622),
p5 = (35.21310882485876,32.104636394957986),
等等...
我想繪制它們,但是,可以看出,它們的坐標彼此非常密集。另外,擴大比例也不起作用,只是移動了框架內的點。
以下是我的嘗試:
private void Oval(Graphics2D g2, String id, int locationX, int locationY) {
AffineTransform old = g2.getTransform();
g2.scale(4,4);
g2.setPaint(Color.blue);
g2.fillOval(locationX - Radius, locationY - Radius, Radius * 2, Radius * 2);
g2.setPaint(Color.black);
g2.drawString(id, locationX Radius, locationY - Radius);
g2.setTransform(old);
}
這是點圖的代碼,考慮到面板尺寸是 (1000,1000)。
這是點繪圖的輸出:

如您所見,它們相互覆寫,這顯然與我的意圖不同。我的目標是將它們分開,以便我們可以清楚地看到要點。
uj5u.com熱心網友回復:
因此,基本概念是對“虛擬”坐標(您的點)到“物理”坐標(螢屏)進行某種“轉換”
您確實嘗試通過縮放圖形背景關系來做到這一點,但問題在于它也會縮放球的大小,這并不是您真正想要做的。
以下是一個可能的解決方案的基本示例。
它計算由點表示的區域的最小/最大范圍,然后使用組件大小來平移點,以便它們適合可見空間

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 GraphPoint {
private String id;
private Point2D point;
public GraphPoint(String id, Point2D point) {
this.id = id;
this.point = point;
}
public String getId() {
return id;
}
public Point2D getPoint() {
return point;
}
}
public class TestPane extends JPanel {
private List<GraphPoint> points;
private int radius = 10;
private double virtualScale = 1.0;
private Point2D minRange;
private Point2D maxRange;
public TestPane() {
points = new ArrayList<>(16);
points.add(new GraphPoint("1", new Point2D.Double(35.19589389346247, 32.10152879327731)));
points.add(new GraphPoint("2", new Point2D.Double(35.20319591121872, 32.10318254621849)));
points.add(new GraphPoint("3", new Point2D.Double(35.20752617756255, 32.1025646605042)));
points.add(new GraphPoint("4", new Point2D.Double(35.21007339305892, 32.10107446554622)));
points.add(new GraphPoint("5", new Point2D.Double(35.21310882485876, 32.104636394957986)));
double minX = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
double minY = Double.MAX_VALUE;
double maxY = Double.MIN_VALUE;
for (GraphPoint gp : points) {
minX = Math.min(minX, gp.getPoint().getX());
maxX = Math.max(maxX, gp.getPoint().getX());
minY = Math.min(minY, gp.getPoint().getY());
maxY = Math.max(maxY, gp.getPoint().getY());
}
minRange = new Point2D.Double(minX, minY);
maxRange = new Point2D.Double(maxX, maxY);
double xRange = maxRange.getX() - minRange.getX();
double yRange = maxRange.getY() - minRange.getY();
System.out.println(minRange.getX() " - " minRange.getY());
System.out.println(maxRange.getX() " - " maxRange.getY());
System.out.println(xRange " - " yRange);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (GraphPoint gp : points) {
paintPoint(g2d, gp);
}
g2d.dispose();
}
private void paintPoint(Graphics2D g2d, GraphPoint gp) {
Graphics2D g2 = (Graphics2D) g2d.create();
Point2D translated = translate(gp);
double xPos = translated.getX();
double yPos = translated.getY();
double offset = radius;
g2.translate(xPos - offset, yPos - offset);
g2.setPaint(Color.blue);
g2.fill(new Ellipse2D.Double(0, 0, offset * 2, offset * 2));
g2.dispose();
}
protected Point2D translate(GraphPoint gp) {
double xRange = maxRange.getX() - minRange.getX();
double yRange = maxRange.getY() - minRange.getY();
double offset = radius;
double width = getWidth() - (offset * 2);
double height = getHeight() - (offset * 2);
double xScale = width / xRange;
double yScale = height / yRange;
Point2D original = gp.getPoint();
double x = offset ((original.getX() - minRange.getX()) * xScale);
double y = offset ((original.getY() - minRange.getY()) * yScale);
System.out.println(gp.getId() " " x " x " y);
return new Point2D.Double(x, y);
}
}
}
我必須強調,這是一種可能的解決方案,您的實際要求可能會有所不同,但這應該為您提供定義自己演算法的起點,例如,您可以定義自己的最小/最大范圍(即 34x30 到36x33)
我已經嘗試了 1 小時的字串,但我沒有得到它,我已經編輯了您的代碼,您對我們的幫助很大。點 id 上方的字串我的意思是點“0”,如果您能幫助我們或向我們展示這個字串,我們將不勝感激!

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 GraphPoint {
private String id;
private Point2D point;
public GraphPoint(String id, Point2D point) {
this.id = id;
this.point = point;
}
public String getId() {
return id;
}
public Point2D getPoint() {
return point;
}
}
public class TestPane extends JPanel {
private List<GraphPoint> points;
private int radius = 10;
private double virtualScale = 1.0;
private Point2D minRange;
private Point2D maxRange;
public TestPane() {
points = new ArrayList<>(16);
points.add(new GraphPoint("1", new Point2D.Double(35.19589389346247, 32.10152879327731)));
points.add(new GraphPoint("2", new Point2D.Double(35.20319591121872, 32.10318254621849)));
points.add(new GraphPoint("3", new Point2D.Double(35.20752617756255, 32.1025646605042)));
points.add(new GraphPoint("4", new Point2D.Double(35.21007339305892, 32.10107446554622)));
points.add(new GraphPoint("5", new Point2D.Double(35.21310882485876, 32.104636394957986)));
double minX = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
double minY = Double.MAX_VALUE;
double maxY = Double.MIN_VALUE;
for (GraphPoint gp : points) {
minX = Math.min(minX, gp.getPoint().getX());
maxX = Math.max(maxX, gp.getPoint().getX());
minY = Math.min(minY, gp.getPoint().getY());
maxY = Math.max(maxY, gp.getPoint().getY());
}
minRange = new Point2D.Double(minX, minY);
maxRange = new Point2D.Double(maxX, maxY);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
double insets = fm.getHeight() radius;
// I'm lazy, so I'm drawing the lines first, then painting
// the points over the top as I can't be bothered to workout
// a clever way to ensure the lines are always painted under
// the dots
GraphPoint lastPoint = null;
for (GraphPoint gp : points) {
if (lastPoint != null) {
paintLine(g2d, lastPoint, gp, insets);
}
lastPoint = gp;
}
for (GraphPoint gp : points) {
paintPoint(g2d, gp, insets);
}
g2d.dispose();
}
private void paintLine(Graphics2D g2d, GraphPoint from, GraphPoint to, double insets) {
Point2D fromPoint = translate(from, insets);
Point2D toPoint = translate(to, insets);
g2d.setColor(Color.RED);
g2d.draw(new Line2D.Double(fromPoint, toPoint));
}
private void paintPoint(Graphics2D g2d, GraphPoint gp, double insets) {
Graphics2D g2 = (Graphics2D) g2d.create();
Point2D translated = translate(gp, insets);
double xPos = translated.getX();
double yPos = translated.getY();
double offset = radius;
g2.translate(xPos - offset, yPos - offset);
g2.setPaint(Color.blue);
g2.fill(new Ellipse2D.Double(0, 0, offset * 2, offset * 2));
FontMetrics fm = g2d.getFontMetrics();
String text = gp.getId();
double x = xPos - (fm.stringWidth(text) / 2);
double y = (yPos - radius - fm.getHeight()) fm.getAscent();
g2d.drawString(text, (float)x, (float)y);
g2.dispose();
}
protected Point2D translate(GraphPoint gp, double insets) {
double xRange = maxRange.getX() - minRange.getX();
double yRange = maxRange.getY() - minRange.getY();
double offset = insets;
double width = getWidth() - (offset * 2);
double height = getHeight() - (offset * 2);
double xScale = width / xRange;
double yScale = height / yRange;
Point2D original = gp.getPoint();
double x = offset ((original.getX() - minRange.getX()) * xScale);
double y = offset ((original.getY() - minRange.getY()) * yScale);
System.out.println(gp.getId() " " x " x " y);
return new Point2D.Double(x, y);
}
}
}
文本的訣竅在于理解我已經翻譯了背景關系的原點,因此 0x0 位置實際上是圓的中間,因此您需要從中減去文本偏移量。
我還做了一個小更新,以允許作業流程傳入一個insets值,這將減少可用的可見區域以“幫助”補償文本
另一個問題可以在提示中劃一條帶箭頭的線
看...
- Java制作一條有向線并使其移動
- 如何使用 Java Swing 繪制二維箭頭?
對于一些想法。請注意,這變得越來越復雜,因為箭頭需要朝著它們所看的點旋轉,例如用一條線連接兩個圓圈可能會有所幫助
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/371767.html
