All Downloads are FREE. Search and download functionalities are using the official Maven repository.

doodle.image.examples.FunctionalGeometry.scala Maven / Gradle / Ivy

There is a newer version: 0.27.0
Show newest version
/*
 * Copyright 2015 Creative Scala
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package doodle
package image
package examples

import doodle.core.*
import doodle.syntax.all.*

// To use this example, open the SBT console and type:
//
// FunctionalGeometry.image.draw
//
// adapted From http://pmh-systems.co.uk/phAcademic/papers/funcgeo.pdf
object FunctionalGeometry {

  def grid(lines: List[((Int, Int), (Int, Int))]) = {
    import PathElement.*
    val paths = lines.map { case (((a, b), (c, d))) =>
      Image.path(
        OpenPath(
          List(moveTo(a.toDouble, b.toDouble), lineTo(c.toDouble, d.toDouble))
        )
      )
    }
    paths.foldLeft(Image.empty)(_ on _)
  }

  def quartet(a: Image, b: Image, c: Image, d: Image): Image =
    (a beside b) above (c beside d)

  def cycle(i: Image): Image =
    quartet(i, i rotate 270.degrees, i rotate 90.degrees, i rotate 180.degrees)

  def blank(m: Int = 4, n: Int = 4): Image =
    Image.rectangle(16, 16).scale(m.toDouble, n.toDouble).noStroke

  def nonet(
      i1: Image,
      i2: Image,
      i3: Image,
      i4: Image,
      i5: Image,
      i6: Image,
      i7: Image,
      i8: Image,
      i9: Image
  ) = {
    (i1 beside (i2 beside i3)) above ((i4 beside (i5 beside i6)) above (i7 beside (i8 beside i9)))
  }

  val p: Image =
    grid(
      List(
        ((4, 4), (6, 0)),
        ((0, 3), (3, 4)),
        ((3, 4), (0, 8)),
        ((0, 8), (0, 3)),
        ((4, 5), (7, 6)),
        ((7, 6), (4, 10)),
        ((4, 10), (4, 5)),
        ((11, 0), (10, 4)),
        ((10, 4), (8, 8)),
        ((8, 8), (4, 13)),
        ((4, 13), (0, 16)),
        ((11, 0), (14, 2)),
        ((14, 2), (16, 2)),
        ((10, 4), (13, 5)),
        ((13, 5), (16, 4)),
        ((9, 6), (12, 7)),
        ((12, 7), (16, 6)),
        ((8, 8), (12, 9)),
        ((12, 9), (16, 8)),
        ((8, 12), (16, 10)),
        ((0, 16), (6, 15)),
        ((6, 15), (8, 16)),
        ((8, 16), (12, 12)),
        ((12, 12), (16, 12)),
        ((10, 16), (12, 14)),
        ((12, 14), (16, 13)),
        ((12, 16), (13, 15)),
        ((13, 15), (16, 14)),
        ((14, 16), (16, 15))
      )
    )

  val q: Image =
    grid(
      List(
        ((2, 0), (4, 5)),
        ((4, 5), (4, 7)),
        ((4, 0), (6, 5)),
        ((6, 5), (6, 7)),
        ((6, 0), (8, 5)),
        ((8, 5), (8, 8)),
        ((8, 0), (10, 6)),
        ((10, 6), (10, 9)),
        ((10, 0), (14, 11)),
        ((12, 0), (13, 4)),
        ((13, 4), (16, 8)),
        ((16, 8), (15, 10)),
        ((15, 10), (16, 16)),
        ((16, 16), (12, 10)),
        ((12, 10), (6, 7)),
        ((6, 7), (4, 7)),
        ((4, 7), (0, 8)),
        ((13, 0), (16, 6)),
        ((14, 0), (16, 4)),
        ((15, 0), (16, 2)),
        ((0, 10), (7, 11)),
        ((9, 12), (10, 10)),
        ((10, 10), (12, 12)),
        ((12, 12), (9, 12)),
        ((8, 15), (9, 13)),
        ((9, 13), (11, 15)),
        ((11, 15), (8, 15)),
        ((0, 12), (3, 13)),
        ((3, 13), (7, 15)),
        ((7, 15), (8, 16)),
        ((2, 16), (3, 13)),
        ((4, 16), (5, 14)),
        ((6, 16), (7, 15))
      )
    )

  val r: Image =
    grid(
      List(
        ((0, 12), (1, 14)),
        ((0, 8), (2, 12)),
        ((0, 4), (5, 10)),
        ((0, 0), (8, 8)),
        ((1, 1), (4, 0)),
        ((2, 2), (8, 0)),
        ((3, 3), (8, 2)),
        ((8, 2), (12, 0)),
        ((5, 5), (12, 3)),
        ((12, 3), (16, 0)),
        ((0, 16), (2, 12)),
        ((2, 12), (8, 8)),
        ((8, 8), (14, 6)),
        ((14, 6), (16, 4)),
        ((6, 16), (11, 10)),
        ((11, 10), (16, 6)),
        ((11, 16), (12, 12)),
        ((12, 12), (16, 8)),
        ((12, 12), (16, 16)),
        ((13, 13), (16, 10)),
        ((14, 14), (16, 12)),
        ((15, 15), (16, 14))
      )
    )

  val s: Image =
    grid(
      List(
        ((0, 0), (4, 2)),
        ((4, 2), (8, 2)),
        ((8, 2), (16, 0)),
        ((0, 4), (2, 1)),
        ((0, 6), (7, 4)),
        ((0, 8), (8, 6)),
        ((0, 10), (7, 8)),
        ((0, 12), (7, 10)),
        ((0, 14), (7, 13)),
        ((8, 16), (7, 13)),
        ((7, 13), (7, 8)),
        ((7, 8), (8, 6)),
        ((8, 6), (10, 4)),
        ((10, 4), (16, 0)),
        ((10, 16), (11, 10)),
        ((10, 6), (12, 4)),
        ((12, 4), (12, 7)),
        ((12, 7), (10, 6)),
        ((13, 7), (15, 5)),
        ((15, 5), (15, 8)),
        ((15, 8), (13, 7)),
        ((12, 16), (13, 13)),
        ((13, 13), (15, 9)),
        ((15, 9), (16, 8)),
        ((13, 13), (16, 14)),
        ((14, 11), (16, 12)),
        ((15, 9), (16, 10))
      )
    )

  val t: Image = quartet(p, q, r, s)

  val u: Image = cycle(q rotate 90.degrees)

  val side1: Image =
    quartet(blank(), blank(), t.scale(2, 2).rotate(90.degrees), t.scale(2, 2))

  val side2: Image =
    quartet(side1, side1, (t rotate 90.degrees).scale(4, 4), t.scale(4, 4))

  val corner1: Image = quartet(blank(), blank(), blank(), u.scale(2, 2))

  val corner2: Image =
    quartet(corner1, side1, side1 rotate 90.degrees, u.scale(4, 4))

  val pseudocorner: Image =
    quartet(
      corner2,
      side2,
      side2 rotate 90.degrees,
      (t rotate 90.degrees).scale(8, 8)
    )

  val fishes: Image = cycle(pseudocorner)

  // the at call is needed because putting 2 different sized images beside
  // each other aligns at the top, but we need them aligned at the bottom
  val corner: Image = nonet(
    corner2,
    side2,
    side2,
    side2 rotate 90.degrees,
    u.scale(8, 8),
    (t rotate 90.degrees).scale(8, 8),
    side2 rotate 90.degrees,
    (t rotate 90.degrees).scale(8, 8),
    (q rotate 90.degrees).scale(16, 16).at(0, -128)
  )

  val squarelimit: Image = cycle(corner)

  val image: Image = squarelimit

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy