Я использую Java AWT для рисования линий на панели ( Line2D
и Graphics2D.drawLine ()
), и мне интересно как я могу нарисовать линию с отметками, как:
| ---- | ---- | ---- | ---- | ---- |
Я знаю позиции, которые я Я хотел бы нарисовать галочки заранее.
Линии могут быть в любом положении, поэтому галочки должны быть нарисованы под углом, соответствующим самой линии.
Моя базовая геометрия и способность применять ее в Java меня не подводят. :)
Я предлагаю вам
Math.atan2
. AffineTransform
с перемещением и вращением перед вызовом метода рисования линейки. Вот полная тестовая программа. (Метод Graphics.create
используется для создания копии исходного графического объекта, чтобы мы не испортили исходное преобразование.)
import java.awt.*;
public class RulerExample {
public static void main(String args[]) {
JFrame f = new JFrame();
f.add(new JComponent() {
private final double TICK_DIST = 20;
void drawRuler(Graphics g1, int x1, int y1, int x2, int y2) {
Graphics2D g = (Graphics2D) g1.create();
double dx = x2 - x1, dy = y2 - y1;
double len = Math.sqrt(dx*dx + dy*dy);
AffineTransform at = AffineTransform.getTranslateInstance(x1, y1);
at.concatenate(AffineTransform.getRotateInstance(Math.atan2(dy, dx)));
g.transform(at);
// Draw horizontal ruler starting in (0, 0)
g.drawLine(0, 0, (int) len, 0);
for (double i = 0; i < len; i += TICK_DIST)
g.drawLine((int) i, -3, (int) i, 3);
}
public void paintComponent(Graphics g) {
drawRuler(g, 10, 30, 300, 150);
drawRuler(g, 300, 150, 100, 100);
drawRuler(g, 100, 100, 120, 350);
drawRuler(g, 50, 350, 350, 50);
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 400);
f.setVisible(true);
}
}
Обратите внимание, что вы можете так же легко нарисовать числа выше клещи. Вызовы drawString прошли бы такое же преобразование и были бы красиво "наклонены" вдоль линии.
Надеюсь, вы знаете умножение матриц. Чтобы повернуть строку, вам нужно умножить ее на матрицу вращения. (Я не могу нарисовать правильную матрицу, но предполагаю, что обе линии не разделены)
|x'| = |cos(an) -sin(an)| |x|
|y`| = |sin(an) cos(an)| |y|
Старые точки - это x, y, а новая - это x ', y'. Давайте проиллюстрируем это примером, допустим, у вас есть вертикальная линия от (0,0) до (0,1), теперь вы хотите повернуть ее на 90 градусов. (0,0) останется нулевым, поэтому давайте просто посмотрим, что произойдет с (0,1)
|x'| = |cos(90) -sin(90)| |0|
|y`| = |sin(90) cos(90)| |1|
==
|1 0| |0|
|0 1| |1|
==
| 1*0 + 0*1|
| 0*0 + 1*1|
== |0|
|1|
, вы попадете на горизонтальную линию (0,0), (0, 1)
, как и следовало ожидать.
Надеюсь, это поможет,
Рони
На что следует обратить внимание:
newdx = dy; newdy = -1 * dx
.
является единичным вектором ( sqrt (dx * dx + dy + dy) == 1
, или dx == cos (theta); dy = sin (theta)
для некоторой theta), тогда вам просто нужно знать, на каком расстоянии вы хотите делать отметки. Таким образом,
(начало x, y) до
от
до