Java - Нарисуйте линейку (линия с метками под углом 90 градусов) )

Я использую Java AWT для рисования линий на панели ( Line2D и Graphics2D.drawLine () ), и мне интересно как я могу нарисовать линию с отметками, как:

| ---- | ---- | ---- | ---- | ---- |

Я знаю позиции, которые я Я хотел бы нарисовать галочки заранее.

Линии могут быть в любом положении, поэтому галочки должны быть нарисованы под углом, соответствующим самой линии.

Моя базовая геометрия и способность применять ее в Java меня не подводят. :)

7
задан aioobe 17 December 2010 в 23:42
поделиться

3 ответа

Я предлагаю вам

  1. реализовать метод рисования линейки, который рисует простую горизонтальную линейку слева направо
  2. Определите желаемый угол, используя Math.atan2 .
  3. Примените 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);
    }
}

enter image description here

Обратите внимание, что вы можете так же легко нарисовать числа выше клещи. Вызовы drawString прошли бы такое же преобразование и были бы красиво "наклонены" вдоль линии.

13
ответ дан 6 December 2019 в 14:00
поделиться

Надеюсь, вы знаете умножение матриц. Чтобы повернуть строку, вам нужно умножить ее на матрицу вращения. (Я не могу нарисовать правильную матрицу, но предполагаю, что обе линии не разделены)

|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) , как и следовало ожидать.

Надеюсь, это поможет,
Рони

1
ответ дан 6 December 2019 в 14:00
поделиться

На что следует обратить внимание:

  • Перпендикулярная линия имеет наклон -1 / oldslope.
  • Чтобы поддерживать линии в любом направлении, вам необходимо сделать это параметрически
  • Таким образом, у вас есть dy и dx поперек исходной линии, что означает, что newdx = dy; newdy = -1 * dx .
  • Если он у вас такой, что является единичным вектором ( sqrt (dx * dx + dy + dy) == 1 , или dx == cos (theta); dy = sin (theta) для некоторой theta), тогда вам просто нужно знать, на каком расстоянии вы хотите делать отметки.
  • sx, sy - ваше начало x и y
  • length - длина линии
  • seglength - длина тире
  • dx, dy - наклон исходной линии
  • newdx, newdy - (вычисленные выше) наклоны линий пересечения

Таким образом,

  1. Нарисуйте линию от (начало x, y) до
  2. Нарисуйте набор линий (для (i = 0; i <= length; i + = interval) из от до
1
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: