Adds #89 - Added delaunay Lua module
parent
e7960051e3
commit
bede9dd623
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Roland Y.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,111 @@
|
|||
Delaunay
|
||||
=====
|
||||
|
||||
[![Build Status](https://travis-ci.org/Yonaba/delaunay.png)](https://travis-ci.org/Yonaba/delaunay)
|
||||
[![Coverage Status](https://coveralls.io/repos/Yonaba/delaunay/badge.png?branch=master)](https://coveralls.io/r/Yonaba/delaunay?branch=master)
|
||||
[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE)
|
||||
|
||||
*delaunay* is a Lua module for [delaunay triangulation](http://en.wikipedia.org/wiki/Delaunay_triangulation) of a convex polygon.
|
||||
|
||||
##Download
|
||||
|
||||
###Git
|
||||
|
||||
````
|
||||
git clone http://github.com/Yonaba/delaunay.git
|
||||
````
|
||||
|
||||
###Archive
|
||||
|
||||
* [zip](https://github.com/Yonaba/delaunay/archive/delaunay-0.1-1.zip) | [tar.gz](https://github.com/Yonaba/delaunay/archive/delaunay-0.1-1.tar.gz) | [all](http://github.com/Yonaba/delaunay/tags)
|
||||
|
||||
###LuaRocks
|
||||
|
||||
````
|
||||
luarocks install delaunay
|
||||
````
|
||||
|
||||
###MoonRocks
|
||||
|
||||
````
|
||||
luarocks install --server=http://rocks.moonscript.org/manifests/Yonaba delaunay
|
||||
````
|
||||
|
||||
##Installation
|
||||
Copy the file [delaunay.lua](http://raw.github.com/Yonaba/delaunay/master/delaunay.lua) inside your project folder,
|
||||
call it with [require](http://pgl.yoyo.org/luai/i/require) function. It will return the `Delaunay` module, keeping safe the global environment.<br/>
|
||||
|
||||
##Usage
|
||||
|
||||
The module provides 3 classes: <br/>
|
||||
* `Point`
|
||||
* `Edge`
|
||||
* `Triangle`
|
||||
|
||||
It also provides a single function named `triangulate`. This function accepts
|
||||
a variable list (*vararg* `...`) of instances of class `Point`. Assuming those
|
||||
points are the vertices of a convex polygon, it returns a table of instances of the class `Triangle` forming a *Delaunay triangulation* of the given polygon.
|
||||
|
||||
A basic code example:
|
||||
```lua
|
||||
local Delaunay = require 'Delaunay'
|
||||
local Point = Delaunay.Point
|
||||
|
||||
-- Creating 10 random points
|
||||
local points = {}
|
||||
for i = 1, 10 do
|
||||
points[i] = Point(math.random() * 100, math.random() * 100)
|
||||
end
|
||||
|
||||
-- Triangulating de convex polygon made by those points
|
||||
local triangles = Delaunay.triangulate(unpack(points))
|
||||
|
||||
-- Printing the results
|
||||
for i, triangle in ipairs(triangles) do
|
||||
print(triangle)
|
||||
end
|
||||
````
|
||||
|
||||
See the [documentation](http://yonaba.github.io/delaunay/doc) for more details.
|
||||
|
||||
##Testing
|
||||
###Specification
|
||||
|
||||
This repository include unit tests. You can run them using [Telescope](https://github.com/norman/telescope) with the following command from the root foolder:
|
||||
|
||||
```
|
||||
lua tsc -f specs/*
|
||||
```
|
||||
|
||||
###Performance
|
||||
|
||||
You can run the random performance tests included with the following command from the root folder:
|
||||
|
||||
```lua
|
||||
lua performance/bench.lua
|
||||
````
|
||||
|
||||
##License
|
||||
This work is under [MIT-LICENSE](http://www.opensource.org/licenses/mit-license.php).<br/>
|
||||
Copyright (c) 2013 Roland Yonaba
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Yonaba/delaunay/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
|
@ -0,0 +1,801 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Delaunay module documentation</title>
|
||||
<link rel="stylesheet" href="ldoc.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Delaunay (v0.1)</h1>
|
||||
|
||||
|
||||
<h2>Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#Class_Edge">Class Edge </a></li>
|
||||
<li><a href="#Class_Point">Class Point </a></li>
|
||||
<li><a href="#Class_Triangle">Class Triangle </a></li>
|
||||
<li><a href="#Delaunay_module">Delaunay module </a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Scripts</h2>
|
||||
<ul class="nowrap">
|
||||
<li><strong>delaunay</strong></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1>Script <code>delaunay</code></h1>
|
||||
|
||||
<p>
|
||||
<h2>Delaunay, Lua module for convex polygon triangulation</h2>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<h3>Info:</h3>
|
||||
<ul>
|
||||
<li><strong>Copyright</strong>: 2013</li>
|
||||
<li><strong>License</strong>: MIT</li>
|
||||
<li><strong>Author</strong>: Roland Yonaba</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a href="#Class_Edge">Class Edge </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:new">Edge:new (p1, p2)</a></td>
|
||||
<td class="summary">Creates a new <a href="index.html#Class_Edge">Edge</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:same">Edge:same (otherEdge)</a></td>
|
||||
<td class="summary">Test if <code>otherEdge</code> is similar to self.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:length">Edge:length ()</a></td>
|
||||
<td class="summary">Returns the length.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:getMidPoint">Edge:getMidPoint ()</a></td>
|
||||
<td class="summary">Returns the midpoint coordinates.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Class_Point">Class Point </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:new">Point:new (x, y)</a></td>
|
||||
<td class="summary">Creates a new <a href="index.html#Class_Point">Point</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:dist2">Point:dist2 (p)</a></td>
|
||||
<td class="summary">Returns the square distance to another <a href="index.html#Class_Point">Point</a> .</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:dist">Point:dist (p)</a></td>
|
||||
<td class="summary">Returns the distance to another <a href="index.html#Class_Point">Point</a> .</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:isInCircle">Point:isInCircle (cx, cy, r)</a></td>
|
||||
<td class="summary">Checks if self lies into the bounds of a circle</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Class_Triangle">Class Triangle </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:new">Triangle:new (p1, p2, p3)</a></td>
|
||||
<td class="summary">Creates a new <a href="index.html#Class_Triangle">Triangle</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:isCW">Triangle:isCW ()</a></td>
|
||||
<td class="summary">Checks if the triangle is defined clockwise (sequence p1-p2-p3)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:isCCW">Triangle:isCCW ()</a></td>
|
||||
<td class="summary">Checks if the triangle is defined counter-clockwise (sequence p1-p2-p3)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getSidesLength">Triangle:getSidesLength ()</a></td>
|
||||
<td class="summary">Returns the length of the edges</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCenter">Triangle:getCenter ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumCircle">Triangle:getCircumCircle ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the circumcircle center and its radius</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumCenter">Triangle:getCircumCenter ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the circumcircle center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumRadius">Triangle:getCircumRadius ()</a></td>
|
||||
<td class="summary">Returns the radius of the circumcircle</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getArea">Triangle:getArea ()</a></td>
|
||||
<td class="summary">Returns the area</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:inCircumCircle">Triangle:inCircumCircle (p)</a></td>
|
||||
<td class="summary">Checks if a given point lies into the triangle circumcircle</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Delaunay_module">Delaunay module </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Delaunay">Delaunay</a></td>
|
||||
<td class="summary">Delaunay module</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Delaunay.triangulate">Delaunay.triangulate (...)</a></td>
|
||||
<td class="summary">Triangulates a set of given vertices</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<h2><a name="Class_Edge"></a>Class Edge </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Edge:new"></a>
|
||||
<strong>Edge:new (p1, p2)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="index.html#Class_Edge">Edge</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p1</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p2</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="index.html#Class_Edge">Edge</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Edge = Delaunay.Edge
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> e = Edge:new(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>))
|
||||
<span class="keyword">local</span> e = Edge(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>)) <span class="comment">-- Alias to Edge.new
|
||||
</span> <span class="global">print</span>(e) <span class="comment">-- print the edge members p1 and p2
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:same"></a>
|
||||
<strong>Edge:same (otherEdge)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Test if <code>otherEdge</code> is similar to self. It does not take into account the direction.
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">otherEdge</span>
|
||||
an <a href="index.html#Class_Edge">Edge</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e1 = Edge(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>))
|
||||
<span class="keyword">local</span> e2 = Edge(Point(<span class="number">2</span>,<span class="number">5</span>), Point(<span class="number">1</span>,<span class="number">1</span>))
|
||||
<span class="global">print</span>(e1:same(e2)) <span class="comment">--> true
|
||||
</span> <span class="global">print</span>(e1 == e2)) <span class="comment">--> false, == operator considers the direction
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:length"></a>
|
||||
<strong>Edge:length ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the length.
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the length of self
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e = Edge(Point(), Point(<span class="number">10</span>,<span class="number">0</span>))
|
||||
<span class="global">print</span>(e:length()) <span class="comment">--> 10
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:getMidPoint"></a>
|
||||
<strong>Edge:getMidPoint ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the midpoint coordinates.
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of self midpoint</li>
|
||||
<li>
|
||||
the y-coordinate of self midpoint</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e = Edge(Point(), Point(<span class="number">10</span>,<span class="number">0</span>))
|
||||
<span class="global">print</span>(e:getMidPoint()) <span class="comment">--> 5, 0
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Class_Point"></a>Class Point </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Point:new"></a>
|
||||
<strong>Point:new (x, y)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="index.html#Class_Point">Point</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">x</span>
|
||||
the x-coordinate
|
||||
</li>
|
||||
<li><span class="parameter">y</span>
|
||||
the y-coordinate
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="index.html#Class_Point">Point</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> p = Point:new(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> p = Point(<span class="number">1</span>,<span class="number">1</span>) <span class="comment">-- Alias to Point.new
|
||||
</span> <span class="global">print</span>(p) <span class="comment">-- print the point members x and y
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:dist2"></a>
|
||||
<strong>Point:dist2 (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the square distance to another <a href="index.html#Class_Point">Point</a> .
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the square distance from self to <code>p</code>.
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="global">print</span>(p1:dist2(p2)) <span class="comment">--> 2
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:dist"></a>
|
||||
<strong>Point:dist (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the distance to another <a href="index.html#Class_Point">Point</a> .
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the distance from self to <code>p</code>.
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="global">print</span>(p1:dist2(p2)) <span class="comment">--> 1.4142135623731
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:isInCircle"></a>
|
||||
<strong>Point:isInCircle (cx, cy, r)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if self lies into the bounds of a circle
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">cx</span>
|
||||
the x-coordinate of the circle center
|
||||
</li>
|
||||
<li><span class="parameter">cy</span>
|
||||
the y-coordinate of the circle center
|
||||
</li>
|
||||
<li><span class="parameter">r</span>
|
||||
the radius of the circle
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p = Point()
|
||||
<span class="global">print</span>(p:isInCircle(<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>)) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Class_Triangle"></a>Class Triangle </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Triangle:new"></a>
|
||||
<strong>Triangle:new (p1, p2, p3)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="index.html#Class_Triangle">Triangle</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p1</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p2</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p3</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="index.html#Class_Triangle">Triangle</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Triangle = Delaunay.Triangle
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle:new(p1, p2, p3)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3) <span class="comment">-- Alias to Triangle.new
|
||||
</span> <span class="global">print</span>(t) <span class="comment">-- print the triangle members p1, p2 and p3
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:isCW"></a>
|
||||
<strong>Triangle:isCW ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if the triangle is defined clockwise (sequence p1-p2-p3)
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">0</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:isCW()) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:isCCW"></a>
|
||||
<strong>Triangle:isCCW ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if the triangle is defined counter-clockwise (sequence p1-p2-p3)
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:isCCW()) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getSidesLength"></a>
|
||||
<strong>Triangle:getSidesLength ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the length of the edges
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the length of the edge p1-p2</li>
|
||||
<li>
|
||||
the length of the edge p2-p3</li>
|
||||
<li>
|
||||
the length of the edge p3-p1</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getSidesLength()) <span class="comment">--> 2 1.4142135623731 1.4142135623731
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCenter"></a>
|
||||
<strong>Triangle:getCenter ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the center
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the center</li>
|
||||
<li>
|
||||
the y-coordinate of the center</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCenter()) <span class="comment">--> 1 0.33333333333333
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumCircle"></a>
|
||||
<strong>Triangle:getCircumCircle ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the circumcircle center and its radius
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the y-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the radius of the circumcircle</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumCircle()) <span class="comment">--> 1 0 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumCenter"></a>
|
||||
<strong>Triangle:getCircumCenter ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the circumcircle center
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the y-coordinate of the circumcircle center</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumCenter()) <span class="comment">--> 1 0
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumRadius"></a>
|
||||
<strong>Triangle:getCircumRadius ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the radius of the circumcircle
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the radius of the circumcircle
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumRadius()) <span class="comment">--> 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getArea"></a>
|
||||
<strong>Triangle:getArea ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the area
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the area
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getArea()) <span class="comment">--> 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:inCircumCircle"></a>
|
||||
<strong>Triangle:inCircumCircle (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if a given point lies into the triangle circumcircle
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:inCircumCircle(Point(<span class="number">1</span>,-<span class="number">1</span>))) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Delaunay_module"></a>Delaunay module </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Delaunay"></a>
|
||||
<strong>Delaunay</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Delaunay module
|
||||
|
||||
<h3>Fields:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">Point</span>
|
||||
reference to the <a href="index.html#Class_Point">Point</a> class
|
||||
</li>
|
||||
<li><span class="parameter">Edge</span>
|
||||
reference to the <a href="index.html#Class_Edge">Edge</a> class
|
||||
</li>
|
||||
<li><span class="parameter">Triangle</span>
|
||||
reference to the <a href="index.html#Class_Triangle">Triangle</a> class
|
||||
</li>
|
||||
<li><span class="parameter">_VERSION</span>
|
||||
the version of the current module
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Delaunay.triangulate"></a>
|
||||
<strong>Delaunay.triangulate (...)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Triangulates a set of given vertices
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">...</span>
|
||||
a <code>vargarg</code> list of objects of type <a href="index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a set of objects of type <a href="index.html#Class_Triangle">Triangle</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> p1, p2, p3, p4 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">1</span>,-<span class="number">1</span>)
|
||||
<span class="keyword">local</span> triangles = Delaunay.triangulate(p1, p2, p3, p4)
|
||||
<span class="keyword">for</span> i = <span class="number">1</span>, #triangles <span class="keyword">do</span>
|
||||
<span class="global">print</span>(triangles[i])
|
||||
<span class="keyword">end</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.0</a></i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,801 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<head>
|
||||
<title>Delaunay module documentation</title>
|
||||
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
|
||||
<div id="main">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
|
||||
<div id="navigation">
|
||||
<br/>
|
||||
<h1>Delaunay (v0.1)</h1>
|
||||
|
||||
|
||||
<h2>Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#Class_Edge">Class Edge </a></li>
|
||||
<li><a href="#Class_Point">Class Point </a></li>
|
||||
<li><a href="#Class_Triangle">Class Triangle </a></li>
|
||||
<li><a href="#Delaunay_module">Delaunay module </a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Scripts</h2>
|
||||
<ul class="nowrap">
|
||||
<li><strong>delaunay</strong></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1>Script <code>delaunay</code></h1>
|
||||
|
||||
<p>
|
||||
<h2>Delaunay, Lua module for convex polygon triangulation</h2>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<h3>Info:</h3>
|
||||
<ul>
|
||||
<li><strong>Copyright</strong>: 2013</li>
|
||||
<li><strong>License</strong>: MIT</li>
|
||||
<li><strong>Author</strong>: Roland Yonaba</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2><a href="#Class_Edge">Class Edge </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:new">Edge:new (p1, p2)</a></td>
|
||||
<td class="summary">Creates a new <a href="../index.html#Class_Edge">Edge</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:same">Edge:same (otherEdge)</a></td>
|
||||
<td class="summary">Test if <code>otherEdge</code> is similar to self.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:length">Edge:length ()</a></td>
|
||||
<td class="summary">Returns the length.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Edge:getMidPoint">Edge:getMidPoint ()</a></td>
|
||||
<td class="summary">Returns the midpoint coordinates.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Class_Point">Class Point </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:new">Point:new (x, y)</a></td>
|
||||
<td class="summary">Creates a new <a href="../index.html#Class_Point">Point</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:dist2">Point:dist2 (p)</a></td>
|
||||
<td class="summary">Returns the square distance to another <a href="../index.html#Class_Point">Point</a> .</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:dist">Point:dist (p)</a></td>
|
||||
<td class="summary">Returns the distance to another <a href="../index.html#Class_Point">Point</a> .</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Point:isInCircle">Point:isInCircle (cx, cy, r)</a></td>
|
||||
<td class="summary">Checks if self lies into the bounds of a circle</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Class_Triangle">Class Triangle </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:new">Triangle:new (p1, p2, p3)</a></td>
|
||||
<td class="summary">Creates a new <a href="../index.html#Class_Triangle">Triangle</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:isCW">Triangle:isCW ()</a></td>
|
||||
<td class="summary">Checks if the triangle is defined clockwise (sequence p1-p2-p3)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:isCCW">Triangle:isCCW ()</a></td>
|
||||
<td class="summary">Checks if the triangle is defined counter-clockwise (sequence p1-p2-p3)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getSidesLength">Triangle:getSidesLength ()</a></td>
|
||||
<td class="summary">Returns the length of the edges</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCenter">Triangle:getCenter ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumCircle">Triangle:getCircumCircle ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the circumcircle center and its radius</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumCenter">Triangle:getCircumCenter ()</a></td>
|
||||
<td class="summary">Returns the coordinates of the circumcircle center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getCircumRadius">Triangle:getCircumRadius ()</a></td>
|
||||
<td class="summary">Returns the radius of the circumcircle</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:getArea">Triangle:getArea ()</a></td>
|
||||
<td class="summary">Returns the area</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Triangle:inCircumCircle">Triangle:inCircumCircle (p)</a></td>
|
||||
<td class="summary">Checks if a given point lies into the triangle circumcircle</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a href="#Delaunay_module">Delaunay module </a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Delaunay">Delaunay</a></td>
|
||||
<td class="summary">Delaunay module</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#Delaunay.triangulate">Delaunay.triangulate (...)</a></td>
|
||||
<td class="summary">Triangulates a set of given vertices</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<h2><a name="Class_Edge"></a>Class Edge </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Edge:new"></a>
|
||||
<strong>Edge:new (p1, p2)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="../index.html#Class_Edge">Edge</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p1</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p2</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="../index.html#Class_Edge">Edge</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Edge = Delaunay.Edge
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> e = Edge:new(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>))
|
||||
<span class="keyword">local</span> e = Edge(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>)) <span class="comment">-- Alias to Edge.new
|
||||
</span> <span class="global">print</span>(e) <span class="comment">-- print the edge members p1 and p2
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:same"></a>
|
||||
<strong>Edge:same (otherEdge)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Test if <code>otherEdge</code> is similar to self. It does not take into account the direction.
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">otherEdge</span>
|
||||
an <a href="../index.html#Class_Edge">Edge</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e1 = Edge(Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">5</span>))
|
||||
<span class="keyword">local</span> e2 = Edge(Point(<span class="number">2</span>,<span class="number">5</span>), Point(<span class="number">1</span>,<span class="number">1</span>))
|
||||
<span class="global">print</span>(e1:same(e2)) <span class="comment">--> true
|
||||
</span> <span class="global">print</span>(e1 == e2)) <span class="comment">--> false, == operator considers the direction
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:length"></a>
|
||||
<strong>Edge:length ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the length.
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the length of self
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e = Edge(Point(), Point(<span class="number">10</span>,<span class="number">0</span>))
|
||||
<span class="global">print</span>(e:length()) <span class="comment">--> 10
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Edge:getMidPoint"></a>
|
||||
<strong>Edge:getMidPoint ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the midpoint coordinates.
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of self midpoint</li>
|
||||
<li>
|
||||
the y-coordinate of self midpoint</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> e = Edge(Point(), Point(<span class="number">10</span>,<span class="number">0</span>))
|
||||
<span class="global">print</span>(e:getMidPoint()) <span class="comment">--> 5, 0
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Class_Point"></a>Class Point </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Point:new"></a>
|
||||
<strong>Point:new (x, y)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="../index.html#Class_Point">Point</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">x</span>
|
||||
the x-coordinate
|
||||
</li>
|
||||
<li><span class="parameter">y</span>
|
||||
the y-coordinate
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="../index.html#Class_Point">Point</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> p = Point:new(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> p = Point(<span class="number">1</span>,<span class="number">1</span>) <span class="comment">-- Alias to Point.new
|
||||
</span> <span class="global">print</span>(p) <span class="comment">-- print the point members x and y
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:dist2"></a>
|
||||
<strong>Point:dist2 (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the square distance to another <a href="../index.html#Class_Point">Point</a> .
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the square distance from self to <code>p</code>.
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="global">print</span>(p1:dist2(p2)) <span class="comment">--> 2
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:dist"></a>
|
||||
<strong>Point:dist (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the distance to another <a href="../index.html#Class_Point">Point</a> .
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the distance from self to <code>p</code>.
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="global">print</span>(p1:dist2(p2)) <span class="comment">--> 1.4142135623731
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Point:isInCircle"></a>
|
||||
<strong>Point:isInCircle (cx, cy, r)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if self lies into the bounds of a circle
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">cx</span>
|
||||
the x-coordinate of the circle center
|
||||
</li>
|
||||
<li><span class="parameter">cy</span>
|
||||
the y-coordinate of the circle center
|
||||
</li>
|
||||
<li><span class="parameter">r</span>
|
||||
the radius of the circle
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p = Point()
|
||||
<span class="global">print</span>(p:isInCircle(<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>)) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Class_Triangle"></a>Class Triangle </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Triangle:new"></a>
|
||||
<strong>Triangle:new (p1, p2, p3)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Creates a new <a href="../index.html#Class_Triangle">Triangle</a>
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p1</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p2</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
<li><span class="parameter">p3</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a new <a href="../index.html#Class_Triangle">Triangle</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Triangle = Delaunay.Triangle
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle:new(p1, p2, p3)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3) <span class="comment">-- Alias to Triangle.new
|
||||
</span> <span class="global">print</span>(t) <span class="comment">-- print the triangle members p1, p2 and p3
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:isCW"></a>
|
||||
<strong>Triangle:isCW ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if the triangle is defined clockwise (sequence p1-p2-p3)
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">2</span>,<span class="number">0</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:isCW()) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:isCCW"></a>
|
||||
<strong>Triangle:isCCW ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if the triangle is defined counter-clockwise (sequence p1-p2-p3)
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:isCCW()) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getSidesLength"></a>
|
||||
<strong>Triangle:getSidesLength ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the length of the edges
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the length of the edge p1-p2</li>
|
||||
<li>
|
||||
the length of the edge p2-p3</li>
|
||||
<li>
|
||||
the length of the edge p3-p1</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getSidesLength()) <span class="comment">--> 2 1.4142135623731 1.4142135623731
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCenter"></a>
|
||||
<strong>Triangle:getCenter ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the center
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the center</li>
|
||||
<li>
|
||||
the y-coordinate of the center</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCenter()) <span class="comment">--> 1 0.33333333333333
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumCircle"></a>
|
||||
<strong>Triangle:getCircumCircle ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the circumcircle center and its radius
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the y-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the radius of the circumcircle</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumCircle()) <span class="comment">--> 1 0 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumCenter"></a>
|
||||
<strong>Triangle:getCircumCenter ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the coordinates of the circumcircle center
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
the x-coordinate of the circumcircle center</li>
|
||||
<li>
|
||||
the y-coordinate of the circumcircle center</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumCenter()) <span class="comment">--> 1 0
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getCircumRadius"></a>
|
||||
<strong>Triangle:getCircumRadius ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the radius of the circumcircle
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the radius of the circumcircle
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getCircumRadius()) <span class="comment">--> 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:getArea"></a>
|
||||
<strong>Triangle:getArea ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Returns the area
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
the area
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:getArea()) <span class="comment">--> 1
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Triangle:inCircumCircle"></a>
|
||||
<strong>Triangle:inCircumCircle (p)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Checks if a given point lies into the triangle circumcircle
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">p</span>
|
||||
a <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<code>true</code> or <code>false</code>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> p1, p2, p3 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>)
|
||||
<span class="keyword">local</span> t = Triangle(p1, p2, p3)
|
||||
<span class="global">print</span>(t:inCircumCircle(Point(<span class="number">1</span>,-<span class="number">1</span>))) <span class="comment">--> true
|
||||
</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a name="Delaunay_module"></a>Delaunay module </h2>
|
||||
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<a name = "Delaunay"></a>
|
||||
<strong>Delaunay</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Delaunay module
|
||||
|
||||
<h3>Fields:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">Point</span>
|
||||
reference to the <a href="../index.html#Class_Point">Point</a> class
|
||||
</li>
|
||||
<li><span class="parameter">Edge</span>
|
||||
reference to the <a href="../index.html#Class_Edge">Edge</a> class
|
||||
</li>
|
||||
<li><span class="parameter">Triangle</span>
|
||||
reference to the <a href="../index.html#Class_Triangle">Triangle</a> class
|
||||
</li>
|
||||
<li><span class="parameter">_VERSION</span>
|
||||
the version of the current module
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Delaunay.triangulate"></a>
|
||||
<strong>Delaunay.triangulate (...)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Triangulates a set of given vertices
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">...</span>
|
||||
a <code>vargarg</code> list of objects of type <a href="../index.html#Class_Point">Point</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
a set of objects of type <a href="../index.html#Class_Triangle">Triangle</a>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<ul>
|
||||
<pre class="example">
|
||||
<span class="keyword">local</span> Delaunay = <span class="global">require</span> <span class="string">'Delaunay'</span>
|
||||
<span class="keyword">local</span> Point = Delaunay.Point
|
||||
<span class="keyword">local</span> p1, p2, p3, p4 = Point(), Point(<span class="number">2</span>,<span class="number">0</span>), Point(<span class="number">1</span>,<span class="number">1</span>), Point(<span class="number">1</span>,-<span class="number">1</span>)
|
||||
<span class="keyword">local</span> triangles = Delaunay.triangulate(p1, p2, p3, p4)
|
||||
<span class="keyword">for</span> i = <span class="number">1</span>, #triangles <span class="keyword">do</span>
|
||||
<span class="global">print</span>(triangles[i])
|
||||
<span class="keyword">end</span></pre>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.0</a></i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
#Version history#
|
||||
|
||||
###0.1 (12/26/2013)
|
||||
* Initial release
|
|
@ -0,0 +1,448 @@
|
|||
#!/usr/bin/env lua
|
||||
---------------
|
||||
-- ## Delaunay, Lua module for convex polygon triangulation
|
||||
-- @author Roland Yonaba
|
||||
-- @copyright 2013
|
||||
-- @license MIT
|
||||
-- @script delaunay
|
||||
|
||||
-- ================
|
||||
-- Private helpers
|
||||
-- ================
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local tostring = tostring
|
||||
local assert = assert
|
||||
local unpack = unpack
|
||||
local remove = table.remove
|
||||
local sqrt = math.sqrt
|
||||
local max = math.max
|
||||
|
||||
-- Internal class constructor
|
||||
local class = function(...)
|
||||
local klass = {}
|
||||
klass.__index = klass
|
||||
klass.__call = function(_,...) return klass:new(...) end
|
||||
function klass:new(...)
|
||||
local instance = setmetatable({}, klass)
|
||||
klass.__init(instance, ...)
|
||||
return instance
|
||||
end
|
||||
return setmetatable(klass,{__call = klass.__call})
|
||||
end
|
||||
|
||||
-- Triangle semi-perimeter by Heron's formula
|
||||
local function quatCross(a, b, c)
|
||||
local p = (a + b + c) * (a + b - c) * (a - b + c) * (-a + b + c)
|
||||
return sqrt(p)
|
||||
end
|
||||
|
||||
|
||||
-- Cross product (p1-p2, p2-p3)
|
||||
local function crossProduct(p1, p2, p3)
|
||||
local x1, x2 = p2.x - p1.x, p3.x - p2.x
|
||||
local y1, y2 = p2.y - p1.y, p3.y - p2.y
|
||||
return x1 * y2 - y1 * x2
|
||||
end
|
||||
|
||||
-- Checks if angle (p1-p2-p3) is flat
|
||||
local function isFlatAngle(p1, p2, p3)
|
||||
return (crossProduct(p1, p2, p3) == 0)
|
||||
end
|
||||
|
||||
-- ================
|
||||
-- Module classes
|
||||
-- ================
|
||||
|
||||
--- `Edge` class
|
||||
-- @type Edge
|
||||
local Edge = class()
|
||||
Edge.__eq = function(a, b) return (a.p1 == b.p1 and a.p2 == b.p2) end
|
||||
Edge.__tostring = function(e)
|
||||
return (('Edge :\n %s\n %s'):format(tostring(e.p1), tostring(e.p2)))
|
||||
end
|
||||
|
||||
--- Creates a new `Edge`
|
||||
-- @name Edge:new
|
||||
-- @param p1 a `Point`
|
||||
-- @param p2 a `Point`
|
||||
-- @return a new `Edge`
|
||||
-- @usage
|
||||
-- local Delaunay = require 'Delaunay'
|
||||
-- local Edge = Delaunay.Edge
|
||||
-- local Point = Delaunay.Point
|
||||
-- local e = Edge:new(Point(1,1), Point(2,5))
|
||||
-- local e = Edge(Point(1,1), Point(2,5)) -- Alias to Edge.new
|
||||
-- print(e) -- print the edge members p1 and p2
|
||||
--
|
||||
function Edge:__init(p1, p2)
|
||||
self.p1, self.p2 = p1, p2
|
||||
end
|
||||
|
||||
--- Test if `otherEdge` is similar to self. It does not take into account the direction.
|
||||
-- @param otherEdge an `Edge`
|
||||
-- @return `true` or `false`
|
||||
-- @usage
|
||||
-- local e1 = Edge(Point(1,1), Point(2,5))
|
||||
-- local e2 = Edge(Point(2,5), Point(1,1))
|
||||
-- print(e1:same(e2)) --> true
|
||||
-- print(e1 == e2)) --> false, == operator considers the direction
|
||||
--
|
||||
function Edge:same(otherEdge)
|
||||
return ((self.p1 == otherEdge.p1) and (self.p2 == otherEdge.p2))
|
||||
or ((self.p1 == otherEdge.p2) and (self.p2 == otherEdge.p1))
|
||||
end
|
||||
|
||||
--- Returns the length.
|
||||
-- @return the length of self
|
||||
-- @usage
|
||||
-- local e = Edge(Point(), Point(10,0))
|
||||
-- print(e:length()) --> 10
|
||||
--
|
||||
function Edge:length()
|
||||
return self.p1:dist(self.p2)
|
||||
end
|
||||
|
||||
--- Returns the midpoint coordinates.
|
||||
-- @return the x-coordinate of self midpoint
|
||||
-- @return the y-coordinate of self midpoint
|
||||
-- @usage
|
||||
-- local e = Edge(Point(), Point(10,0))
|
||||
-- print(e:getMidPoint()) --> 5, 0
|
||||
--
|
||||
function Edge:getMidPoint()
|
||||
local x = self.p1.x + (self.p2.x - self.p1.x) / 2
|
||||
local y = self.p1.x + (self.p2.y - self.p1.y) / 2
|
||||
return x, y
|
||||
end
|
||||
|
||||
--- Point class
|
||||
-- @type Point
|
||||
local Point = class()
|
||||
Point.__eq = function(a,b) return (a.x == b.x and a.y == b.y) end
|
||||
Point.__tostring = function(p)
|
||||
return ('Point (%s) x: %.2f y: %.2f'):format(p.id, p.x, p.y)
|
||||
end
|
||||
|
||||
--- Creates a new `Point`
|
||||
-- @name Point:new
|
||||
-- @param x the x-coordinate
|
||||
-- @param y the y-coordinate
|
||||
-- @return a new `Point`
|
||||
-- @usage
|
||||
-- local Delaunay = require 'Delaunay'
|
||||
-- local Point = Delaunay.Point
|
||||
-- local p = Point:new(1,1)
|
||||
-- local p = Point(1,1) -- Alias to Point.new
|
||||
-- print(p) -- print the point members x and y
|
||||
--
|
||||
function Point:__init(x, y)
|
||||
self.x, self.y, self.id = x or 0, y or 0, '?'
|
||||
end
|
||||
|
||||
--- Returns the square distance to another `Point`.
|
||||
-- @param p a `Point`
|
||||
-- @return the square distance from self to `p`.
|
||||
-- @usage
|
||||
-- local p1, p2 = Point(), Point(1,1)
|
||||
-- print(p1:dist2(p2)) --> 2
|
||||
--
|
||||
function Point:dist2(p)
|
||||
local dx, dy = (self.x - p.x), (self.y - p.y)
|
||||
return dx * dx + dy * dy
|
||||
end
|
||||
|
||||
--- Returns the distance to another `Point`.
|
||||
-- @param p a `Point`
|
||||
-- @return the distance from self to `p`.
|
||||
-- @usage
|
||||
-- local p1, p2 = Point(), Point(1,1)
|
||||
-- print(p1:dist2(p2)) --> 1.4142135623731
|
||||
--
|
||||
function Point:dist(p)
|
||||
return sqrt(self:dist2(p))
|
||||
end
|
||||
|
||||
--- Checks if self lies into the bounds of a circle
|
||||
-- @param cx the x-coordinate of the circle center
|
||||
-- @param cy the y-coordinate of the circle center
|
||||
-- @param r the radius of the circle
|
||||
-- @return `true` or `false`
|
||||
-- @usage
|
||||
-- local p = Point()
|
||||
-- print(p:isInCircle(0,0,1)) --> true
|
||||
--
|
||||
function Point:isInCircle(cx, cy, r)
|
||||
local dx = (cx - self.x)
|
||||
local dy = (cy - self.y)
|
||||
return ((dx * dx + dy * dy) <= (r * r))
|
||||
end
|
||||
|
||||
--- `Triangle` class
|
||||
-- @type Triangle
|
||||
|
||||
local Triangle = class()
|
||||
Triangle.__tostring = function(t)
|
||||
return (('Triangle: \n %s\n %s\n %s')
|
||||
:format(tostring(t.p1), tostring(t.p2), tostring(t.p3)))
|
||||
end
|
||||
|
||||
--- Creates a new `Triangle`
|
||||
-- @name Triangle:new
|
||||
-- @param p1 a `Point`
|
||||
-- @param p2 a `Point`
|
||||
-- @param p3 a `Point`
|
||||
-- @return a new `Triangle`
|
||||
-- @usage
|
||||
-- local Delaunay = require 'Delaunay'
|
||||
-- local Triangle = Delaunay.Triangle
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle:new(p1, p2, p3)
|
||||
-- local t = Triangle(p1, p2, p3) -- Alias to Triangle.new
|
||||
-- print(t) -- print the triangle members p1, p2 and p3
|
||||
--
|
||||
function Triangle:__init(p1, p2, p3)
|
||||
assert(not isFlatAngle(p1, p2, p3), ("angle (p1, p2, p3) is flat:\n %s\n %s\n %s")
|
||||
:format(tostring(p1), tostring(p2), tostring(p3)))
|
||||
self.p1, self.p2, self.p3 = p1, p2, p3
|
||||
self.e1, self.e2, self.e3 = Edge(p1, p2), Edge(p2, p3), Edge(p3, p1)
|
||||
end
|
||||
|
||||
--- Checks if the triangle is defined clockwise (sequence p1-p2-p3)
|
||||
-- @return `true` or `false`
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(1,1), Point(2,0)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:isCW()) --> true
|
||||
--
|
||||
function Triangle:isCW()
|
||||
return (crossProduct(self.p1, self.p2, self.p3) < 0)
|
||||
end
|
||||
|
||||
--- Checks if the triangle is defined counter-clockwise (sequence p1-p2-p3)
|
||||
-- @return `true` or `false`
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:isCCW()) --> true
|
||||
--
|
||||
function Triangle:isCCW()
|
||||
return (crossProduct(self.p1, self.p2, self.p3) > 0)
|
||||
end
|
||||
|
||||
--- Returns the length of the edges
|
||||
-- @return the length of the edge p1-p2
|
||||
-- @return the length of the edge p2-p3
|
||||
-- @return the length of the edge p3-p1
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getSidesLength()) --> 2 1.4142135623731 1.4142135623731
|
||||
--
|
||||
function Triangle:getSidesLength()
|
||||
return self.e1:length(), self.e2:length(), self.e3:length()
|
||||
end
|
||||
|
||||
--- Returns the coordinates of the center
|
||||
-- @return the x-coordinate of the center
|
||||
-- @return the y-coordinate of the center
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getCenter()) --> 1 0.33333333333333
|
||||
--
|
||||
function Triangle:getCenter()
|
||||
local x = (self.p1.x + self.p2.x + self.p3.x) / 3
|
||||
local y = (self.p1.y + self.p2.y + self.p3.y) / 3
|
||||
return x, y
|
||||
end
|
||||
|
||||
--- Returns the coordinates of the circumcircle center and its radius
|
||||
-- @return the x-coordinate of the circumcircle center
|
||||
-- @return the y-coordinate of the circumcircle center
|
||||
-- @return the radius of the circumcircle
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getCircumCircle()) --> 1 0 1
|
||||
--
|
||||
function Triangle:getCircumCircle()
|
||||
local x, y = self:getCircumCenter()
|
||||
local r = self:getCircumRadius()
|
||||
return x, y, r
|
||||
end
|
||||
|
||||
--- Returns the coordinates of the circumcircle center
|
||||
-- @return the x-coordinate of the circumcircle center
|
||||
-- @return the y-coordinate of the circumcircle center
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getCircumCenter()) --> 1 0
|
||||
--
|
||||
function Triangle:getCircumCenter()
|
||||
local p1, p2, p3 = self.p1, self.p2, self.p3
|
||||
local D = ( p1.x * (p2.y - p3.y) +
|
||||
p2.x * (p3.y - p1.y) +
|
||||
p3.x * (p1.y - p2.y)) * 2
|
||||
local x = (( p1.x * p1.x + p1.y * p1.y) * (p2.y - p3.y) +
|
||||
( p2.x * p2.x + p2.y * p2.y) * (p3.y - p1.y) +
|
||||
( p3.x * p3.x + p3.y * p3.y) * (p1.y - p2.y))
|
||||
local y = (( p1.x * p1.x + p1.y * p1.y) * (p3.x - p2.x) +
|
||||
( p2.x * p2.x + p2.y * p2.y) * (p1.x - p3.x) +
|
||||
( p3.x * p3.x + p3.y * p3.y) * (p2.x - p1.x))
|
||||
return (x / D), (y / D)
|
||||
end
|
||||
|
||||
--- Returns the radius of the circumcircle
|
||||
-- @return the radius of the circumcircle
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getCircumRadius()) --> 1
|
||||
--
|
||||
function Triangle:getCircumRadius()
|
||||
local a, b, c = self:getSidesLength()
|
||||
return ((a * b * c) / quatCross(a, b, c))
|
||||
end
|
||||
|
||||
--- Returns the area
|
||||
-- @return the area
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:getArea()) --> 1
|
||||
--
|
||||
function Triangle:getArea()
|
||||
local a, b, c = self:getSidesLength()
|
||||
return (quatCross(a, b, c) / 4)
|
||||
end
|
||||
|
||||
--- Checks if a given point lies into the triangle circumcircle
|
||||
-- @param p a `Point`
|
||||
-- @return `true` or `false`
|
||||
-- @usage
|
||||
-- local p1, p2, p3 = Point(), Point(2,0), Point(1,1)
|
||||
-- local t = Triangle(p1, p2, p3)
|
||||
-- print(t:inCircumCircle(Point(1,-1))) --> true
|
||||
--
|
||||
function Triangle:inCircumCircle(p)
|
||||
return p:isInCircle(self:getCircumCircle())
|
||||
end
|
||||
|
||||
--- Delaunay module
|
||||
-- @section public
|
||||
|
||||
--- Delaunay module
|
||||
-- @table Delaunay
|
||||
-- @field Point reference to the `Point` class
|
||||
-- @field Edge reference to the `Edge` class
|
||||
-- @field Triangle reference to the `Triangle` class
|
||||
-- @field _VERSION the version of the current module
|
||||
local Delaunay = {
|
||||
Point = Point,
|
||||
Edge = Edge,
|
||||
Triangle = Triangle,
|
||||
_VERSION = "0.1"
|
||||
}
|
||||
|
||||
--- Triangulates a set of given vertices
|
||||
-- @param ... a `vargarg` list of objects of type `Point`
|
||||
-- @return a set of objects of type `Triangle`
|
||||
-- @usage
|
||||
-- local Delaunay = require 'Delaunay'
|
||||
-- local Point = Delaunay.Point
|
||||
-- local p1, p2, p3, p4 = Point(), Point(2,0), Point(1,1), Point(1,-1)
|
||||
-- local triangles = Delaunay.triangulate(p1, p2, p3, p4)
|
||||
-- for i = 1, #triangles do
|
||||
-- print(triangles[i])
|
||||
-- end
|
||||
--
|
||||
function Delaunay.triangulate(...)
|
||||
local vertices = {...}
|
||||
local nvertices = #vertices
|
||||
assert(nvertices > 2, "Cannot triangulate, needs more than 3 vertices")
|
||||
if nvertices == 3 then
|
||||
return {Triangle(unpack(vertices))}
|
||||
end
|
||||
|
||||
local trmax = nvertices * 4
|
||||
|
||||
local minX, minY = vertices[1].x, vertices[1].y
|
||||
local maxX, maxY = minX, minY
|
||||
|
||||
for i = 1, #vertices do
|
||||
local vertex = vertices[i]
|
||||
vertex.id = i
|
||||
if vertex.x < minX then minX = vertex.x end
|
||||
if vertex.y < minY then minY = vertex.y end
|
||||
if vertex.x > maxX then maxX = vertex.x end
|
||||
if vertex.y > maxY then maxY = vertex.y end
|
||||
end
|
||||
|
||||
local dx, dy = maxX - minX, maxY - minY
|
||||
local deltaMax = max(dx, dy)
|
||||
local midx, midy = (minX + maxX) * 0.5, (minY + maxY) * 0.5
|
||||
|
||||
local p1 = Point(midx - 2 * deltaMax, midy - deltaMax)
|
||||
local p2 = Point(midx, midy + 2 * deltaMax)
|
||||
local p3 = Point(midx + 2 * deltaMax, midy - deltaMax)
|
||||
p1.id, p2.id, p3.id = nvertices + 1, nvertices + 2, nvertices + 3
|
||||
vertices[p1.id] = p1
|
||||
vertices[p2.id] = p2
|
||||
vertices[p3.id] = p3
|
||||
|
||||
local triangles = {}
|
||||
triangles[#triangles + 1] = Triangle(vertices[nvertices + 1],
|
||||
vertices[nvertices + 2],
|
||||
vertices[nvertices + 3]
|
||||
)
|
||||
|
||||
for i = 1, nvertices do
|
||||
|
||||
local edges = {}
|
||||
local ntriangles = #triangles
|
||||
|
||||
for j = #triangles, 1, -1 do
|
||||
local curTriangle = triangles[j]
|
||||
if curTriangle:inCircumCircle(vertices[i]) then
|
||||
edges[#edges + 1] = curTriangle.e1
|
||||
edges[#edges + 1] = curTriangle.e2
|
||||
edges[#edges + 1] = curTriangle.e3
|
||||
remove(triangles, j)
|
||||
end
|
||||
end
|
||||
|
||||
for j = #edges - 1, 1, -1 do
|
||||
for k = #edges, j + 1, -1 do
|
||||
if edges[j] and edges[k] and edges[j]:same(edges[k]) then
|
||||
remove(edges, j)
|
||||
remove(edges, k-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for j = 1, #edges do
|
||||
local n = #triangles
|
||||
assert(n <= trmax, "Generated more than needed triangles")
|
||||
triangles[n + 1] = Triangle(edges[j].p1, edges[j].p2, vertices[i])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for i = #triangles, 1, -1 do
|
||||
local triangle = triangles[i]
|
||||
if (triangle.p1.id > nvertices or
|
||||
triangle.p2.id > nvertices or
|
||||
triangle.p3.id > nvertices) then
|
||||
remove(triangles, i)
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1,3 do remove(vertices) end
|
||||
|
||||
return triangles
|
||||
|
||||
end
|
||||
|
||||
return Delaunay
|
|
@ -0,0 +1,38 @@
|
|||
local Delaunay = require ('Delaunay')
|
||||
local Point = Delaunay.Point
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
local function newPoint()
|
||||
local x, y = math.random(), math.random()
|
||||
return Point(x * 1000, y * 1000)
|
||||
end
|
||||
|
||||
local MAX_POINTS = arg[1] or 500
|
||||
local N_TESTS = arg[2] or 10
|
||||
|
||||
local function genPoints(n)
|
||||
local points = {}
|
||||
for i = 1, n do
|
||||
points[i] = newPoint()
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
local function time(f, p)
|
||||
local start_time = os.clock()
|
||||
local result = f(unpack(p))
|
||||
local duration = (os.clock() - start_time) * 1000
|
||||
assert(result~=nil, 'Unexpected output, returned nil')
|
||||
return duration
|
||||
end
|
||||
|
||||
local function main()
|
||||
for i = 1, N_TESTS do
|
||||
local p = genPoints(MAX_POINTS)
|
||||
local duration = time(Delaunay.triangulate, p)
|
||||
print(('Test %02d: triangulating %04d points in %.2f ms'):format(i, MAX_POINTS, duration))
|
||||
end
|
||||
end
|
||||
|
||||
main()
|
Loading…
Reference in New Issue