Rysowanie punktów z pliku - java.awt.*

0

Cześć,
Napisałem program który wczytuje dane z pliku, następnie wykonuje działania na poszczególnych "rekordach" i powinien rysować.
Mam jednak pewne zastrzeżenia:
1) Podczas kompilacji program momentami staje w miejscu tak jakby się zawieszał (nic nie zmienia się na konsoli - specjalnie wrzuciłem system.out.println aby sprawdzić jaki jest wynik oraz czy wszystko idzie dalej), po kilku minutach pętla powraca do działania ale nie wiem co ona tak na prawdę robi, czy się resetuje czy co? Rozumiem, przechodzi ona przez 168 tys linijek x 3 liczby w każdej ale czy tak powinno być? Mój komputer nie ma problemu z utrzymaniem eclipse'a.
2) Chciałbym aby zmienne "x" oraz "z" były zapisywane jako double ponieważ ucina to wyniki działania w mojej pętli for a to jest kluczowe, jeśli to zrobię to nie będę mógł skorzystać z metody drawOval. Czy jest jakaś metoda w awt która jednocześnie skorzysta z double'a i wykorzysta moje dwie zmienne?
3) Czy te działania są potrzebne? Czy może trzeba w ogóle zamieniać tego na radiany? Trzecia kolumna to mikrony, druga w mikronach a pierwsza w mikro radianach. Czy dobrze zamieniam je aby później wykorzystać we współrzędnych?
4) Czy ten kod jest poprawny i wystarczy zaczekać te kilkadziesiąt minut na całą pętlę i powinien narysować? Czy ify zagnieżdżone w forze działają poprawnie? Inaczej pętla wychodzi poza ArrayListe. Trochę mnie to dziwi bo ludzie nie korzystają tylko z plików zawierających po 50 linijek, tak mi się wydaje. Podczas kompilacji we Frame'ie coś się zmienia ale czy to celowy zabieg czy też jakiś bug Eclipse - tego nie wiem. Często można zauważyć dwa prostokąty które po pewnym czasie znikają i znowu wracają.

Oto mój kod:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Rysowanie extends JPanel {

    ArrayList<Double> liczby = new ArrayList<Double>();

    public Rysowanie() {
        try {
            File file = new File("pliki/wynik5.xyz");
            Scanner input = new Scanner(file);
            input.useLocale(Locale.ENGLISH);

            while (input.hasNextDouble()) {
                dodajLiczbe(input.nextDouble());
            }
            input.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Załadowalem tyle plikow: " + ileLiczb());
    }

    public void dodajLiczbe(double liczba) {
        liczby.add(liczba);
    }

    public Double wezLiczbe(int indeks) {
        return liczby.get(indeks);
    }

    public int ileLiczb() {
        return liczby.size();
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        int x;
        int z;
        int c = 0;
        int d = 1;
        int e = 2;
        for (int i = 0; i < liczby.size(); i++) {
            x = (int) (wezLiczbe(e) * Math.sin(wezLiczbe(c) * Math.pow(10, -6)));
            z = (int) (wezLiczbe(e) * Math.cos(wezLiczbe(c) * Math.pow(10, -6)));

            g.setColor(Color.blue);
            g.drawOval(x, z, d, d);

            System.out.println("Narysowalem kropke o indeksie: " + x + " oraz " + z);
            if (c < liczby.size() - 3) {
                c = c + 3;
            } else if (e < liczby.size() - 3) {
                e = e + 3;
            }
        }
    }

    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("NIE WIEM");
        JPanel world = new Rysowanie();
        frame.getContentPane().add(world);
        frame.setLocation(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();
    }
}

Plik jeśli by ktoś potrzebował to wrzucam na SS ponieważ załączniki tego nie obsługują, przynajmniej nie widzę na liście formatów.

2

U mnie wczytanie pliku zajmuje nieco ponad 4 sekundy, a wykonanie metody paintComponent zajmuje mniej niż pól sekundy.

  1. Dlaczego instrukcja
    g.setColor(Color.blue);

    jest wewnątrz pętli?

  2. Dlaczego do rysowania kropki używasz metody drawOval? Użyj
    g.drawLine(x,z,x,z);
  3. Nie wykorzystujesz liczb z drugiej kolumny.
    Moim zdaniem kod powinien wyglądać mniej więcej tak:

    //odczytanie
    ArrayList<Point> dane = new ArrayList<Point>();
    
    public Rysowanie() {
        try {
            double a;
            int b,c,x,y;
            File file = new File("pliki/wynik5.xyz");
            Scanner input = new Scanner(file);
            input.useLocale(Locale.ENGLISH);
            while (input.hasNextDouble()) 
            {
                a = input.nextDouble();
                b = input.nextInt();
                c = input.nextInt();
                //obliczenie x i y, nie podam wzorów, bo nie wiem co chcesz uzyskać 
                dane.add(new Point(x,y);
            }
            input.close();
    
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("Ilość odczytanych wierszy: " + dane.size());
    //rysowanie
    public void paintComponent(Graphics g) {
    
        super.paintComponent(g);
        g.setColor(Color.blue);
        int x;
        int y; 
        for (int i = 0; i < dane.size(); i++) 
        {
            x = dane.get(i).x;
            x = dane.get(i).y;
            g.drawLine(x, y, x, y);
    
        }
    }
0

Dziękuję za odpowiedź,

  1. Ahhh, okay, już ją wyrzucam przed for'a.
  2. Próbowałem, ale byłem przekonany że coś jest nie tak gdy tak długo mi się to kompilowało.
  3. Czy w takim razie, rysuje się Panu coś?
  4. Co z danymi w double'u?

Sam nie wiem dlaczego u mnie to tak długo trwa, czy robię to na laptopie czy też na stacjonarnym to i tu i tu tak samo nie może się skończyć. Może środowisko?

// UPDATE

Linijka o zmianie koloru wyrzucona, komenda na drawLine zmieniona i jedyne co widzę w okienku Frame'a to to że lewa krawędź jest pomalowana na niebiesko.

1

U mnie się też rysuje się tylko krawedź, ale moim zdaniem Twoje obliczenia współrzędnych są błędne. Jakie współrzędne chciałbyś uzyskać np. dla takich wierszy:

0.626 1267 522
0.626 1274 523

W podanym przeze mnie kodzie nie ma żadnych danych w double.

0

Dane z pliku to układ walcowy a więc chodzi o te wzory:

x = radius*sin(theta)
z = radius*cos(theta)

Kolejność kolumn: theta, y, radius.
Miałbym gdzieś tu użyć y'ka?

1

Jeśli to jest układ walcowy, to punkty leżą w przestrzeni, a rysunek jest dwuwymiarowy. Konieczna jest jeszcze informacja na jaką płaszczyznę chcesz rzutować. Prostopadłą do osi walca?
Jaki jest związek kolumn w pliku tekstowym ze współrzędnymi?
pierwsza kolumna - kąt (theta)
druga kolumna - ???
trzecia kolumna - ???

0

Nie chcę źle powiedzieć bo tak na prawdę nie wiem, chce wywołać te punkty na Frame'a aby sprawdzić czy coś z tego jest, następnie połączyć je ze sobą w jeden, spójny obiekt. Powinny one stworzyć jakiś kształt.

Kolumny od lewej, theta, y, radius,

Tutaj znajdują się dokładne informacje, radius moim zdaniem to "p" - https://pl.wikipedia.org/wiki[...]%C5%82rz%C4%99dnych_walcowych

1

Jeśli zrzutujesz punkty na płaszczyznę prostopadłą do osi walca, przeskalujesz żeby wszystko się zmieściło w prostokącie 200x200 i przesuniesz początek układ współrzędnych z lewgo górnego rogu do środka ramki to otrzymasz taka figurę:
kleks.png
Odczytanie pliku:

            while (input.hasNextDouble()) 
            {
                fi = input.nextDouble();
                b = input.nextInt();
                r = input.nextInt();
                max = Math.max(max,r);
                x = (int)(r*Math.sin(fi));
                y = (int)(r*Math.cos(fi));
                dane.add(new Point(x,y));
            }

Rysowanie:

    public void paintComponent(Graphics g) {

        super.paintComponent(g);        
        int x;
        int y;
        g.setColor(Color.blue);
        Graphics2D g2 = (Graphics2D)g;
        g2.translate(100,100);
        for (int i = 0; i < dane.size(); i++) 
        {
            x = (int)(dane.get(i).x*100.0/max);
            y = (int)(dane.get(i).y*100./max);            
            g2.drawLine(x, y, x, y);
        }
    }

Po rzutowaniu na jedną z płaszczyzn zawierających oś walca, odpowiednim przeskalowaniu i przesunięciu początku układu otrzymamy takie głowy:
head.png behind.png

0

Bardzo dziękuję za pomoc @bogdans oraz @Shalom. Wiem co muszę zrobić aby zbliżyć się ku końcowi zadania, działam dalej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0