Advertisement
anonEMuss

ArcTan2Spiral_JavaFX

Jun 30th, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.47 KB | None | 0 0
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package arctan2spiral;
  7.  
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.HashMap;
  11. import javafx.application.Application;
  12. import javafx.embed.swing.SwingFXUtils;
  13. import javafx.event.ActionEvent;
  14. import javafx.event.EventHandler;
  15. import javafx.scene.Scene;
  16. import javafx.scene.SnapshotParameters;
  17. import javafx.scene.canvas.Canvas;
  18. import javafx.scene.canvas.GraphicsContext;
  19. import javafx.scene.control.Button;
  20. import javafx.scene.control.TextField;
  21. import javafx.scene.control.ToggleButton;
  22. import javafx.scene.image.WritableImage;
  23. import javafx.scene.layout.ColumnConstraints;
  24. import javafx.scene.layout.GridPane;
  25. import javafx.scene.layout.HBox;
  26. import javafx.scene.layout.Pane;
  27. import javafx.scene.layout.RowConstraints;
  28. import javafx.scene.text.Text;
  29. import javafx.stage.Stage;
  30. import javafx.util.Pair;
  31. import javax.imageio.ImageIO;
  32.  
  33. /**
  34. *
  35. * @author Nunya Business
  36. */
  37. public class AnglePlotter2D extends Application {
  38.  
  39. private double angle;
  40. private int width;
  41. private int height;
  42. private int canvWidth;
  43. private int canvHeight;
  44. private int revs;
  45. private double numer;
  46. private double denom;
  47. private boolean constDec;
  48. private boolean piNumer;
  49. private boolean piDenom;
  50. private Pair<Double, Double> p1;
  51. private Pair<Double, Double> p2;
  52.  
  53. private Pane wrapperPane;
  54. private Canvas canvas;
  55. private GraphicsContext gc;
  56.  
  57. private HBox inBox;
  58. private TextField pngWidthTF;
  59. private Text pngWidthTxt;
  60. private TextField pngHeightTF;
  61. private Text pngHeightTxt;
  62. private Text riseTxt;
  63. private Text rise;
  64. private Button riseButtonInc;
  65. private Button riseButtonDec;
  66. private Text runTxt;
  67. private Text run;
  68. private Button runButtonInc;
  69. private Button runButtonDec;
  70. private ToggleButton decayBtn;
  71. private ToggleButton piNumerBtn;
  72. private ToggleButton piDenomBtn;
  73. private Text decayTxt;
  74. private TextField revsTF;
  75. private Text revsTxt;
  76.  
  77. private HashMap<String, Boolean> inputValMap;
  78.  
  79. /**
  80. * @param args the command line arguments
  81. */
  82. public static void main(String[] args) {
  83. launch(args);
  84. }
  85.  
  86. @Override
  87. public void start(Stage primaryStage) {
  88. inputValMap = new HashMap<>();
  89. width = 1024;
  90. height = 512;
  91. numer = 1;
  92. piNumer = false;
  93. denom = 2;
  94. piDenom = false;
  95. constDec = false;
  96. canvHeight = (int)(height * .9);
  97.  
  98. createComponents();
  99. GridPane root = new GridPane();
  100. ColumnConstraints c1 = new ColumnConstraints();
  101. c1.setPercentWidth(12.5);
  102. ColumnConstraints c2 = new ColumnConstraints();
  103. c2.setPercentWidth(12.5);
  104. ColumnConstraints c3 = new ColumnConstraints();
  105. c3.setPercentWidth(12.5);
  106. ColumnConstraints c4 = new ColumnConstraints();
  107. c4.setPercentWidth(12.5);
  108. ColumnConstraints c5 = new ColumnConstraints();
  109. c5.setPercentWidth(12.5);
  110. ColumnConstraints c6 = new ColumnConstraints();
  111. c6.setPercentWidth(12.5);
  112. ColumnConstraints c7 = new ColumnConstraints();
  113. c7.setPercentWidth(12.5);
  114. ColumnConstraints c8 = new ColumnConstraints();
  115. c8.setPercentWidth(12.5);
  116. root.getColumnConstraints().addAll(c1,c2,c3,c4,c5,c6,c7,c8);
  117.  
  118. RowConstraints r1 = new RowConstraints();
  119. r1.setPercentHeight(5);
  120. RowConstraints r2 = new RowConstraints();
  121. r2.setPercentHeight(90);
  122. RowConstraints r3 = new RowConstraints();
  123. r3.setPercentHeight(5);
  124. root.getRowConstraints().addAll(r1,r2,r3);
  125.  
  126. decayBtn = new ToggleButton("rev");
  127. decayBtn.setOnAction(new EventHandler<ActionEvent>(){
  128. @Override
  129. public void handle(ActionEvent e){
  130. constDec = !constDec;
  131. if(decayBtn.getText().equals("rev")){
  132. decayBtn.setText("const");
  133. }
  134. else{
  135. decayBtn.setText("rev");
  136. }
  137. }
  138. });
  139. piNumerBtn = new ToggleButton();
  140. piNumerBtn.setOnAction(new EventHandler<ActionEvent>(){
  141. @Override
  142. public void handle(ActionEvent e){
  143. piNumer = !piNumer;
  144. if(piNumerBtn.getText().equals("* \u03C0")){
  145. piNumerBtn.setText(" ");
  146. }
  147. else{
  148. piNumerBtn.setText("* \u03C0");
  149. }
  150. }
  151. });
  152. riseButtonInc = new Button("+");
  153. riseButtonInc.setOnAction(new EventHandler<ActionEvent>(){
  154. @Override
  155. public void handle(ActionEvent e){
  156. numer++;
  157. rise.setText(String.valueOf(numer));
  158. if(goodInput()){
  159. go();
  160. primaryStage.show();
  161. }
  162. else{
  163. System.out.println("fix input");
  164. }
  165. }
  166. });
  167. riseButtonDec = new Button("-");
  168. riseButtonDec.setOnAction(new EventHandler<ActionEvent>(){
  169. @Override
  170. public void handle(ActionEvent e){
  171. if(numer > 1.1){
  172. numer--;
  173. rise.setText(String.valueOf(numer));
  174. if(goodInput()){
  175. go();
  176. primaryStage.show();
  177. }
  178. else{
  179. System.out.println("fix input");
  180. }
  181. }
  182. else{
  183. System.out.println("0 increment error");
  184. }
  185. }
  186. });
  187. piDenomBtn = new ToggleButton();
  188. piDenomBtn.setOnAction(new EventHandler<ActionEvent>(){
  189. @Override
  190. public void handle(ActionEvent e){
  191. piDenom = !piDenom;
  192. if(piDenomBtn.getText().equals("* \u03C0")){
  193. piDenomBtn.setText(" ");
  194. }
  195. else{
  196. piDenomBtn.setText("* \u03C0");
  197. }
  198. }
  199. });
  200. runButtonInc = new Button("+");
  201. runButtonInc.setOnAction(new EventHandler<ActionEvent>(){
  202. @Override
  203. public void handle(ActionEvent e){
  204. denom = denom + 1.0;
  205. run.setText(String.valueOf(denom));
  206. if(goodInput()){
  207. go();
  208. primaryStage.show();
  209. }
  210. else{
  211. System.out.println("fix input");
  212. }
  213. }
  214. });
  215. runButtonDec = new Button("-");
  216. runButtonDec.setOnAction(new EventHandler<ActionEvent>(){
  217. @Override
  218. public void handle(ActionEvent e){
  219. if(denom > 1.1){
  220. denom = denom - 1.0;
  221. run.setText(String.valueOf(denom));
  222. if(goodInput()){
  223. go();
  224. primaryStage.show();
  225. }
  226. else{
  227. System.out.println("fix input");
  228. }
  229. }
  230. else{
  231. System.out.println("div by 0");
  232. }
  233. }
  234. });
  235. Button btnClear = new Button("clear");
  236. btnClear.setOnAction(new EventHandler<ActionEvent>(){
  237. @Override
  238. public void handle(ActionEvent e){
  239. gc.clearRect(0,0,canvas.getWidth(),canvas.getHeight());
  240. }
  241. });
  242. Button btnCap = new Button("cap");
  243. btnCap.setOnAction(new EventHandler<ActionEvent>(){
  244. @Override
  245. public void handle(ActionEvent e){
  246. take(canvas);
  247. }
  248. });
  249.  
  250. root.add(inBox,0,0,4,1);
  251. root.add(decayTxt,4,0);
  252. root.add(decayBtn,5,0);
  253. root.add(btnClear,6,0);
  254. root.add(btnCap,7,0);
  255. wrapperPane = new Pane();
  256. root.add(wrapperPane,0,1,8,1);
  257.  
  258. HBox riseHBox = new HBox();
  259. riseHBox.getChildren().addAll(riseTxt,rise,riseButtonInc,riseButtonDec,piNumerBtn);
  260. root.add(riseHBox,0,2,4,1);
  261.  
  262. HBox runHBox = new HBox();
  263. runHBox.getChildren().addAll(runTxt,run,runButtonInc,runButtonDec,piDenomBtn);
  264. root.add(runHBox,4,2,4,1);
  265.  
  266. canvas = new Canvas();
  267. wrapperPane.getChildren().add(canvas);
  268. canvas.widthProperty().bind(wrapperPane.widthProperty());
  269. canvas.heightProperty().bind(wrapperPane.heightProperty());
  270. canvas.widthProperty().addListener(event -> go());
  271. canvas.heightProperty().addListener(event -> go());
  272. gc = canvas.getGraphicsContext2D();
  273.  
  274. Scene scene = new Scene(root, width, width);
  275.  
  276. primaryStage.setTitle("AnglePlotter2D");
  277. primaryStage.setScene(scene);
  278. primaryStage.show();
  279. }
  280.  
  281. private void createComponents(){
  282. pngWidthTF = new TextField(String.valueOf(width));
  283. pngWidthTxt = new Text("width");
  284. pngHeightTF = new TextField(String.valueOf(height));
  285. pngHeightTxt = new Text("height");
  286. riseTxt = new Text("rise: ");
  287. rise = new Text(String.valueOf(numer));
  288. runTxt = new Text("run: ");
  289. run = new Text(String.valueOf(denom));
  290. revsTF = new TextField("3");
  291. revsTxt= new Text("revolutions");
  292. decayTxt = new Text("decay on: ");
  293. inBox = new HBox();
  294. inBox.getChildren().addAll(pngWidthTxt,pngWidthTF,pngHeightTxt,pngHeightTF,
  295. revsTxt, revsTF);
  296. }
  297. private void go(){
  298. gc.clearRect(0,0,wrapperPane.getWidth(),wrapperPane.getHeight());
  299. double x1, x2, y1, y2, distance, distanceMod, effNumer, effDenom;
  300.  
  301. if(piNumer){
  302. effNumer = numer * Math.PI;
  303. }
  304. else{
  305. effNumer = numer;
  306. }
  307. if(piDenom){
  308. effDenom = denom * Math.PI;
  309. }
  310. else{
  311. effDenom = denom;
  312. }
  313.  
  314. angle = Math.atan(effNumer/effDenom);
  315. double currAngle = 0;
  316. int maxIt = Math.abs((int)Math.ceil((revs * 2 * Math.PI)/angle));
  317. double alphaMod;
  318. double alpha = 1.0;
  319.  
  320. x1 = wrapperPane.getWidth() / 2.0;
  321. x2 = wrapperPane.getWidth();
  322. y1 = wrapperPane.getWidth() / 2.0;
  323. y2 = y1;
  324. p1 = new Pair(x1,y1);
  325. p2 = new Pair(x2,y2);
  326. distance = x1;
  327. if(constDec){
  328. distanceMod = distance / maxIt;
  329. alphaMod = 1.0 / maxIt;
  330. for(int i = 0; i < maxIt; i++){
  331. gc.setGlobalAlpha(alpha);
  332. gc.strokeLine((int) Math.round(p1.getKey()),(int) Math.round(p1.getValue()),
  333. (int) Math.round(p2.getKey()),(int) Math.round(p2.getValue()));
  334. distance -= distanceMod;
  335. currAngle += angle;
  336. p2 = nxtPair(p1,currAngle,distance);
  337. alpha -= alphaMod;
  338. }
  339. }
  340. else{
  341. distanceMod = distance / revs;
  342. alphaMod = 1.0 / revs;
  343. int revCount = 0;
  344. for(int i = 0; i < maxIt; i++){
  345. gc.setGlobalAlpha(alpha);
  346. gc.strokeLine((int) Math.round(p1.getKey()),(int) Math.round(p1.getValue()),
  347. (int) Math.round(p2.getKey()),(int) Math.round(p2.getValue()));
  348. if(i * Math.abs(angle) > ((revCount + 1) * 2 * Math.PI)){
  349. distance -= distanceMod;
  350. alpha -= alphaMod;
  351. revCount++;
  352. }
  353. currAngle += angle;
  354. p2 = nxtPair(p1,currAngle,distance);
  355. }
  356. }
  357. }
  358. private Pair<Double, Double> nxtPair(Pair<Double, Double> p1, double angle, double distance){
  359. System.out.println("next pair angle: " + angle);
  360. double x2 = distance * Math.cos(angle) + p1.getKey();
  361. double y2 = distance * Math.sin(angle) + p1.getValue();
  362. return new Pair(x2,y2);
  363. }
  364. private Boolean goodInput(){
  365. try{
  366. width = Integer.parseInt(pngWidthTF.getText());
  367. inputValMap.put("width", true);
  368. }
  369. catch(NumberFormatException nfe){
  370. System.out.println("Error: " + nfe);
  371. pngWidthTF.setText("Error");
  372. inputValMap.put("width", false);
  373. }
  374. try{
  375. height = Integer.parseInt(pngHeightTF.getText());
  376. inputValMap.put("height", true);
  377. }
  378. catch(NumberFormatException nfe){
  379. System.out.println("Error: " + nfe);
  380. pngHeightTF.setText("Error");
  381. inputValMap.put("height", false);
  382. }
  383. try{
  384. revs = Integer.parseInt(revsTF.getText());
  385. inputValMap.put("revs", true);
  386. }
  387. catch(NumberFormatException nfe){
  388. System.out.println("Error: " + nfe);
  389. revsTF.setText("Error");
  390. inputValMap.put("revs", false);
  391. }
  392. for(String key : inputValMap.keySet()){
  393. if(inputValMap.get(key) == false){
  394. return false;
  395. }
  396. }
  397. return true;
  398. }
  399. public void take(final Canvas canvas) {
  400. final WritableImage writableImage = new WritableImage((int) canvas.getWidth(), (int) canvas.getHeight());
  401. final WritableImage snapshot = canvas.snapshot(new SnapshotParameters(), writableImage);
  402. String angleStr = String.valueOf(angle);
  403. angleStr = angleStr.replace(".","_");
  404. String fileName = "angles" + width + "x" + height + "_" + angleStr +
  405. ".png";
  406. try {
  407. ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "PNG", new File(fileName));
  408. System.out.println("png written");
  409. } catch (final IOException e) {
  410. System.out.println("Snapshot could not be taken." + e);
  411. }
  412. }
  413.  
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement