001/*
002 * Renderer Models. The MIT License.
003 * Copyright (c) 2022 rlkraft@pnw.edu
004 * See LICENSE for details.
005*/
006
007package renderer.models_L.turtlegraphics;
008
009import renderer.scene.Model;
010
011/**
012   https://inventwithpython.com/recursion/chapter9.html#calibre_link-350
013*/
014public class HilbertCurveTurtle extends Turtle
015{
016   /**
017      @param model   a reference to the {@link Model} that this {@code Turtle} is builing
018      @param n       number of levels for the Hibert curve
019      @param length  side length
020   */
021   public HilbertCurveTurtle(final Model model, final int n, final double length)
022   {
023      this(model, n, length, 0.0, 0.0, 0.0);
024   }
025
026
027   /**
028      @param model   a reference to the {@link Model} that this {@code Turtle} is builing
029      @param n       number of levels for the Hibert curve
030      @param length  side length
031      @param xPos    the intial x-coordinate for this {@link Turtle}
032      @param yPos    the intial y-coordinate for this {@link Turtle}
033   */
034   public HilbertCurveTurtle(final Model model, final int n, final double length,
035                            final double xPos, final double yPos)
036   {
037      this(model, n, length, xPos, yPos, 0.0);
038   }
039
040
041   /**
042      @param model   a reference to the {@link Model} that this {@code Turtle} is builing
043      @param n       number of levels for the Hibert curve
044      @param length  side length
045      @param xPos    the intial x-coordinate for this {@link Turtle}
046      @param yPos    the intial y-coordinate for this {@link Turtle}
047      @param z       the z-plane for this {@code Turtle}
048   */
049   public HilbertCurveTurtle(final Model model, final int n, final double length,
050                            final double xPos, final double yPos, final double z)
051   {
052      super(model, xPos, yPos, z);
053      curve(n, 90, length / Math.pow(2, n));
054   }
055
056
057   private void curve(final int n, final double angle, final double length)
058   {
059      curveQuadrant(n, angle, length);
060
061      forward(length);
062
063      curveQuadrant(n, angle, length);
064
065      turn(-angle);
066      forward(length);
067      turn(-angle);
068
069      curveQuadrant(n, angle, length);
070
071      forward(length);
072
073      curveQuadrant(n, angle, length);
074
075      turn(-angle);
076      forward(length);
077      turn(-angle);
078   }
079
080
081   private void curveQuadrant(final int n, final double angle, final double length)
082   {
083      if (n > 0)
084      {
085         turn(angle);
086
087         curveQuadrant(n - 1, -angle, length);
088
089         forward(length);
090         turn(-angle);
091
092         curveQuadrant(n - 1,  angle, length);
093
094         forward(length);
095
096         curveQuadrant(n - 1,  angle, length);
097
098         turn(-angle);
099         forward(length);
100
101         curveQuadrant(n - 1, -angle, length);
102
103         turn(angle);
104      }
105   }
106
107}//HilbertCurveTurtle