2013-10-04 12 views
5

Więc skończyłem program, który rekurencyjnie rysuje linie, które pobierają argument "n", aby zdefiniować głębokość rekursji. Mam dwie funkcje, jedną, która rysuje względnie lewą linię, a drugą, która rysuje relatywnie prawą. Testowałem to i wydaje mi się, że działa na pierwszych 4 poziomach, ale wtedy albo linie stają się zbyt małe, by dokładnie je reprezentować, albo coś jest nie tak z moim kodem, ponieważ przerwy pomiędzy liniami wydają się być arbitralne. Miałam nadzieję, że ktoś będzie mógł przetestować mój kod i sprawdzić, czy może znaleźć problem.Sprawdź program debugowania

Poniższy obraz jest od głębokości 10.

EDIT: naprawiono część kodu, nadal potrzebują pomocy chociaż

public class Art 
{ 

//draws the relatively left line 
public static void drawLeftLine(double x0, double y0, double x1, double y1) 
{ 
    //define new x coordinate for line 
    //double x2 = (1/3.0)*(x1 - x0); 

    //color of line 
    StdDraw.setPenColor(StdDraw.BLUE); 


    //draw line by adding new x coord to original 
    StdDraw.line(x0, y0, x1, y1); 

} 
//draw relatively right line 
public static void drawRightLine(double x0, double y0, double x1, double y1) 
{ 
    //define new x coord for line 
    //double x2 = (2/3.0)*(x1 - x0); 

    //color of line 
    StdDraw.setPenColor(StdDraw.BLUE); 


    //draw line by adding new x coord to original 
    StdDraw.line(x0, y0, x1, y1); 

} 

public static void cantor(int n, double x0, double y0, double x1, double y1) 
{ 
    if (n == 0) 
     return; 

    drawLeftLine(x0, y0, x1, y1); 
    drawRightLine(x0, y0, x1, y1); 

    y0 = y0 - 0.1; 
    y1 = y1 - 0.1; 



    cantor(n-1, x0, y0, x0 + ((x1 - x0))/3.0, y1); //left 
    cantor(n-1, (2.0/ 3) * (x1 - x0) + x0, y0, x1, y1); //right 

} 

public static void main(String[] args) 
{ 
    //change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    //specify inital values for line 
    double x0 = 0; 
    double y0 = 0.9; 
    double x1 = 0.9; 
    double y1 = 0.9; 



    //recursive function cantor 
    cantor(n, x0, y0, x1, y1); 

} 
} 

Odpowiedz

4

Myślę, że rysunek wygląda błędna, ponieważ z fakt, że wszystkie ładne podwójne wartości są przybliżone z dyskretnymi pikselami powodującymi niepożądane nakładanie się między segmentami liniowymi (patrz EDYCJA na dole). Niektóre komentarze na temat twojego kodu:

1) Nie potrzebujesz metod drawLeftLine i drawRightLine, ponieważ obecnie rysują dokładnie to samo. Ponieważ na każdym etapie dwa razy wywołujesz cantor (raz dla każdej strony usuniętej wewnętrznej trzeciej), masz jedno połączenie do cantor dla każdego segmentu linii, który ma zostać narysowany. Jako takie chciałbym umieścić cały rysunek bezpośrednio w metodzie cantor.

2) Ponieważ y0 i y1 są zawsze takie same, ograniczyłbym je do pojedynczej zmiennej y.

3) Chciałbym uprościć matematyczne do obliczania nowych wartości x0 i x1 dół do

double third = (x1 - x0)/3; 
cantor(n - 1, x0, x0 + third, y); // left 
cantor(n - 1, x1 - third, x1, y); // right 

4) Zamiast zmniejszanie wartości y przez 0.1 za każdym razem, trzeba mieć globalną zmienną, która decyduje kwota, o którą należy ją zmniejszyć (w przeciwnym razie, jeśli spróbujesz, rzeczy się zepsują). Ta wartość może być ustawiona na 1.0/n.

5) Nie trzeba ustawiać koloru pióra za każdym razem, gdy malujesz. Możesz ustawić go tylko raz w głównej metodzie.

6) StdDraw już ustawia obramowanie wokół rysunku, który rysujesz, więc nie ma potrzeby, aby rozpocząć współrzędne od 0.9 - możesz użyć zamiast tego 1.

następstwie tych sugestii kod wyglądałby następująco:

private static double yIncrement; 

public static void cantor(int n, double x0, double x1, double y) { 
    if (n == 0) 
    return; 

    StdDraw.line(x0, y, x1, y); 

    y = y - yIncrement; 

    double third = (x1 - x0)/3; 
    cantor(n - 1, x0, x0 + third, y); // left 
    cantor(n - 1, x1 - third, x1, y); // right 

} 

public static void main(String[] args) { 
    //change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    // specify inital values for line 
    double x0 = 0; 
    double x1 = 1; 
    double y = 1; 

    yIncrement = 1.0/n; 
    StdDraw.setPenColor(Color.BLUE); 

    // recursive function cantor 
    cantor(n, x0, x1, y); 
} 

EDIT: odtwarzanie z rozmiaru StdDraw płótnie, ustawienia skalowania płótno i końcowego odcinka linii zaokrąglenia trybie można uzyskać nieco lepszy obraz (the poniższy kod tworzy obraz, który wygląda w większości poprawny aż do 8 poziomu)

private static double yIncrement; 

public static void cantor(int n, double x0, double x1, double y) { 
    if (n == 0) 
    return; 

    x0 = Math.ceil(x0); 
    x1 = Math.floor(x1); 

    StdDraw.line(x0, y, x1, y); 

    y = y - yIncrement; 

    double third = (x1 - x0)/3; 
    cantor(n - 1, x0, x0 + third, y); // left 
    cantor(n - 1, x1 - third, x1, y); // right 

} 

public static void main(String[] args) { 
    // change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    int width = 1920; 
    int height = 1080; 

    StdDraw.setCanvasSize(width, height); 

    // specify inital values for line 
    double x0 = 0; 
    double x1 = width; 
    double y = 1; 

    yIncrement = 1.0/n; 
    StdDraw.setPenColor(Color.BLUE); 
    StdDraw.setXscale(0, width); 

    // recursive function cantor 
    cantor(n, x0, x1, y); 
} 

aby wyświetlić wszystko w dół do poziomu dziesiątego z absolutną poprawność musisz szerokości 3^9 pikseli (19K pikseli). Dla poziomu 9 to 3^8 = 6K. Dla poziomu 8 to 3^7 = 2k, dlatego wygląda prawie poprawnie z szerokością 1,9K pikseli i zaokrągleniem całkowitym.

+0

Właściwie nie wolno mi zepsuć rozmiaru płótna dla tego projektu, ale spróbuję to zaimplementować za kilka minut. Wygląda świetnie, i wspaniale jest usłyszeć, że to prawdopodobnie błąd graficzny. Jesteś mężczyzną! Dziękuję Ci! – user2782981

Powiązane problemy