Java - Gambar penggaris (garis dengan tanda centang pada sudut 90 derajat)

Saya menggunakan Java AWT untuk menggambar garis pada panel (Line2D dan Graphics2D.drawLine()) dan saya bertanya-tanya bagaimana cara menggambar garis dengan tanda centang, mirip dengan:

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

Saya mengetahui posisi yang ingin saya tandai terlebih dahulu.

Garisnya bisa berada di posisi mana pun, jadi tanda centang harus digambar pada sudut yang berhubungan dengan garis itu sendiri.

Geometri dasar & kemampuan saya untuk menerapkannya di Java mengecewakan saya. :)


person Matt    schedule 15.08.2010    source sumber
comment
Apakah Anda ingin menggambar garis penggaris ke segala arah? Apakah tanda centang berada pada interval yang tetap, atau Anda ingin tanda centang tersebut muncul, misalnya 0%,33%, 66%, 100% ?   -  person aioobe    schedule 15.08.2010
comment
Silakan lihat di bawah untuk deskripsi grafik secara umum. Tanda centang akan ditempatkan secara merata dengan jarak yang berubah-ubah. (IE: Saya memerlukan solusi di mana saya dapat mengelompokkan garis dan menggambar sejumlah tanda centang sepanjang garis tersebut di setiap segmen)   -  person Matt    schedule 15.08.2010
comment
beri tahu saya pendapat Anda tentang jawaban saya.   -  person jjnguy    schedule 15.08.2010


Jawaban (3)


saya menyarankan Anda

  1. menerapkan metode menggambar penggaris yang menggambar penggaris horizontal sederhana dari kiri ke kanan
  2. Cari tahu sudut yang diinginkan menggunakan Math.atan2.
  3. Terapkan AffineTransform dengan terjemahan dan rotasi sebelum menjalankan metode menggambar penggaris.

Berikut adalah program pengujian lengkap. (Metode Graphics.create digunakan untuk membuat salinan objek grafik asli, sehingga kita tidak mengacaukan transformasi aslinya.)

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);
    }
}

masukkan deskripsi gambar di sini

Perhatikan, Anda dapat dengan mudah menggambar angka di atas tanda centang. Panggilan drawString akan melalui transformasi yang sama dan "dimiringkan" dengan baik di sepanjang garis.

person aioobe    schedule 15.08.2010
comment
Menariknya, saya yakin 'AffineTransform' adalah kata kunci yang saya cari. Google membuat tutorial ini dengan komponen yang sangat mirip: glyphic.com/transform/applet/1intro.html Sekarang saya hanya perlu memahami bagaimana menerapkannya pada masalah saya. - person Matt; 15.08.2010
comment
Anda menerapkannya dengan terlebih dahulu menerjemahkan (memindahkan) ke titik awal yang diinginkan, kemudian dengan memutar sesuai sudut yang diinginkan (atan2(dy, dx)). Gabungkan kedua transformasi dengan AffineTransform.concatenate. - person aioobe; 15.08.2010
comment
Kelihatannya bagus. Saya perlu membuat diri saya lebih akrab dengan hal-hal Transformasi. - person jjnguy; 15.08.2010

Hal-hal yang perlu diperhatikan:

  • Sebuah garis tegak lurus mempunyai kemiringan -1/kemiringan lama.
  • Untuk mendukung garis ke segala arah, Anda perlu melakukannya secara parametrik
  • Jadi, Anda memiliki dy dan dx melintasi garis aslinya, yang berarti newdx=dy; newdy=-1*dx.
  • Jika Anda memilikinya sehingga <dx, dy> adalah vektor satuan (sqrt(dx*dx+dy+dy)==1, atau dx==cos(theta); dy=sin(theta) untuk beberapa theta), maka Anda hanya perlu mengetahui seberapa jauh tanda centang yang Anda inginkan.
  • sx, sy adalah awalmu x dan y
  • panjangnya adalah panjang garis
  • seglength adalah panjang garis putus-putus
  • dx, dy adalah kemiringan garis asal
  • newdx, newdy adalah kemiringan (dihitung di atas) dari garis melintang

Dengan demikian,

  1. Tarik garis dari <sx,sy> (mulai x,y) ke <sx+dx*length,sy+dy*length>
  2. Gambarlah sekumpulan garis (untuk(i=0;i‹=panjang;i+=interval) dari <sx+dx*i-newdx*seglength/2,sy+dy*i-newdy*seglength/2> hingga <sx+dx*i+newdx*seglength/2,sy+dy*i+newdy*seglength/2>
person zebediah49    schedule 15.08.2010
comment
Saya sangat menyukai jawaban ini karena mencoba menjelaskan geometri. Sayangnya, saya kesulitan memahaminya. Saya memasukkan rumus yang Anda jelaskan dan saya mendapatkan hasil yang sangat aneh untuk newdy & newdx. (nilai negatif yang berada jauh di luar jangkauan koordinat pada panel saya) Sekali lagi, geometri saya paling dasar, tapi saya bertanya-tanya apakah rumusnya untuk sistem koordinat kartesius. Koordinat Java menempatkan 0,0 di pojok kiri atas panel. - person Matt; 15.08.2010

Saya harap Anda mengetahui perkalian matriks. Untuk memutar garis, Anda perlu mengalikannya dengan matriks rotasi. (Saya tidak dapat menggambar matriks yang tepat tetapi menganggap kedua garis tidak dipisahkan)

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

|y`| = |sin(an)  cos(an)| |y|

Titik yang lama adalah x,y dan yang baru adalah x',y'. Mari kita ilustrasikan dengan sebuah contoh, katakanlah Anda memiliki garis vertikal dari (0,0) hingga (0,1), sekarang Anda ingin memutarnya sebesar 90 derajat. (0,0) akan tetap nol jadi mari kita lihat apa yang terjadi pada (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|

Anda mendapatkan garis horizontal (0,0),(0,1) seperti yang Anda harapkan.

Semoga membantu,
Roni

person roni bar yanai    schedule 15.08.2010