Optical illusion parallel lines

2

I have the following exercise that asks me to draw an optical illusion like the following:

But I can not find a simple way to make the code so that it makes this progression in which it goes one square forward then some back. Now I have this missing the "detours":

import javafx.application.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
import javafx.scene.shape.*;
import javafx.embed.swing.*;
import javafx.application.*;
import javafx.scene.text.*;
import java.util.*;
import javafx.scene.paint.Color;


public class Ilusão2  {  
    private Pane pane;
    private void start(Stage primaryStage) 
  {
    primaryStage.setOnCloseRequest(
        e -> Platform.runLater( () -> {Platform.exit(); System.exit(0);} ) 
  ); 

    // https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Pane.html
    this.pane = new Pane();
    this.pane.setPrefSize(750, 600);
    primaryStage.setScene(new Scene(this.pane, Color.BLACK));
    primaryStage.show();

    this.squares(10);
    this.lines(1);
} // END start

/**
 * Add shape to pane 
 */
public void addShape(Shape shape)
{
     Platform.runLater(() -> this.pane.getChildren().add(shape));
}

/** execute this method to start the program
 * executing the code in method start(Stage primaryStage) 
 */
public static void start()
{
    Ilusão2 drawingApp = new Ilusão2();
    drawingApp.launch();
}

public void launch()
{
    // Initialises JavaFX:
    new JFXPanel();
    // Makes sure JavaFX doesn't exit when first window is closed:
    Platform.setImplicitExit(false);
    // Runs initialisation on the JavaFX thread:
    Platform.runLater(() -> start(new Stage()));
}

public Ilusão2() 
{
    super();
}

private void squares(int squares)
{
    int width = 50;
    int heigth = width;
    for(int j = 100;j<=450;j+=50)
    {
    for(int i =50;i<=700;i+=100)
    {
     Rectangle square = new Rectangle(i,j,width,heigth);
     square.setStrokeWidth(3);
     square.setStroke(Color.GREY);
     square.setFill(Color.WHITE);
     pane.getChildren().add(square);
    }

    // for (int i = 50;i<=1000;i+=100)
    // {
     // for(int k = 0;k<=600;k+=50)
     // {
         // Rectangle squaresLow = new Rectangle(i,k,width,heigth);
         // squaresLow.setStrokeWidth(1);
         // squaresLow.setStroke(Color.GREY);
         // squaresLow.setFill(Color.WHITE);
         // pane.getChildren().add(squaresLow);
        // }
    // }
}
}

private void lines(int lines)
{
 int xInit= 0;
 int xFin=750;
 for(int y = 100;y<=500;y+=50)
 {
 Line line = new Line (xInit,y,xFin,y);
 line.setStrokeWidth(3);
 line.setStroke(Color.GREY);
 pane.getChildren().add(line);
}

}
} // END class World

This code does:

    
asked by anonymous 27.12.2017 / 20:20

1 answer

4

I've added a bit of code that basically checks which line of rectangles is being created in the current iteration of the loop and sets the appropriate increment in the X position (each line has its own increment in the X position , which can be 0, 20, or 40). It is this increment that is creating the "deviations" that you spoke of.

See the result:

  

importjavafx.application.Platform;importjavafx.embed.swing.JFXPanel;importjavafx.scene.Scene;importjavafx.scene.layout.Pane;importjavafx.scene.paint.Color;importjavafx.scene.shape.Line;importjavafx.scene.shape.Rectangle;importjavafx.scene.shape.Shape;importjavafx.stage.Stage;publicclassIlusao2{privatePanepane;privatevoidstart(StageprimaryStage){primaryStage.setOnCloseRequest(e->Platform.runLater(()->{Platform.exit();System.exit(0);}));//https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Pane.htmlthis.pane=newPane();this.pane.setPrefSize(710,600);primaryStage.setScene(newScene(this.pane,Color.BLACK));primaryStage.show();this.squares(10);this.lines(1);}//ENDstart/***Addshapetopane*/publicvoidaddShape(Shapeshape){Platform.runLater(()->this.pane.getChildren().add(shape));}/***executethismethodtostarttheprogramexecutingthecodeinmethod*start(StageprimaryStage)*/publicstaticvoidstart(){Ilusao2drawingApp=newIlusao2();drawingApp.launch();}publicvoidlaunch(){//InitialisesJavaFX:newJFXPanel();//MakessureJavaFXdoesn'texitwhenfirstwindowisclosed:Platform.setImplicitExit(false);//RunsinitialisationontheJavaFXthread:Platform.runLater(()->start(newStage()));}publicIlusao2(){super();}privatevoidsquares(intsquares){intwidth=50;intheigth=width;intlinhaAtual=0;for(intj=100;j<=450;j+=50){for(inti=10;i<=700;i+=100){intxIncremento=definirIncrementoEmX(linhaAtual);Rectanglesquare=newRectangle(i+xIncremento,j,width,heigth);square.setStrokeWidth(3);square.setStroke(Color.GREY);square.setFill(Color.WHITE);pane.getChildren().add(square);}linhaAtual++;}}privateintdefinirIncrementoEmX(intlinhaAtual){intxIncremento;if(linhaAtual==0){xIncremento=0;}elseif(linhaAtual==1){xIncremento=20;}elseif(linhaAtual==2){xIncremento=40;}elseif(linhaAtual==3){xIncremento=20;}elseif(linhaAtual==4){xIncremento=0;}elseif(linhaAtual==5){xIncremento=20;}elseif(linhaAtual==6){xIncremento=40;}elseif(linhaAtual==7){xIncremento=20;}elseif(linhaAtual==8){xIncremento=0;}else{thrownewRuntimeException("Há mais Linhas que o esperado!");
        }
        return xIncremento;
    }

    private void lines(int lines) {
        int xInit = 0;
        int xFin = 750;
        for (int y = 100; y <= 500; y += 50) {
            Line line = new Line(xInit, y, xFin, y);
            line.setStrokeWidth(3);
            line.setStroke(Color.GREY);
            pane.getChildren().add(line);
        }

    }

    public static void main(String[] args) {
        start();
    }
} // END class World

The implementation of the " definirIncrementoEmX(...) " method is simple to understand but is limited; you can replace these ifs / elses (which not are a flexible implementation because they only work with a limited number of possible rows) for a better implementation that is able to return the appropriate increment for any number of rows (currently only works up to linhaAtual is 8, which is enough for the given example).

    
30.12.2017 / 02:13