Skip to content

Commit

Permalink
V0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
nhartland committed Jul 14, 2018
1 parent ec8d5f3 commit ec7118c
Show file tree
Hide file tree
Showing 72 changed files with 1,629 additions and 1,872 deletions.
29 changes: 18 additions & 11 deletions CHANGELOG.md
Expand Up @@ -5,27 +5,34 @@
0.2b
---------

- Improved circle raster (no longer repeats points)
### Features
- Implemented a 'mask' subpattern that masks out cells according to a provided
function
- Added Voronoi relaxation via Lloyd's algorithm
- Added pattern.cells: an iterator over the constituent cells in a pattern
- Added cell_coordinates iterator, returning an (x,y) pair rather than a cell
- Added shuffled_cells iterator, similar to cells but in a randomised order
- Added centroid and medoid (with general distance measure) methods and tests
- Added a Poisson-disc sampling subpattern
- Added Mitchell's Best-Candidate sampling (approximate Poisson-Disc)

### Bugfix
- Fixed bug with subpattern.enclosed which would generate more than one enclosed
point for a primitive.circle
- Fixed default initialisation of RNG in automata.async_iterate

### Misc
- Improved circle raster (no longer repeats points)
- Integrated all tests into a single test script, and added luacov coverage
- Implemented a 'mask' subpattern that masks out cells according to a provided
function
- Converted subpattern.random to take as an argument a fixed integer number of
desired samples rather than a fraction of the domain size.
- Added Voronoi relaxation via Lloyd's algorithm
- Fixed default initialisation of RNG in automata.async_iterate
- Removed special handling of '-0' coordinate in cell: No longer required with
integer spatial hash in patterns.
- Made pattern coordinate limits explicit in MAX_COORDINATE
- Changed internal structure of `pattern`, from a list of cells to a list of
coordinate hashes
- Added pattern.cells: an iterator over the constituent cells in a pattern
- Added cell_coordinates iterator, returning an (x,y) pair rather than a cell
- Added shuffled_cells iterator, similar to cells but in a randomised order
- Added example of Worley noise
- Various optimisations
- Added centroid and medoid (with general distance measure) methods and tests
- Added a Poisson-disc sampling subpattern
- Removed some (confusing) functionality from `cell`, namely addition and
multiplication with a number value.
- Added isoline drawing example
- Renamed pretty_print to print_patterns
140 changes: 76 additions & 64 deletions README.md
@@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.org/nhartland/forma.svg?branch=master)](https://travis-ci.org/nhartland/forma)
[![Coverage Status](https://coveralls.io/repos/github/nhartland/forma/badge.svg?branch=master)](https://coveralls.io/github/nhartland/forma?branch=master)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

forma
Expand All @@ -10,92 +11,103 @@ __2D grid shape generation in Lua__
<img width="650" height="320" src="https://i.imgur.com/si0FhKN.png">
</p>

This package is intended for the generation and manipulation of shapes on a two
dimensional grid or lattice. It came about as part of experiments in making
roguelike games. **forma** is therefore particularly suited for the generation
of roguelike environments.

Shapes can be generated in several ways. From simple rasters of primitive shapes
like circles, lines and squares, to pattern generation by a [Cellular
Automata](https://en.wikipedia.org/wiki/Cellular_automaton) (CA) implementation,
including both synchronous and asynchronous update rules. Using the CA methods,
patterns such as the classic 4-5 rule 'cave' systems can be generated:

<p align="center">
<img width="650" height="320" src="https://i.imgur.com/r6D7hxb.png">
</p>

However the real power of the CA implementation is in its flexibility.
Different CA rules with custom cellular *neighbourhoods* (including
**forma** is a utility library for the procedural generation and manipulation of
shapes on a two dimensional grid or lattice. It came about as part of
experiments in making roguelike games. **forma** is therefore particularly
suited for (but not limited to) the generation of roguelike environments.


## Features

- **A spatial-hashing pattern** class for fast lookup of active cells.
- **Pattern manipulators** such as addition, subtraction and reflection for the
generation of symmetrical patterns.
- **Rasterisation algorithms** for 2D primitives, e.g lines, circles, squares.
- A very flexible **cellular automata** implementation with
- Synchronous and asynchronous updates
- Combination of multiple rule sets
- **Pattern sampling** algorithms including
- Random (white noise) sampling
- Poisson-disc sampling
- Mitchell's best-candidate sampling
- **Algorithms for subpattern finding** including
- Flood-fill contiguous segment finding
- Pattern edge and surface finding
- Binary space partitioning
- Voronoi tessellation / Lloyd's algorithm

Results can be nested to produce complex patterns, and all of these methods are
able to use custom distance measures and definitions of the cellular
**neighbourhood** (e.g
[Moore](https://en.wikipedia.org/wiki/Moore_neighborhood), [von
Neumann](https://en.wikipedia.org/wiki/Von_Neumann_neighborhood) and more) may
be combined. Patterns can also be recursively generated by nesting the result of
one pattern in another. Interesting structures can therefore be formed by
combining different CA rule sets with different neighbourhoods and domains. For
example a 'corridor' structure:
Neumann](https://en.wikipedia.org/wiki/Von_Neumann_neighborhood)).

<p align="center">
<img width="650" height="320" src="https://i.imgur.com/PF7cMw7.png">
</p>

In addition to pattern generation tools, **forma** implements several useful
methods for the manipulation of patterns. Basic operations such as pattern
addition or subtraction, enlargement and reflection are included. On top of
these, more involved methods such as flood-filling, Voronoi tessellation, hull
finding or Binary Space Partitioning are also available. Once again most of
these operations can be performed under custom definitions of the cellular
neighbourhood.
## Examples
* [Example Gallery](examples/)
```lua
-- Generate a square box to run the CA inside
local domain = primitives.square(80,20)

Custom pattern operations can be easily implemented making use of a masking
procedure, as shown in an example demonstrating thresholded [Worley
noise](https://en.wikipedia.org/wiki/Worley_noise):
-- CA initial condition: 800-point random sample of the domain
local ca = subpattern.random(domain, 800)

<p align="center">
<img width="650" height="320" src="https://i.imgur.com/Gyn4QLx.png">
</p>
-- Moore (8-cell) neighbourhood 4-5 rule
local moore = automata.rule(neighbourhood.moore(), "B5678/S45678")

All of the above examples can be generated by code in the `examples` folder.
-- Run the CA until converged or 1000 iterations
local ite, converged = 0, false
while converged == false and ite < 1000 do
ca, converged = automata.iterate(ca, domain, {moore})
ite = ite+1
end

Warning
-------
The master branch is in active development. API breaking changes may
occasionally occur.
-- Access a subpattern's cell coordinates for external use
for icell in ca:cells() do
-- local foo = bar(cell)
-- or
-- local foo = bar(cell.x, cell.y)
end

Requirements
------------
Compatible with Lua 5.1, 5.2, 5.3 and LuaJIT 2.0, 2.1.
-- Find all 4-contiguous segments of the CA pattern
-- Uses the von-neumann neighbourhood to determine 'connectedness'
-- but any custom neighbourhood can be used)
local segments = subpattern.segments(ca, neighbourhood.von_neumann())

The test suite requires
- [LuaCov](https://keplerproject.github.io/luacov/)
- [luaunit](https://github.com/bluebird75/luaunit)
-- Print a representation to io.output
subpattern.print_patterns(domain, segments)
```

Generating the documentation requires
- [LDoc](https://github.com/stevedonovan/LDoc)
## Installation

Running examples
----------------
**forma** is compatible with Lua 5.1, 5.2, 5.3 and LuaJIT 2.0, 2.1. The library
is written in pure Lua, no compilation is required. Including the project is as
simple as including the `forma` directory in your project or Lua path.

The examples require that the `forma/` directory is in the lua path. The easiest
way to try the examples is to run them from the root directory of this repo. For
example
The easiest way to do this is via LuaRocks:

lua examples/game_of_life.lua
```Shell
luarocks install forma
```

Generating documentation
------------------------
## Generating documentation

Documentation is hosted [here](https://nhartland.github.io/forma/).

Generating the documentation requires
- [LDoc](https://github.com/stevedonovan/LDoc)

Simply running

ldoc --output contents --dir docs .

in the root directory should generate all the required pages.

Testing
-------
## Testing

Unit tests and coverage reports are provided. The test suite requires
- [LuaCov](https://keplerproject.github.io/luacov/)
- [luaunit](https://github.com/bluebird75/luaunit)

Unit tests are provided for some methods with the luaunit framework, coverage is
tested using LuaCov. To run the tests use
To run the tests use

./run_tests.sh
13 changes: 0 additions & 13 deletions TODO.md

This file was deleted.

2 changes: 1 addition & 1 deletion config.ld
@@ -1,5 +1,5 @@
project = 'forma'
title = 'forma Reference Manual'
title = 'forma Reference'
description = 'A 2D grid shape generation package'
kind_names={topic='Readme'}
format = 'markdown'
Expand Down
1 change: 0 additions & 1 deletion docs/README.md

This file was deleted.

47 changes: 16 additions & 31 deletions docs/contents.html
Expand Up @@ -3,7 +3,7 @@
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>forma Reference Manual</title>
<title>forma Reference</title>
<link rel="stylesheet" href="ldoc.css" type="text/css" />
</head>
<body>
Expand Down Expand Up @@ -44,19 +44,16 @@ <h2>Readme</h2>
</ul>
<h2>Examples</h2>
<ul class="nowrap">
<li><a href="examples/async_automata.lua.html">async_automata.lua</a></li>
<li><a href="examples/binary_space_partition.lua.html">binary_space_partition.lua</a></li>
<li><a href="examples/carpet.lua.html">carpet.lua</a></li>
<li><a href="examples/caves.lua.html">caves.lua</a></li>
<li><a href="examples/bubbles.lua.html">bubbles.lua</a></li>
<li><a href="examples/cellular_automata.lua.html">cellular_automata.lua</a></li>
<li><a href="examples/corridors.lua.html">corridors.lua</a></li>
<li><a href="examples/game_of_life.lua.html">game_of_life.lua</a></li>
<li><a href="examples/game_of_life_async.lua.html">game_of_life_async.lua</a></li>
<li><a href="examples/lloyds_algorithm.lua.html">lloyds_algorithm.lua</a></li>
<li><a href="examples/isolines.lua.html">isolines.lua</a></li>
<li><a href="examples/maxrectangle.lua.html">maxrectangle.lua</a></li>
<li><a href="examples/platformer.lua.html">platformer.lua</a></li>
<li><a href="examples/primitives.lua.html">primitives.lua</a></li>
<li><a href="examples/shapes.lua.html">shapes.lua</a></li>
<li><a href="examples/readme.lua.html">readme.lua</a></li>
<li><a href="examples/sampling.lua.html">sampling.lua</a></li>
<li><a href="examples/voronoi.lua.html">voronoi.lua</a></li>
<li><a href="examples/worley.lua.html">worley.lua</a></li>
</ul>

</div>
Expand Down Expand Up @@ -103,64 +100,52 @@ <h2>Readme</h2>
<h2>Examples</h2>
<table class="module_list">
<tr>
<td class="name" nowrap><a href="examples/binary_space_partition.lua.html">binary_space_partition.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/carpet.lua.html">carpet.lua</a></td>
<td class="name" nowrap><a href="examples/async_automata.lua.html">async_automata.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/caves.lua.html">caves.lua</a></td>
<td class="name" nowrap><a href="examples/binary_space_partition.lua.html">binary_space_partition.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/corridors.lua.html">corridors.lua</a></td>
<td class="name" nowrap><a href="examples/bubbles.lua.html">bubbles.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/game_of_life.lua.html">game_of_life.lua</a></td>
<td class="name" nowrap><a href="examples/cellular_automata.lua.html">cellular_automata.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/game_of_life_async.lua.html">game_of_life_async.lua</a></td>
<td class="name" nowrap><a href="examples/corridors.lua.html">corridors.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/lloyds_algorithm.lua.html">lloyds_algorithm.lua</a></td>
<td class="name" nowrap><a href="examples/isolines.lua.html">isolines.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/maxrectangle.lua.html">maxrectangle.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/platformer.lua.html">platformer.lua</a></td>
<td class="name" nowrap><a href="examples/readme.lua.html">readme.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/primitives.lua.html">primitives.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/shapes.lua.html">shapes.lua</a></td>
<td class="name" nowrap><a href="examples/sampling.lua.html">sampling.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/voronoi.lua.html">voronoi.lua</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name" nowrap><a href="examples/worley.lua.html">worley.lua</a></td>
<td class="summary"></td>
</tr>
</table>

</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2018-07-08 14:23:43 </i>
<i style="float:right;">Last updated 2018-07-14 16:06:25 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
Expand Down

0 comments on commit ec7118c

Please sign in to comment.