2010-08-15 3 views
7

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

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

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

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

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

+0

Вы хотите нарисовать «линейку» линию в произвольных направлениях? Являются ли тики фиксированными интервалами или вы хотите, чтобы они появлялись, скажем, 0%, 33%, 66%, 100%? – aioobe

+0

Пожалуйста, смотрите ниже, чтобы описать графику в целом. Маркеры будут равномерно распределены с произвольным интервалом. (IE: Мне нужно решение, где я могу сегментировать линию и нарисовать произвольное количество этих тиков по своей длине в каждом сегменте) – Matt

+0

дайте мне знать, что вы думаете о моем ответе. – jjnguy

ответ

13

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

  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 будут проходить через одно и то же преобразование и красиво «наклонены» вдоль линии.

+0

Интересно, я считаю, что «AffineTransform» - это ключевое слово, которое я искал. Google подготовил этот учебник с очень похожими компонентами: http://www.glyphic.com/transform/applet/1intro.html Теперь я просто должен понять, как применить его к моей проблеме. – Matt

+0

Вы применяете его, сначала переведя (перемещая) в желаемую начальную точку, затем поворачивая на нужный угол (atan2 (dy, dx)). Объедините два преобразования с AffineTransform.concatenate. – aioobe

+1

Это выглядит великолепно. Мне нужно больше познакомиться с вещами Transform. – jjnguy

1

вещи, которые должны отметив:

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

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

  1. рисовать линия от <sx,sy> (начало х, у) <sx+dx*length,sy+dy*length>
  2. Draw набор линий (для (I = 0; я < = длина; я + = интервал) от <sx+dx*i-newdx*seglength/2,sy+dy*i-newdy*seglength/2> к <sx+dx*i+newdx*seglength/2,sy+dy*i+newdy*seglength/2>
+0

Мне очень нравится этот ответ, потому что он пытается объяснить геометрию. К сожалению, у меня возникают проблемы с обволакиванием головы. Я подключил формулы, которые вы описали, и я получаю очень странные результаты для newdy & newdx. (отрицательные значения, которые выходят далеко за пределы координат на моей панели) Опять же, моя геометрия в лучшем случае элементарна, но мне интересно, является ли формула для декартовой системы координат.Координаты Java размещают 0,0 в левом верхнем углу панели. – Matt

1

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

|x'| = |cos(an) -sin(an)| |x| 

|y`| = |sin(an) cos(an)| |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) как и следовало ожидать.

Надеется, что это помогает,
Рони

Смежные вопросы