├── .gitignore ├── MIT-LICENSE ├── README.md ├── demo ├── Assets │ ├── Demo.unity │ ├── Demo.unity.meta │ ├── Unity-delaunay.meta │ ├── Unity-delaunay │ │ ├── Delaunay.meta │ │ ├── Delaunay │ │ │ ├── DelaunayHelpers.cs │ │ │ ├── DelaunayHelpers.cs.meta │ │ │ ├── Edge.cs │ │ │ ├── Edge.cs.meta │ │ │ ├── EdgeList.cs │ │ │ ├── EdgeList.cs.meta │ │ │ ├── EdgeReorderer.cs │ │ │ ├── EdgeReorderer.cs.meta │ │ │ ├── Halfedge.cs │ │ │ ├── Halfedge.cs.meta │ │ │ ├── HalfedgePriorityQueue.cs │ │ │ ├── HalfedgePriorityQueue.cs.meta │ │ │ ├── ICoord.cs │ │ │ ├── ICoord.cs.meta │ │ │ ├── LR.cs │ │ │ ├── LR.cs.meta │ │ │ ├── Site.cs │ │ │ ├── Site.cs.meta │ │ │ ├── SiteList.cs │ │ │ ├── SiteList.cs.meta │ │ │ ├── Triangle.cs │ │ │ ├── Triangle.cs.meta │ │ │ ├── Vertex.cs │ │ │ ├── Vertex.cs.meta │ │ │ ├── Voronoi.cs │ │ │ └── Voronoi.cs.meta │ │ ├── geom.meta │ │ ├── geom │ │ │ ├── Circle.cs │ │ │ ├── Circle.cs.meta │ │ │ ├── LineSegment.cs │ │ │ ├── LineSegment.cs.meta │ │ │ ├── Polygon.cs │ │ │ ├── Polygon.cs.meta │ │ │ ├── Winding.cs │ │ │ └── Winding.cs.meta │ │ ├── utils.meta │ │ └── utils │ │ │ ├── IDisposable.cs │ │ │ └── IDisposable.cs.meta │ ├── VoronoiDemo.cs │ └── VoronoiDemo.cs.meta └── ProjectSettings │ ├── AudioManager.asset │ ├── DynamicsManager.asset │ ├── EditorBuildSettings.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── NavMeshLayers.asset │ ├── NetworkManager.asset │ ├── Physics2DSettings.asset │ ├── ProjectSettings.asset │ ├── QualitySettings.asset │ ├── TagManager.asset │ └── TimeManager.asset ├── spanning_graph.png └── triangulation.png /.gitignore: -------------------------------------------------------------------------------- 1 | # =============== # 2 | # Unity generated # 3 | # =============== # 4 | Temp/ 5 | Obj/ 6 | UnityGenerated/ 7 | Library/ 8 | 9 | # ===================================== # 10 | # Visual Studio / MonoDevelop generated # 11 | # ===================================== # 12 | ExportedObj/ 13 | *.svd 14 | *.userprefs 15 | *.csproj 16 | *.pidb 17 | *.suo 18 | *.sln 19 | *.user 20 | *.unityproj 21 | *.booproj 22 | 23 | # ============ # 24 | # OS generated # 25 | # ============ # 26 | .DS_Store 27 | .DS_Store? 28 | ._* 29 | .Spotlight-V100 30 | .Trashes 31 | Icon? 32 | ehthumbs.db 33 | Thumbs.db -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Alan Shaw 2 | Unity C# Translation Copyright (c) 2014 Julian Ceipek 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is no longer maintained, but there are some great alternatives. 2 | ============== 3 | 4 | - ~~[https://github.com/adamgit/Unity-delaunay](https://github.com/adamgit/Unity-delaunay) (Fork of this project)~~ no longer available; before it was removed, it suggested Triangle.net as a good alternative 5 | - [ScrawkBlog's Delaunay Triangulation in Unity](https://scrawkblog.com/2014/06/16/delaunay-triangulation-in-unity/) 6 | - [Triangle.net Unity Port](https://github.com/Ranguna/Triangle-NET-Unity-Port) 7 | -------------------------------------------------------------------------------- /demo/Assets/Demo.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | SceneSettings: 5 | m_ObjectHideFlags: 0 6 | m_PVSData: 7 | m_PVSObjectsArray: [] 8 | m_PVSPortalsArray: [] 9 | m_OcclusionBakeSettings: 10 | smallestOccluder: 5 11 | smallestHole: .25 12 | backfaceThreshold: 100 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_Fog: 0 16 | m_FogColor: {r: .5, g: .5, b: .5, a: 1} 17 | m_FogMode: 3 18 | m_FogDensity: .00999999978 19 | m_LinearFogStart: 0 20 | m_LinearFogEnd: 300 21 | m_AmbientLight: {r: .200000003, g: .200000003, b: .200000003, a: 1} 22 | m_SkyboxMaterial: {fileID: 0} 23 | m_HaloStrength: .5 24 | m_FlareStrength: 1 25 | m_FlareFadeSpeed: 3 26 | m_HaloTexture: {fileID: 0} 27 | m_SpotCookie: {fileID: 0} 28 | m_ObjectHideFlags: 0 29 | --- !u!127 &3 30 | LevelGameManager: 31 | m_ObjectHideFlags: 0 32 | --- !u!157 &4 33 | LightmapSettings: 34 | m_ObjectHideFlags: 0 35 | m_LightProbes: {fileID: 0} 36 | m_Lightmaps: [] 37 | m_LightmapsMode: 1 38 | m_BakedColorSpace: 0 39 | m_UseDualLightmapsInForward: 0 40 | m_LightmapEditorSettings: 41 | m_Resolution: 50 42 | m_LastUsedResolution: 0 43 | m_TextureWidth: 1024 44 | m_TextureHeight: 1024 45 | m_BounceBoost: 1 46 | m_BounceIntensity: 1 47 | m_SkyLightColor: {r: .860000014, g: .930000007, b: 1, a: 1} 48 | m_SkyLightIntensity: 0 49 | m_Quality: 0 50 | m_Bounces: 1 51 | m_FinalGatherRays: 1000 52 | m_FinalGatherContrastThreshold: .0500000007 53 | m_FinalGatherGradientThreshold: 0 54 | m_FinalGatherInterpolationPoints: 15 55 | m_AOAmount: 0 56 | m_AOMaxDistance: .100000001 57 | m_AOContrast: 1 58 | m_LODSurfaceMappingDistance: 1 59 | m_Padding: 0 60 | m_TextureCompression: 0 61 | m_LockAtlas: 0 62 | --- !u!196 &5 63 | NavMeshSettings: 64 | m_ObjectHideFlags: 0 65 | m_BuildSettings: 66 | agentRadius: .5 67 | agentHeight: 2 68 | agentSlope: 45 69 | agentClimb: .400000006 70 | ledgeDropHeight: 0 71 | maxJumpAcrossDistance: 0 72 | accuratePlacement: 0 73 | minRegionArea: 2 74 | widthInaccuracy: 16.666666 75 | heightInaccuracy: 10 76 | m_NavMesh: {fileID: 0} 77 | --- !u!1 &1746107355 78 | GameObject: 79 | m_ObjectHideFlags: 0 80 | m_PrefabParentObject: {fileID: 0} 81 | m_PrefabInternal: {fileID: 0} 82 | serializedVersion: 4 83 | m_Component: 84 | - 4: {fileID: 1746107357} 85 | - 114: {fileID: 1746107356} 86 | m_Layer: 0 87 | m_Name: VoronoiDemo 88 | m_TagString: Untagged 89 | m_Icon: {fileID: 0} 90 | m_NavMeshLayer: 0 91 | m_StaticEditorFlags: 0 92 | m_IsActive: 1 93 | --- !u!114 &1746107356 94 | MonoBehaviour: 95 | m_ObjectHideFlags: 0 96 | m_PrefabParentObject: {fileID: 0} 97 | m_PrefabInternal: {fileID: 0} 98 | m_GameObject: {fileID: 1746107355} 99 | m_Enabled: 1 100 | m_EditorHideFlags: 0 101 | m_Script: {fileID: 11500000, guid: 6b8eb48d5779546089555c7b0bd5341e, type: 3} 102 | m_Name: 103 | m_EditorClassIdentifier: 104 | m_pointCount: 300 105 | --- !u!4 &1746107357 106 | Transform: 107 | m_ObjectHideFlags: 0 108 | m_PrefabParentObject: {fileID: 0} 109 | m_PrefabInternal: {fileID: 0} 110 | m_GameObject: {fileID: 1746107355} 111 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 112 | m_LocalPosition: {x: 44.6139297, y: 18.9922752, z: 0} 113 | m_LocalScale: {x: 1, y: 1, z: 1} 114 | m_Children: [] 115 | m_Father: {fileID: 0} 116 | m_RootOrder: 1 117 | --- !u!1 &2037205290 118 | GameObject: 119 | m_ObjectHideFlags: 0 120 | m_PrefabParentObject: {fileID: 0} 121 | m_PrefabInternal: {fileID: 0} 122 | serializedVersion: 4 123 | m_Component: 124 | - 4: {fileID: 2037205295} 125 | - 20: {fileID: 2037205294} 126 | - 92: {fileID: 2037205293} 127 | - 124: {fileID: 2037205292} 128 | - 81: {fileID: 2037205291} 129 | m_Layer: 0 130 | m_Name: Main Camera 131 | m_TagString: MainCamera 132 | m_Icon: {fileID: 0} 133 | m_NavMeshLayer: 0 134 | m_StaticEditorFlags: 0 135 | m_IsActive: 1 136 | --- !u!81 &2037205291 137 | AudioListener: 138 | m_ObjectHideFlags: 0 139 | m_PrefabParentObject: {fileID: 0} 140 | m_PrefabInternal: {fileID: 0} 141 | m_GameObject: {fileID: 2037205290} 142 | m_Enabled: 1 143 | --- !u!124 &2037205292 144 | Behaviour: 145 | m_ObjectHideFlags: 0 146 | m_PrefabParentObject: {fileID: 0} 147 | m_PrefabInternal: {fileID: 0} 148 | m_GameObject: {fileID: 2037205290} 149 | m_Enabled: 1 150 | --- !u!92 &2037205293 151 | Behaviour: 152 | m_ObjectHideFlags: 0 153 | m_PrefabParentObject: {fileID: 0} 154 | m_PrefabInternal: {fileID: 0} 155 | m_GameObject: {fileID: 2037205290} 156 | m_Enabled: 1 157 | --- !u!20 &2037205294 158 | Camera: 159 | m_ObjectHideFlags: 0 160 | m_PrefabParentObject: {fileID: 0} 161 | m_PrefabInternal: {fileID: 0} 162 | m_GameObject: {fileID: 2037205290} 163 | m_Enabled: 1 164 | serializedVersion: 2 165 | m_ClearFlags: 1 166 | m_BackGroundColor: {r: 0, g: 0, b: 0, a: .0196078438} 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: .300000012 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 1 177 | orthographic size: 30 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_HDR: 0 186 | m_OcclusionCulling: 1 187 | m_StereoConvergence: 10 188 | m_StereoSeparation: .0219999999 189 | --- !u!4 &2037205295 190 | Transform: 191 | m_ObjectHideFlags: 0 192 | m_PrefabParentObject: {fileID: 0} 193 | m_PrefabInternal: {fileID: 0} 194 | m_GameObject: {fileID: 2037205290} 195 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 196 | m_LocalPosition: {x: 50, y: 25, z: -10} 197 | m_LocalScale: {x: 1, y: 1, z: 1} 198 | m_Children: [] 199 | m_Father: {fileID: 0} 200 | m_RootOrder: 0 201 | -------------------------------------------------------------------------------- /demo/Assets/Demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79883178826fb4e77a1f5cda54f78635 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adf918391394e4918943cbf0bb3dd6ea 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ea91cd8b2a424a0f97e63013b752cdc 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/DelaunayHelpers.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public class Node 11 | { 12 | public static Stack pool = new Stack (); 13 | 14 | public Node parent; 15 | public int treeSize; 16 | } 17 | 18 | public enum KruskalType 19 | { 20 | MINIMUM, 21 | MAXIMUM 22 | } 23 | 24 | public static class DelaunayHelpers 25 | { 26 | public static List VisibleLineSegments (List edges) 27 | { 28 | List segments = new List (); 29 | 30 | for (int i = 0; i p1 = edge.clippedEnds [Side.LEFT]; 34 | Nullable p2 = edge.clippedEnds [Side.RIGHT]; 35 | segments.Add (new LineSegment (p1, p2)); 36 | } 37 | } 38 | 39 | return segments; 40 | } 41 | 42 | public static List SelectEdgesForSitePoint (Vector2 coord, List edgesToTest) 43 | { 44 | return edgesToTest.FindAll (delegate (Edge edge) { 45 | return ((edge.leftSite != null && edge.leftSite.Coord == coord) 46 | || (edge.rightSite != null && edge.rightSite.Coord == coord)); 47 | }); 48 | } 49 | 50 | public static List SelectNonIntersectingEdges (/*keepOutMask:BitmapData,*/List edgesToTest) 51 | { 52 | // if (keepOutMask == null) 53 | // { 54 | return edgesToTest; 55 | // } 56 | 57 | // var zeroPoint:Point = new Point(); 58 | // return edgesToTest.filter(myTest); 59 | // 60 | // function myTest(edge:Edge, index:int, vector:Vector.):Boolean 61 | // { 62 | // var delaunayLineBmp:BitmapData = edge.makeDelaunayLineBmp(); 63 | // var notIntersecting:Boolean = !(keepOutMask.hitTest(zeroPoint, 1, delaunayLineBmp, zeroPoint, 1)); 64 | // delaunayLineBmp.dispose(); 65 | // return notIntersecting; 66 | // } 67 | } 68 | 69 | public static List DelaunayLinesForEdges (List edges) 70 | { 71 | List segments = new List (); 72 | Edge edge; 73 | for (int i = 0; i < edges.Count; i++) { 74 | edge = edges [i]; 75 | segments.Add (edge.DelaunayLine ()); 76 | } 77 | return segments; 78 | } 79 | 80 | /** 81 | * Kruskal's spanning tree algorithm with union-find 82 | * Skiena: The Algorithm Design Manual, p. 196ff 83 | * Note: the sites are implied: they consist of the end points of the line segments 84 | */ 85 | public static List Kruskal (List lineSegments, KruskalType type = KruskalType.MINIMUM) 86 | { 87 | Dictionary,Node> nodes = new Dictionary,Node> (); 88 | List mst = new List (); 89 | Stack nodePool = Node.pool; 90 | 91 | switch (type) { 92 | // note that the compare functions are the reverse of what you'd expect 93 | // because (see below) we traverse the lineSegments in reverse order for speed 94 | case KruskalType.MAXIMUM: 95 | lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) { 96 | return LineSegment.CompareLengths (l1, l2); 97 | }); 98 | break; 99 | default: 100 | lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) { 101 | return LineSegment.CompareLengths_MAX (l1, l2); 102 | }); 103 | break; 104 | } 105 | 106 | for (int i = lineSegments.Count; --i > -1;) { 107 | LineSegment lineSegment = lineSegments [i]; 108 | 109 | Node node0 = null; 110 | Node rootOfSet0; 111 | if (!nodes.ContainsKey (lineSegment.p0)) { 112 | node0 = nodePool.Count > 0 ? nodePool.Pop () : new Node (); 113 | // intialize the node: 114 | rootOfSet0 = node0.parent = node0; 115 | node0.treeSize = 1; 116 | 117 | nodes [lineSegment.p0] = node0; 118 | } else { 119 | node0 = nodes [lineSegment.p0]; 120 | rootOfSet0 = Find (node0); 121 | } 122 | 123 | Node node1 = null; 124 | Node rootOfSet1; 125 | if (!nodes.ContainsKey (lineSegment.p1)) { 126 | node1 = nodePool.Count > 0 ? nodePool.Pop () : new Node (); 127 | // intialize the node: 128 | rootOfSet1 = node1.parent = node1; 129 | node1.treeSize = 1; 130 | 131 | nodes [lineSegment.p1] = node1; 132 | } else { 133 | node1 = nodes [lineSegment.p1]; 134 | rootOfSet1 = Find (node1); 135 | } 136 | 137 | if (rootOfSet0 != rootOfSet1) { // nodes not in same set 138 | mst.Add (lineSegment); 139 | 140 | // merge the two sets: 141 | int treeSize0 = rootOfSet0.treeSize; 142 | int treeSize1 = rootOfSet1.treeSize; 143 | if (treeSize0 >= treeSize1) { 144 | // set0 absorbs set1: 145 | rootOfSet1.parent = rootOfSet0; 146 | rootOfSet0.treeSize += treeSize1; 147 | } else { 148 | // set1 absorbs set0: 149 | rootOfSet0.parent = rootOfSet1; 150 | rootOfSet1.treeSize += treeSize0; 151 | } 152 | } 153 | } 154 | foreach (Node node in nodes.Values) { 155 | nodePool.Push (node); 156 | } 157 | 158 | return mst; 159 | } 160 | 161 | private static Node Find (Node node) 162 | { 163 | if (node.parent == node) { 164 | return node; 165 | } else { 166 | Node root = Find (node.parent); 167 | // this line is just to speed up subsequent finds by keeping the tree depth low: 168 | node.parent = root; 169 | return root; 170 | } 171 | } 172 | } 173 | 174 | 175 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/DelaunayHelpers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e5cf667cd9df4f68a86433bcfff21d4 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Edge.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | // import com.nodename.geom.LineSegment; 10 | // 11 | // import flash.display.BitmapData; 12 | // import flash.display.CapsStyle; 13 | // import flash.display.Graphics; 14 | // import flash.display.LineScaleMode; 15 | // import flash.display.Sprite; 16 | // import flash.geom.Point; 17 | // import flash.geom.Rectangle; 18 | // import flash.utils.Dictionary; 19 | 20 | /** 21 | * The line segment connecting the two Sites is part of the Delaunay triangulation; 22 | * the line segment connecting the two Vertices is part of the Voronoi diagram 23 | * @author ashaw 24 | * 25 | */ 26 | public sealed class Edge 27 | { 28 | private static Stack _pool = new Stack (); 29 | 30 | /** 31 | * This is the only way to create a new Edge 32 | * @param site0 33 | * @param site1 34 | * @return 35 | * 36 | */ 37 | public static Edge CreateBisectingEdge (Site site0, Site site1) 38 | { 39 | float dx, dy, absdx, absdy; 40 | float a, b, c; 41 | 42 | dx = site1.x - site0.x; 43 | dy = site1.y - site0.y; 44 | absdx = dx > 0 ? dx : -dx; 45 | absdy = dy > 0 ? dy : -dy; 46 | c = site0.x * dx + site0.y * dy + (dx * dx + dy * dy) * 0.5f; 47 | if (absdx > absdy) { 48 | a = 1.0f; 49 | b = dy / dx; 50 | c /= dx; 51 | } else { 52 | b = 1.0f; 53 | a = dx / dy; 54 | c /= dy; 55 | } 56 | 57 | Edge edge = Edge.Create (); 58 | 59 | edge.leftSite = site0; 60 | edge.rightSite = site1; 61 | site0.AddEdge (edge); 62 | site1.AddEdge (edge); 63 | 64 | edge._leftVertex = null; 65 | edge._rightVertex = null; 66 | 67 | edge.a = a; 68 | edge.b = b; 69 | edge.c = c; 70 | //trace("createBisectingEdge: a ", edge.a, "b", edge.b, "c", edge.c); 71 | 72 | return edge; 73 | } 74 | 75 | private static Edge Create () 76 | { 77 | Edge edge; 78 | if (_pool.Count > 0) { 79 | edge = _pool.Pop (); 80 | edge.Init (); 81 | } else { 82 | edge = new Edge (); 83 | } 84 | return edge; 85 | } 86 | 87 | // private static const LINESPRITE:Sprite = new Sprite(); 88 | // private static const GRAPHICS:Graphics = LINESPRITE.graphics; 89 | // 90 | // private var _delaunayLineBmp:BitmapData; 91 | // internal function get delaunayLineBmp():BitmapData 92 | // { 93 | // if (!_delaunayLineBmp) 94 | // { 95 | // _delaunayLineBmp = makeDelaunayLineBmp(); 96 | // } 97 | // return _delaunayLineBmp; 98 | // } 99 | // 100 | // // making this available to Voronoi; running out of memory in AIR so I cannot cache the bmp 101 | // internal function makeDelaunayLineBmp():BitmapData 102 | // { 103 | // var p0:Point = leftSite.coord; 104 | // var p1:Point = rightSite.coord; 105 | // 106 | // GRAPHICS.clear(); 107 | // // clear() resets line style back to undefined! 108 | // GRAPHICS.lineStyle(0, 0, 1.0, false, LineScaleMode.NONE, CapsStyle.NONE); 109 | // GRAPHICS.moveTo(p0.x, p0.y); 110 | // GRAPHICS.lineTo(p1.x, p1.y); 111 | // 112 | // var w:int = int(Math.ceil(Math.max(p0.x, p1.x))); 113 | // if (w < 1) 114 | // { 115 | // w = 1; 116 | // } 117 | // var h:int = int(Math.ceil(Math.max(p0.y, p1.y))); 118 | // if (h < 1) 119 | // { 120 | // h = 1; 121 | // } 122 | // var bmp:BitmapData = new BitmapData(w, h, true, 0); 123 | // bmp.draw(LINESPRITE); 124 | // return bmp; 125 | // } 126 | 127 | public LineSegment DelaunayLine () 128 | { 129 | // draw a line connecting the input Sites for which the edge is a bisector: 130 | return new LineSegment (leftSite.Coord, rightSite.Coord); 131 | } 132 | 133 | public LineSegment VoronoiEdge () 134 | { 135 | if (!visible) 136 | return new LineSegment (null, null); 137 | return new LineSegment (_clippedVertices [Side.LEFT], 138 | _clippedVertices [Side.RIGHT]); 139 | } 140 | 141 | private static int _nedges = 0; 142 | 143 | public static readonly Edge DELETED = new Edge (); 144 | 145 | // the equation of the edge: ax + by = c 146 | public float a, b, c; 147 | 148 | // the two Voronoi vertices that the edge connects 149 | // (if one of them is null, the edge extends to infinity) 150 | private Vertex _leftVertex; 151 | public Vertex leftVertex { 152 | get { return _leftVertex;} 153 | } 154 | private Vertex _rightVertex; 155 | public Vertex rightVertex { 156 | get { return _rightVertex;} 157 | } 158 | public Vertex Vertex (Side leftRight) 159 | { 160 | return (leftRight == Side.LEFT) ? _leftVertex : _rightVertex; 161 | } 162 | public void SetVertex (Side leftRight, Vertex v) 163 | { 164 | if (leftRight == Side.LEFT) { 165 | _leftVertex = v; 166 | } else { 167 | _rightVertex = v; 168 | } 169 | } 170 | 171 | public bool IsPartOfConvexHull () 172 | { 173 | return (_leftVertex == null || _rightVertex == null); 174 | } 175 | 176 | public float SitesDistance () 177 | { 178 | return Vector2.Distance (leftSite.Coord, rightSite.Coord); 179 | } 180 | 181 | public static int CompareSitesDistances_MAX (Edge edge0, Edge edge1) 182 | { 183 | float length0 = edge0.SitesDistance (); 184 | float length1 = edge1.SitesDistance (); 185 | if (length0 < length1) { 186 | return 1; 187 | } 188 | if (length0 > length1) { 189 | return -1; 190 | } 191 | return 0; 192 | } 193 | 194 | public static int CompareSitesDistances (Edge edge0, Edge edge1) 195 | { 196 | return - CompareSitesDistances_MAX (edge0, edge1); 197 | } 198 | 199 | // Once clipVertices() is called, this Dictionary will hold two Points 200 | // representing the clipped coordinates of the left and right ends... 201 | private Dictionary> _clippedVertices; 202 | public Dictionary> clippedEnds { 203 | get { return _clippedVertices;} 204 | } 205 | // unless the entire Edge is outside the bounds. 206 | // In that case visible will be false: 207 | public bool visible { 208 | get { return _clippedVertices != null;} 209 | } 210 | 211 | // the two input Sites for which this Edge is a bisector: 212 | private Dictionary _sites; 213 | public Site leftSite { 214 | get{ return _sites [Side.LEFT];} 215 | set{ _sites [Side.LEFT] = value;} 216 | 217 | } 218 | public Site rightSite { 219 | get { return _sites [Side.RIGHT];} 220 | set { _sites [Side.RIGHT] = value;} 221 | } 222 | 223 | public Site Site (Side leftRight) 224 | { 225 | return _sites [leftRight]; 226 | } 227 | 228 | private int _edgeIndex; 229 | 230 | public void Dispose () 231 | { 232 | // if (_delaunayLineBmp) { 233 | // _delaunayLineBmp.Dispose (); 234 | // _delaunayLineBmp = null; 235 | // } 236 | _leftVertex = null; 237 | _rightVertex = null; 238 | if (_clippedVertices != null) { 239 | _clippedVertices [Side.LEFT] = null; 240 | _clippedVertices [Side.RIGHT] = null; 241 | _clippedVertices = null; 242 | } 243 | _sites [Side.LEFT] = null; 244 | _sites [Side.RIGHT] = null; 245 | _sites = null; 246 | 247 | _pool.Push (this); 248 | } 249 | 250 | private Edge () 251 | { 252 | // if (lock != PrivateConstructorEnforcer) 253 | // { 254 | // throw new Error("Edge: constructor is private"); 255 | // } 256 | 257 | _edgeIndex = _nedges++; 258 | Init (); 259 | } 260 | 261 | private void Init () 262 | { 263 | _sites = new Dictionary (); 264 | } 265 | 266 | public override string ToString () 267 | { 268 | return "Edge " + _edgeIndex.ToString () + "; sites " + _sites [Side.LEFT].ToString () + ", " + _sites [Side.RIGHT].ToString () 269 | + "; endVertices " + ((_leftVertex != null) ? _leftVertex.vertexIndex.ToString () : "null") + ", " 270 | + ((_rightVertex != null) ? _rightVertex.vertexIndex.ToString () : "null") + "::"; 271 | } 272 | 273 | /** 274 | * Set _clippedVertices to contain the two ends of the portion of the Voronoi edge that is visible 275 | * within the bounds. If no part of the Edge falls within the bounds, leave _clippedVertices null. 276 | * @param bounds 277 | * 278 | */ 279 | public void ClipVertices (Rect bounds) 280 | { 281 | float xmin = bounds.xMin; 282 | float ymin = bounds.yMin; 283 | float xmax = bounds.xMax; 284 | float ymax = bounds.yMax; 285 | 286 | Vertex vertex0, vertex1; 287 | float x0, x1, y0, y1; 288 | 289 | if (a == 1.0 && b >= 0.0) { 290 | vertex0 = _rightVertex; 291 | vertex1 = _leftVertex; 292 | } else { 293 | vertex0 = _leftVertex; 294 | vertex1 = _rightVertex; 295 | } 296 | 297 | if (a == 1.0) { 298 | y0 = ymin; 299 | if (vertex0 != null && vertex0.y > ymin) { 300 | y0 = vertex0.y; 301 | } 302 | if (y0 > ymax) { 303 | return; 304 | } 305 | x0 = c - b * y0; 306 | 307 | y1 = ymax; 308 | if (vertex1 != null && vertex1.y < ymax) { 309 | y1 = vertex1.y; 310 | } 311 | if (y1 < ymin) { 312 | return; 313 | } 314 | x1 = c - b * y1; 315 | 316 | if ((x0 > xmax && x1 > xmax) || (x0 < xmin && x1 < xmin)) { 317 | return; 318 | } 319 | 320 | if (x0 > xmax) { 321 | x0 = xmax; 322 | y0 = (c - x0) / b; 323 | } else if (x0 < xmin) { 324 | x0 = xmin; 325 | y0 = (c - x0) / b; 326 | } 327 | 328 | if (x1 > xmax) { 329 | x1 = xmax; 330 | y1 = (c - x1) / b; 331 | } else if (x1 < xmin) { 332 | x1 = xmin; 333 | y1 = (c - x1) / b; 334 | } 335 | } else { 336 | x0 = xmin; 337 | if (vertex0 != null && vertex0.x > xmin) { 338 | x0 = vertex0.x; 339 | } 340 | if (x0 > xmax) { 341 | return; 342 | } 343 | y0 = c - a * x0; 344 | 345 | x1 = xmax; 346 | if (vertex1 != null && vertex1.x < xmax) { 347 | x1 = vertex1.x; 348 | } 349 | if (x1 < xmin) { 350 | return; 351 | } 352 | y1 = c - a * x1; 353 | 354 | if ((y0 > ymax && y1 > ymax) || (y0 < ymin && y1 < ymin)) { 355 | return; 356 | } 357 | 358 | if (y0 > ymax) { 359 | y0 = ymax; 360 | x0 = (c - y0) / a; 361 | } else if (y0 < ymin) { 362 | y0 = ymin; 363 | x0 = (c - y0) / a; 364 | } 365 | 366 | if (y1 > ymax) { 367 | y1 = ymax; 368 | x1 = (c - y1) / a; 369 | } else if (y1 < ymin) { 370 | y1 = ymin; 371 | x1 = (c - y1) / a; 372 | } 373 | } 374 | 375 | // _clippedVertices = new Dictionary(true); // XXX: Weak ref'd dict might be a problem to use standard 376 | _clippedVertices = new Dictionary> (); 377 | if (vertex0 == _leftVertex) { 378 | _clippedVertices [Side.LEFT] = new Vector2 (x0, y0); 379 | _clippedVertices [Side.RIGHT] = new Vector2 (x1, y1); 380 | } else { 381 | _clippedVertices [Side.RIGHT] = new Vector2 (x0, y0); 382 | _clippedVertices [Side.LEFT] = new Vector2 (x1, y1); 383 | } 384 | } 385 | 386 | } 387 | } 388 | 389 | //class PrivateConstructorEnforcer {} -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Edge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49202b1d309f140d6bd015a7fbce4b64 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/EdgeList.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Delaunay.Utils; 3 | 4 | namespace Delaunay 5 | { 6 | 7 | internal sealed class EdgeList: Utils.IDisposable 8 | { 9 | private float _deltax; 10 | private float _xmin; 11 | 12 | private int _hashsize; 13 | private Halfedge[] _hash; 14 | private Halfedge _leftEnd; 15 | public Halfedge leftEnd { 16 | get { return _leftEnd;} 17 | } 18 | private Halfedge _rightEnd; 19 | public Halfedge rightEnd { 20 | get { return _rightEnd;} 21 | } 22 | 23 | public void Dispose () 24 | { 25 | Halfedge halfEdge = _leftEnd; 26 | Halfedge prevHe; 27 | while (halfEdge != _rightEnd) { 28 | prevHe = halfEdge; 29 | halfEdge = halfEdge.edgeListRightNeighbor; 30 | prevHe.Dispose (); 31 | } 32 | _leftEnd = null; 33 | _rightEnd.Dispose (); 34 | _rightEnd = null; 35 | 36 | int i; 37 | for (i = 0; i < _hashsize; ++i) { 38 | _hash [i] = null; 39 | } 40 | _hash = null; 41 | } 42 | 43 | public EdgeList (float xmin, float deltax, int sqrt_nsites) 44 | { 45 | _xmin = xmin; 46 | _deltax = deltax; 47 | _hashsize = 2 * sqrt_nsites; 48 | 49 | _hash = new Halfedge[_hashsize]; 50 | 51 | // two dummy Halfedges: 52 | _leftEnd = Halfedge.CreateDummy (); 53 | _rightEnd = Halfedge.CreateDummy (); 54 | _leftEnd.edgeListLeftNeighbor = null; 55 | _leftEnd.edgeListRightNeighbor = _rightEnd; 56 | _rightEnd.edgeListLeftNeighbor = _leftEnd; 57 | _rightEnd.edgeListRightNeighbor = null; 58 | _hash [0] = _leftEnd; 59 | _hash [_hashsize - 1] = _rightEnd; 60 | } 61 | 62 | /** 63 | * Insert newHalfedge to the right of lb 64 | * @param lb 65 | * @param newHalfedge 66 | * 67 | */ 68 | public void Insert (Halfedge lb, Halfedge newHalfedge) 69 | { 70 | newHalfedge.edgeListLeftNeighbor = lb; 71 | newHalfedge.edgeListRightNeighbor = lb.edgeListRightNeighbor; 72 | lb.edgeListRightNeighbor.edgeListLeftNeighbor = newHalfedge; 73 | lb.edgeListRightNeighbor = newHalfedge; 74 | } 75 | 76 | /** 77 | * This function only removes the Halfedge from the left-right list. 78 | * We cannot dispose it yet because we are still using it. 79 | * @param halfEdge 80 | * 81 | */ 82 | public void Remove (Halfedge halfEdge) 83 | { 84 | halfEdge.edgeListLeftNeighbor.edgeListRightNeighbor = halfEdge.edgeListRightNeighbor; 85 | halfEdge.edgeListRightNeighbor.edgeListLeftNeighbor = halfEdge.edgeListLeftNeighbor; 86 | halfEdge.edge = Edge.DELETED; 87 | halfEdge.edgeListLeftNeighbor = halfEdge.edgeListRightNeighbor = null; 88 | } 89 | 90 | /** 91 | * Find the rightmost Halfedge that is still left of p 92 | * @param p 93 | * @return 94 | * 95 | */ 96 | public Halfedge EdgeListLeftNeighbor (Vector2 p) 97 | { 98 | int i, bucket; 99 | Halfedge halfEdge; 100 | 101 | /* Use hash table to get close to desired halfedge */ 102 | bucket = (int)((p.x - _xmin) / _deltax * _hashsize); 103 | if (bucket < 0) { 104 | bucket = 0; 105 | } 106 | if (bucket >= _hashsize) { 107 | bucket = _hashsize - 1; 108 | } 109 | halfEdge = GetHash (bucket); 110 | if (halfEdge == null) { 111 | for (i = 1; true; ++i) { 112 | if ((halfEdge = GetHash (bucket - i)) != null) 113 | break; 114 | if ((halfEdge = GetHash (bucket + i)) != null) 115 | break; 116 | } 117 | } 118 | /* Now search linear list of halfedges for the correct one */ 119 | if (halfEdge == leftEnd || (halfEdge != rightEnd && halfEdge.IsLeftOf (p))) { 120 | do { 121 | halfEdge = halfEdge.edgeListRightNeighbor; 122 | } while (halfEdge != rightEnd && halfEdge.IsLeftOf(p)); 123 | halfEdge = halfEdge.edgeListLeftNeighbor; 124 | } else { 125 | do { 126 | halfEdge = halfEdge.edgeListLeftNeighbor; 127 | } while (halfEdge != leftEnd && !halfEdge.IsLeftOf(p)); 128 | } 129 | 130 | /* Update hash table and reference counts */ 131 | if (bucket > 0 && bucket < _hashsize - 1) { 132 | _hash [bucket] = halfEdge; 133 | } 134 | return halfEdge; 135 | } 136 | 137 | /* Get entry from hash table, pruning any deleted nodes */ 138 | private Halfedge GetHash (int b) 139 | { 140 | Halfedge halfEdge; 141 | 142 | if (b < 0 || b >= _hashsize) { 143 | return null; 144 | } 145 | halfEdge = _hash [b]; 146 | if (halfEdge != null && halfEdge.edge == Edge.DELETED) { 147 | /* Hash table points to deleted halfedge. Patch as necessary. */ 148 | _hash [b] = null; 149 | // still can't dispose halfEdge yet! 150 | return null; 151 | } else { 152 | return halfEdge; 153 | } 154 | } 155 | 156 | } 157 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/EdgeList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f2bfd7ed370844afb774f34e1d6366a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/EdgeReorderer.cs: -------------------------------------------------------------------------------- 1 | using Delaunay.LR; 2 | using Delaunay.Utils; 3 | using System.Collections.Generic; 4 | 5 | namespace Delaunay 6 | { 7 | public enum VertexOrSite 8 | { 9 | VERTEX, 10 | SITE 11 | } 12 | 13 | sealed class EdgeReorderer: Utils.IDisposable 14 | { 15 | private List _edges; 16 | private List _edgeOrientations; 17 | public List edges { 18 | get { return _edges;} 19 | } 20 | public List edgeOrientations { 21 | get{ return _edgeOrientations;} 22 | } 23 | 24 | public EdgeReorderer (List origEdges, VertexOrSite criterion) 25 | { 26 | _edges = new List (); 27 | _edgeOrientations = new List (); 28 | if (origEdges.Count > 0) { 29 | _edges = ReorderEdges (origEdges, criterion); 30 | } 31 | } 32 | 33 | public void Dispose () 34 | { 35 | _edges = null; 36 | _edgeOrientations = null; 37 | } 38 | 39 | private List ReorderEdges (List origEdges, VertexOrSite criterion) 40 | { 41 | int i; 42 | int n = origEdges.Count; 43 | Edge edge; 44 | // we're going to reorder the edges in order of traversal 45 | bool[] done = new bool[n]; 46 | int nDone = 0; 47 | for (int j=0; j newEdges = new List (); // TODO: Switch to Deque if performance is a concern 51 | 52 | i = 0; 53 | edge = origEdges [i]; 54 | newEdges.Add (edge); 55 | _edgeOrientations.Add (Side.LEFT); 56 | ICoord firstPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite; 57 | ICoord lastPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite; 58 | 59 | if (firstPoint == Vertex.VERTEX_AT_INFINITY || lastPoint == Vertex.VERTEX_AT_INFINITY) { 60 | return new List (); 61 | } 62 | 63 | done [i] = true; 64 | ++nDone; 65 | 66 | while (nDone < n) { 67 | for (i = 1; i < n; ++i) { 68 | if (done [i]) { 69 | continue; 70 | } 71 | edge = origEdges [i]; 72 | ICoord leftPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.leftVertex : (ICoord)edge.leftSite; 73 | ICoord rightPoint = (criterion == VertexOrSite.VERTEX) ? (ICoord)edge.rightVertex : (ICoord)edge.rightSite; 74 | if (leftPoint == Vertex.VERTEX_AT_INFINITY || rightPoint == Vertex.VERTEX_AT_INFINITY) { 75 | return new List (); 76 | } 77 | if (leftPoint == lastPoint) { 78 | lastPoint = rightPoint; 79 | _edgeOrientations.Add (Side.LEFT); 80 | newEdges.Add (edge); 81 | done [i] = true; 82 | } else if (rightPoint == firstPoint) { 83 | firstPoint = leftPoint; 84 | _edgeOrientations.Insert (0, Side.LEFT); // TODO: Change datastructure if this is slow 85 | newEdges.Insert (0, edge); 86 | done [i] = true; 87 | } else if (leftPoint == firstPoint) { 88 | firstPoint = rightPoint; 89 | _edgeOrientations.Insert (0, Side.RIGHT); 90 | newEdges.Insert (0, edge); 91 | done [i] = true; 92 | } else if (rightPoint == lastPoint) { 93 | lastPoint = leftPoint; 94 | _edgeOrientations.Add (Side.RIGHT); 95 | newEdges.Add (edge); 96 | done [i] = true; 97 | } 98 | if (done [i]) { 99 | ++nDone; 100 | } 101 | } 102 | } 103 | 104 | return newEdges; 105 | } 106 | 107 | } 108 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/EdgeReorderer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6e9c0c7f4ae649678b34ec5397e4079 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Halfedge.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.LR; 5 | using Delaunay.Geo; 6 | using Delaunay.Utils; 7 | 8 | namespace Delaunay 9 | { 10 | 11 | 12 | public sealed class Halfedge: Delaunay.Utils.IDisposable 13 | { 14 | private static Stack _pool = new Stack (); 15 | public static Halfedge Create (Edge edge, Nullable lr) 16 | { 17 | if (_pool.Count > 0) { 18 | return _pool.Pop ().Init (edge, lr); 19 | } else { 20 | return new Halfedge (edge, lr); 21 | } 22 | } 23 | 24 | public static Halfedge CreateDummy () 25 | { 26 | return Create (null, null); 27 | } 28 | 29 | public Halfedge edgeListLeftNeighbor, edgeListRightNeighbor; 30 | public Halfedge nextInPriorityQueue; 31 | 32 | public Edge edge; 33 | public Nullable leftRight; 34 | public Vertex vertex; 35 | 36 | // the vertex's y-coordinate in the transformed Voronoi space V* 37 | public float ystar; 38 | 39 | public Halfedge (Edge edge = null, Nullable lr = null) 40 | { 41 | Init (edge, lr); 42 | } 43 | 44 | private Halfedge Init (Edge edge, Nullable lr) 45 | { 46 | this.edge = edge; 47 | leftRight = lr; 48 | nextInPriorityQueue = null; 49 | vertex = null; 50 | return this; 51 | } 52 | 53 | public override string ToString () 54 | { 55 | return "Halfedge (leftRight: " + leftRight.ToString () + "; vertex: " + vertex.ToString () + ")"; 56 | } 57 | 58 | public void Dispose () 59 | { 60 | if (edgeListLeftNeighbor != null || edgeListRightNeighbor != null) { 61 | // still in EdgeList 62 | return; 63 | } 64 | if (nextInPriorityQueue != null) { 65 | // still in PriorityQueue 66 | return; 67 | } 68 | edge = null; 69 | leftRight = null; 70 | vertex = null; 71 | _pool.Push (this); 72 | } 73 | 74 | public void ReallyDispose () 75 | { 76 | edgeListLeftNeighbor = null; 77 | edgeListRightNeighbor = null; 78 | nextInPriorityQueue = null; 79 | edge = null; 80 | leftRight = null; 81 | vertex = null; 82 | _pool.Push (this); 83 | } 84 | 85 | internal bool IsLeftOf (Vector2 p) 86 | { 87 | Site topSite; 88 | bool rightOfSite, above, fast; 89 | float dxp, dyp, dxs, t1, t2, t3, yl; 90 | 91 | topSite = edge.rightSite; 92 | rightOfSite = p.x > topSite.x; 93 | if (rightOfSite && this.leftRight == Side.LEFT) { 94 | return true; 95 | } 96 | if (!rightOfSite && this.leftRight == Side.RIGHT) { 97 | return false; 98 | } 99 | 100 | if (edge.a == 1.0) { 101 | dyp = p.y - topSite.y; 102 | dxp = p.x - topSite.x; 103 | fast = false; 104 | if ((!rightOfSite && edge.b < 0.0) || (rightOfSite && edge.b >= 0.0)) { 105 | above = dyp >= edge.b * dxp; 106 | fast = above; 107 | } else { 108 | above = p.x + p.y * edge.b > edge.c; 109 | if (edge.b < 0.0) { 110 | above = !above; 111 | } 112 | if (!above) { 113 | fast = true; 114 | } 115 | } 116 | if (!fast) { 117 | dxs = topSite.x - edge.leftSite.x; 118 | above = edge.b * (dxp * dxp - dyp * dyp) < 119 | dxs * dyp * (1.0 + 2.0 * dxp / dxs + edge.b * edge.b); 120 | if (edge.b < 0.0) { 121 | above = !above; 122 | } 123 | } 124 | } else { /* edge.b == 1.0 */ 125 | yl = edge.c - edge.a * p.x; 126 | t1 = p.y - yl; 127 | t2 = p.x - topSite.x; 128 | t3 = yl - topSite.y; 129 | above = t1 * t1 > t2 * t2 + t3 * t3; 130 | } 131 | return this.leftRight == Side.LEFT ? above : !above; 132 | } 133 | 134 | } 135 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Halfedge.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e873e30775b564fbd9b4b27ac5b0787a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Delaunay.Utils; 4 | 5 | namespace Delaunay 6 | { 7 | 8 | internal sealed class HalfedgePriorityQueue: Utils.IDisposable // also known as heap 9 | { 10 | private Halfedge[] _hash; 11 | private int _count; 12 | private int _minBucket; 13 | private int _hashsize; 14 | 15 | private float _ymin; 16 | private float _deltay; 17 | 18 | public HalfedgePriorityQueue (float ymin, float deltay, int sqrt_nsites) 19 | { 20 | _ymin = ymin; 21 | _deltay = deltay; 22 | _hashsize = 4 * sqrt_nsites; 23 | Initialize (); 24 | } 25 | 26 | public void Dispose () 27 | { 28 | // get rid of dummies 29 | for (int i = 0; i < _hashsize; ++i) { 30 | _hash [i].Dispose (); 31 | _hash [i] = null; 32 | } 33 | _hash = null; 34 | } 35 | 36 | private void Initialize () 37 | { 38 | int i; 39 | 40 | _count = 0; 41 | _minBucket = 0; 42 | _hash = new Halfedge[_hashsize]; 43 | // dummy Halfedge at the top of each hash 44 | for (i = 0; i < _hashsize; ++i) { 45 | _hash [i] = Halfedge.CreateDummy (); 46 | _hash [i].nextInPriorityQueue = null; 47 | } 48 | } 49 | 50 | public void Insert (Halfedge halfEdge) 51 | { 52 | Halfedge previous, next; 53 | int insertionBucket = Bucket (halfEdge); 54 | if (insertionBucket < _minBucket) { 55 | _minBucket = insertionBucket; 56 | } 57 | previous = _hash [insertionBucket]; 58 | while ((next = previous.nextInPriorityQueue) != null 59 | && (halfEdge.ystar > next.ystar || (halfEdge.ystar == next.ystar && halfEdge.vertex.x > next.vertex.x))) { 60 | previous = next; 61 | } 62 | halfEdge.nextInPriorityQueue = previous.nextInPriorityQueue; 63 | previous.nextInPriorityQueue = halfEdge; 64 | ++_count; 65 | } 66 | 67 | public void Remove (Halfedge halfEdge) 68 | { 69 | Halfedge previous; 70 | int removalBucket = Bucket (halfEdge); 71 | 72 | if (halfEdge.vertex != null) { 73 | previous = _hash [removalBucket]; 74 | while (previous.nextInPriorityQueue != halfEdge) { 75 | previous = previous.nextInPriorityQueue; 76 | } 77 | previous.nextInPriorityQueue = halfEdge.nextInPriorityQueue; 78 | _count--; 79 | halfEdge.vertex = null; 80 | halfEdge.nextInPriorityQueue = null; 81 | halfEdge.Dispose (); 82 | } 83 | } 84 | 85 | private int Bucket (Halfedge halfEdge) 86 | { 87 | int theBucket = (int)((halfEdge.ystar - _ymin) / _deltay * _hashsize); 88 | if (theBucket < 0) 89 | theBucket = 0; 90 | if (theBucket >= _hashsize) 91 | theBucket = _hashsize - 1; 92 | return theBucket; 93 | } 94 | 95 | private bool IsEmpty (int bucket) 96 | { 97 | return (_hash [bucket].nextInPriorityQueue == null); 98 | } 99 | 100 | /** 101 | * move _minBucket until it contains an actual Halfedge (not just the dummy at the top); 102 | * 103 | */ 104 | private void AdjustMinBucket () 105 | { 106 | while (_minBucket < _hashsize - 1 && IsEmpty(_minBucket)) { 107 | ++_minBucket; 108 | } 109 | } 110 | 111 | public bool Empty () 112 | { 113 | return _count == 0; 114 | } 115 | 116 | /** 117 | * @return coordinates of the Halfedge's vertex in V*, the transformed Voronoi diagram 118 | * 119 | */ 120 | public Vector2 Min () 121 | { 122 | AdjustMinBucket (); 123 | Halfedge answer = _hash [_minBucket].nextInPriorityQueue; 124 | return new Vector2 (answer.vertex.x, answer.ystar); 125 | } 126 | 127 | /** 128 | * remove and return the min Halfedge 129 | * @return 130 | * 131 | */ 132 | public Halfedge ExtractMin () 133 | { 134 | Halfedge answer; 135 | 136 | // get the first real Halfedge in _minBucket 137 | answer = _hash [_minBucket].nextInPriorityQueue; 138 | 139 | _hash [_minBucket].nextInPriorityQueue = answer.nextInPriorityQueue; 140 | _count--; 141 | answer.nextInPriorityQueue = null; 142 | 143 | return answer; 144 | } 145 | 146 | } 147 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/HalfedgePriorityQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ba85128b77e245478cd4bc1ac6c8f60 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/ICoord.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Delaunay 4 | { 5 | 6 | public interface ICoord 7 | { 8 | Vector2 Coord { 9 | get; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/ICoord.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a0a816d1340149068ec7fa5bc31c72c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/LR.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace LR 4 | { 5 | public enum Side 6 | { 7 | LEFT = 0, 8 | RIGHT 9 | } 10 | 11 | public class SideHelper 12 | { 13 | public static Side Other (Side leftRight) 14 | { 15 | return leftRight == Side.LEFT ? Side.RIGHT : Side.LEFT; 16 | } 17 | } 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/LR.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42741f042d2e748aaaf15e94b6ba71dd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Site.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.LR; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public sealed class Site: ICoord, IComparable 11 | { 12 | private static Stack _pool = new Stack (); 13 | public static Site Create (Vector2 p, uint index, float weight, uint color) 14 | { 15 | if (_pool.Count > 0) { 16 | return _pool.Pop ().Init (p, index, weight, color); 17 | } else { 18 | return new Site (p, index, weight, color); 19 | } 20 | } 21 | 22 | internal static void SortSites (List sites) 23 | { 24 | // sites.sort(Site.compare); 25 | sites.Sort (); // XXX: Check if this works 26 | } 27 | 28 | /** 29 | * sort sites on y, then x, coord 30 | * also change each site's _siteIndex to match its new position in the list 31 | * so the _siteIndex can be used to identify the site for nearest-neighbor queries 32 | * 33 | * haha "also" - means more than one responsibility... 34 | * 35 | */ 36 | public int CompareTo (System.Object obj) // XXX: Really, really worried about this because it depends on how sorting works in AS3 impl - Julian 37 | { 38 | Site s2 = (Site)obj; 39 | 40 | int returnValue = Voronoi.CompareByYThenX (this, s2); 41 | 42 | // swap _siteIndex values if necessary to match new ordering: 43 | uint tempIndex; 44 | if (returnValue == -1) { 45 | if (this._siteIndex > s2._siteIndex) { 46 | tempIndex = this._siteIndex; 47 | this._siteIndex = s2._siteIndex; 48 | s2._siteIndex = tempIndex; 49 | } 50 | } else if (returnValue == 1) { 51 | if (s2._siteIndex > this._siteIndex) { 52 | tempIndex = s2._siteIndex; 53 | s2._siteIndex = this._siteIndex; 54 | this._siteIndex = tempIndex; 55 | } 56 | 57 | } 58 | 59 | return returnValue; 60 | } 61 | 62 | 63 | private static readonly float EPSILON = .005f; 64 | private static bool CloseEnough (Vector2 p0, Vector2 p1) 65 | { 66 | return Vector2.Distance (p0, p1) < EPSILON; 67 | } 68 | 69 | private Vector2 _coord; 70 | public Vector2 Coord { 71 | get { return _coord;} 72 | } 73 | 74 | public uint color; 75 | public float weight; 76 | 77 | private uint _siteIndex; 78 | 79 | // the edges that define this Site's Voronoi region: 80 | private List _edges; 81 | internal List edges { 82 | get { return _edges;} 83 | } 84 | // which end of each edge hooks up with the previous edge in _edges: 85 | private List _edgeOrientations; 86 | // ordered list of points that define the region clipped to bounds: 87 | private List _region; 88 | 89 | private Site (Vector2 p, uint index, float weight, uint color) 90 | { 91 | // if (lock != PrivateConstructorEnforcer) 92 | // { 93 | // throw new Error("Site constructor is private"); 94 | // } 95 | Init (p, index, weight, color); 96 | } 97 | 98 | private Site Init (Vector2 p, uint index, float weight, uint color) 99 | { 100 | _coord = p; 101 | _siteIndex = index; 102 | this.weight = weight; 103 | this.color = color; 104 | _edges = new List (); 105 | _region = null; 106 | return this; 107 | } 108 | 109 | public override string ToString () 110 | { 111 | return "Site " + _siteIndex.ToString () + ": " + Coord.ToString (); 112 | } 113 | 114 | private void Move (Vector2 p) 115 | { 116 | Clear (); 117 | _coord = p; 118 | } 119 | 120 | public void Dispose () 121 | { 122 | // _coord = null; 123 | Clear (); 124 | _pool.Push (this); 125 | } 126 | 127 | private void Clear () 128 | { 129 | if (_edges != null) { 130 | _edges.Clear (); 131 | _edges = null; 132 | } 133 | if (_edgeOrientations != null) { 134 | _edgeOrientations.Clear (); 135 | _edgeOrientations = null; 136 | } 137 | if (_region != null) { 138 | _region.Clear (); 139 | _region = null; 140 | } 141 | } 142 | 143 | public void AddEdge (Edge edge) 144 | { 145 | _edges.Add (edge); 146 | } 147 | 148 | public Edge NearestEdge () 149 | { 150 | _edges.Sort (delegate (Edge a, Edge b) { 151 | return Edge.CompareSitesDistances (a, b); 152 | }); 153 | return _edges [0]; 154 | } 155 | 156 | public List NeighborSites () 157 | { 158 | if (_edges == null || _edges.Count == 0) { 159 | return new List (); 160 | } 161 | if (_edgeOrientations == null) { 162 | ReorderEdges (); 163 | } 164 | List list = new List (); 165 | Edge edge; 166 | for (int i = 0; i < _edges.Count; i++) { 167 | edge = _edges [i]; 168 | list.Add (NeighborSite (edge)); 169 | } 170 | return list; 171 | } 172 | 173 | private Site NeighborSite (Edge edge) 174 | { 175 | if (this == edge.leftSite) { 176 | return edge.rightSite; 177 | } 178 | if (this == edge.rightSite) { 179 | return edge.leftSite; 180 | } 181 | return null; 182 | } 183 | 184 | internal List Region (Rect clippingBounds) 185 | { 186 | if (_edges == null || _edges.Count == 0) { 187 | return new List (); 188 | } 189 | if (_edgeOrientations == null) { 190 | ReorderEdges (); 191 | _region = ClipToBounds (clippingBounds); 192 | if ((new Polygon (_region)).Winding () == Winding.CLOCKWISE) { 193 | _region.Reverse (); 194 | } 195 | } 196 | return _region; 197 | } 198 | 199 | private void ReorderEdges () 200 | { 201 | //trace("_edges:", _edges); 202 | EdgeReorderer reorderer = new EdgeReorderer (_edges, VertexOrSite.VERTEX); 203 | _edges = reorderer.edges; 204 | //trace("reordered:", _edges); 205 | _edgeOrientations = reorderer.edgeOrientations; 206 | reorderer.Dispose (); 207 | } 208 | 209 | private List ClipToBounds (Rect bounds) 210 | { 211 | List points = new List (); 212 | int n = _edges.Count; 213 | int i = 0; 214 | Edge edge; 215 | while (i < n && ((_edges[i] as Edge).visible == false)) { 216 | ++i; 217 | } 218 | 219 | if (i == n) { 220 | // no edges visible 221 | return new List (); 222 | } 223 | edge = _edges [i]; 224 | Side orientation = _edgeOrientations [i]; 225 | 226 | if (edge.clippedEnds [orientation] == null) { 227 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 228 | } 229 | if (edge.clippedEnds [SideHelper.Other (orientation)] == null) { 230 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 231 | } 232 | points.Add ((Vector2)edge.clippedEnds [orientation]); 233 | points.Add ((Vector2)edge.clippedEnds [SideHelper.Other (orientation)]); 234 | 235 | for (int j = i + 1; j < n; ++j) { 236 | edge = _edges [j]; 237 | if (edge.visible == false) { 238 | continue; 239 | } 240 | Connect (points, j, bounds); 241 | } 242 | // close up the polygon by adding another corner point of the bounds if needed: 243 | Connect (points, i, bounds, true); 244 | 245 | return points; 246 | } 247 | 248 | private void Connect (List points, int j, Rect bounds, bool closingUp = false) 249 | { 250 | Vector2 rightPoint = points [points.Count - 1]; 251 | Edge newEdge = _edges [j] as Edge; 252 | Side newOrientation = _edgeOrientations [j]; 253 | // the point that must be connected to rightPoint: 254 | if (newEdge.clippedEnds [newOrientation] == null) { 255 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 256 | } 257 | Vector2 newPoint = (Vector2)newEdge.clippedEnds [newOrientation]; 258 | if (!CloseEnough (rightPoint, newPoint)) { 259 | // The points do not coincide, so they must have been clipped at the bounds; 260 | // see if they are on the same border of the bounds: 261 | if (rightPoint.x != newPoint.x 262 | && rightPoint.y != newPoint.y) { 263 | // They are on different borders of the bounds; 264 | // insert one or two corners of bounds as needed to hook them up: 265 | // (NOTE this will not be correct if the region should take up more than 266 | // half of the bounds rect, for then we will have gone the wrong way 267 | // around the bounds and included the smaller part rather than the larger) 268 | int rightCheck = BoundsCheck.Check (rightPoint, bounds); 269 | int newCheck = BoundsCheck.Check (newPoint, bounds); 270 | float px, py; 271 | if ((rightCheck & BoundsCheck.RIGHT) != 0) { 272 | px = bounds.xMax; 273 | if ((newCheck & BoundsCheck.BOTTOM) != 0) { 274 | py = bounds.yMax; 275 | points.Add (new Vector2 (px, py)); 276 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 277 | py = bounds.yMin; 278 | points.Add (new Vector2 (px, py)); 279 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 280 | if (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) { 281 | py = bounds.yMin; 282 | } else { 283 | py = bounds.yMax; 284 | } 285 | points.Add (new Vector2 (px, py)); 286 | points.Add (new Vector2 (bounds.xMin, py)); 287 | } 288 | } else if ((rightCheck & BoundsCheck.LEFT) != 0) { 289 | px = bounds.xMin; 290 | if ((newCheck & BoundsCheck.BOTTOM) != 0) { 291 | py = bounds.yMax; 292 | points.Add (new Vector2 (px, py)); 293 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 294 | py = bounds.yMin; 295 | points.Add (new Vector2 (px, py)); 296 | } else if ((newCheck & BoundsCheck.RIGHT) != 0) { 297 | if (rightPoint.y - bounds.y + newPoint.y - bounds.y < bounds.height) { 298 | py = bounds.yMin; 299 | } else { 300 | py = bounds.yMax; 301 | } 302 | points.Add (new Vector2 (px, py)); 303 | points.Add (new Vector2 (bounds.xMax, py)); 304 | } 305 | } else if ((rightCheck & BoundsCheck.TOP) != 0) { 306 | py = bounds.yMin; 307 | if ((newCheck & BoundsCheck.RIGHT) != 0) { 308 | px = bounds.xMax; 309 | points.Add (new Vector2 (px, py)); 310 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 311 | px = bounds.xMin; 312 | points.Add (new Vector2 (px, py)); 313 | } else if ((newCheck & BoundsCheck.BOTTOM) != 0) { 314 | if (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) { 315 | px = bounds.xMin; 316 | } else { 317 | px = bounds.xMax; 318 | } 319 | points.Add (new Vector2 (px, py)); 320 | points.Add (new Vector2 (px, bounds.yMax)); 321 | } 322 | } else if ((rightCheck & BoundsCheck.BOTTOM) != 0) { 323 | py = bounds.yMax; 324 | if ((newCheck & BoundsCheck.RIGHT) != 0) { 325 | px = bounds.xMax; 326 | points.Add (new Vector2 (px, py)); 327 | } else if ((newCheck & BoundsCheck.LEFT) != 0) { 328 | px = bounds.xMin; 329 | points.Add (new Vector2 (px, py)); 330 | } else if ((newCheck & BoundsCheck.TOP) != 0) { 331 | if (rightPoint.x - bounds.x + newPoint.x - bounds.x < bounds.width) { 332 | px = bounds.xMin; 333 | } else { 334 | px = bounds.xMax; 335 | } 336 | points.Add (new Vector2 (px, py)); 337 | points.Add (new Vector2 (px, bounds.yMin)); 338 | } 339 | } 340 | } 341 | if (closingUp) { 342 | // newEdge's ends have already been added 343 | return; 344 | } 345 | points.Add (newPoint); 346 | } 347 | if (newEdge.clippedEnds [SideHelper.Other (newOrientation)] == null) { 348 | Debug.LogError ("XXX: Null detected when there should be a Vector2!"); 349 | } 350 | Vector2 newRightPoint = (Vector2)newEdge.clippedEnds [SideHelper.Other (newOrientation)]; 351 | if (!CloseEnough (points [0], newRightPoint)) { 352 | points.Add (newRightPoint); 353 | } 354 | } 355 | 356 | public float x { 357 | get { return _coord.x;} 358 | } 359 | internal float y { 360 | get { return _coord.y;} 361 | } 362 | 363 | public float Dist (ICoord p) 364 | { 365 | return Vector2.Distance (p.Coord, this._coord); 366 | } 367 | 368 | } 369 | } 370 | 371 | // class PrivateConstructorEnforcer {} 372 | 373 | // import flash.geom.Point; 374 | // import flash.geom.Rectangle; 375 | 376 | static class BoundsCheck 377 | { 378 | public static readonly int TOP = 1; 379 | public static readonly int BOTTOM = 2; 380 | public static readonly int LEFT = 4; 381 | public static readonly int RIGHT = 8; 382 | 383 | /** 384 | * 385 | * @param point 386 | * @param bounds 387 | * @return an int with the appropriate bits set if the Point lies on the corresponding bounds lines 388 | * 389 | */ 390 | public static int Check (Vector2 point, Rect bounds) 391 | { 392 | int value = 0; 393 | if (point.x == bounds.xMin) { 394 | value |= LEFT; 395 | } 396 | if (point.x == bounds.xMax) { 397 | value |= RIGHT; 398 | } 399 | if (point.y == bounds.yMin) { 400 | value |= TOP; 401 | } 402 | if (point.y == bounds.yMax) { 403 | value |= BOTTOM; 404 | } 405 | return value; 406 | } 407 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Site.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa5d818389dce40d29f97fb47bf83081 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/SiteList.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.Geo; 5 | using Delaunay.Utils; 6 | 7 | namespace Delaunay 8 | { 9 | 10 | public sealed class SiteList: Utils.IDisposable 11 | { 12 | private List _sites; 13 | private int _currentIndex; 14 | 15 | private bool _sorted; 16 | 17 | public SiteList () 18 | { 19 | _sites = new List (); 20 | _sorted = false; 21 | } 22 | 23 | public void Dispose () 24 | { 25 | if (_sites != null) { 26 | for (int i = 0; i < _sites.Count; i++) { 27 | Site site = _sites [i]; 28 | site.Dispose (); 29 | } 30 | _sites.Clear (); 31 | _sites = null; 32 | } 33 | } 34 | 35 | public int Add (Site site) 36 | { 37 | _sorted = false; 38 | _sites.Add (site); 39 | return _sites.Count; 40 | } 41 | 42 | public int Count { 43 | get { return _sites.Count;} 44 | } 45 | 46 | public Site Next () 47 | { 48 | if (_sorted == false) { 49 | UnityEngine.Debug.LogError ("SiteList::next(): sites have not been sorted"); 50 | } 51 | if (_currentIndex < _sites.Count) { 52 | return _sites [_currentIndex++]; 53 | } else { 54 | return null; 55 | } 56 | } 57 | 58 | internal Rect GetSitesBounds () 59 | { 60 | if (_sorted == false) { 61 | Site.SortSites (_sites); 62 | _currentIndex = 0; 63 | _sorted = true; 64 | } 65 | float xmin, xmax, ymin, ymax; 66 | if (_sites.Count == 0) { 67 | return new Rect (0, 0, 0, 0); 68 | } 69 | xmin = float.MaxValue; 70 | xmax = float.MinValue; 71 | for (int i = 0; i<_sites.Count; i++) { 72 | Site site = _sites [i]; 73 | if (site.x < xmin) { 74 | xmin = site.x; 75 | } 76 | if (site.x > xmax) { 77 | xmax = site.x; 78 | } 79 | } 80 | // here's where we assume that the sites have been sorted on y: 81 | ymin = _sites [0].y; 82 | ymax = _sites [_sites.Count - 1].y; 83 | 84 | return new Rect (xmin, ymin, xmax - xmin, ymax - ymin); 85 | } 86 | 87 | public List SiteColors (/*BitmapData referenceImage = null*/) 88 | { 89 | List colors = new List (); 90 | Site site; 91 | for (int i = 0; i< _sites.Count; i++) { 92 | site = _sites [i]; 93 | colors.Add (/*referenceImage ? referenceImage.getPixel(site.x, site.y) :*/site.color); 94 | } 95 | return colors; 96 | } 97 | 98 | public List SiteCoords () 99 | { 100 | List coords = new List (); 101 | Site site; 102 | for (int i = 0; i<_sites.Count; i++) { 103 | site = _sites [i]; 104 | coords.Add (site.Coord); 105 | } 106 | return coords; 107 | } 108 | 109 | /** 110 | * 111 | * @return the largest circle centered at each site that fits in its region; 112 | * if the region is infinite, return a circle of radius 0. 113 | * 114 | */ 115 | public List Circles () 116 | { 117 | List circles = new List (); 118 | Site site; 119 | for (int i = 0; i<_sites.Count; i++) { 120 | site = _sites [i]; 121 | float radius = 0f; 122 | Edge nearestEdge = site.NearestEdge (); 123 | 124 | if (!nearestEdge.IsPartOfConvexHull ()) { 125 | radius = nearestEdge.SitesDistance () * 0.5f; 126 | } 127 | circles.Add (new Circle (site.x, site.y, radius)); 128 | } 129 | return circles; 130 | } 131 | 132 | public List> Regions (Rect plotBounds) 133 | { 134 | List> regions = new List> (); 135 | Site site; 136 | for (int i = 0; i< _sites.Count; i++) { 137 | site = _sites [i]; 138 | regions.Add (site.Region (plotBounds)); 139 | } 140 | return regions; 141 | } 142 | 143 | /** 144 | * 145 | * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions() 146 | * @param x 147 | * @param y 148 | * @return coordinates of nearest Site to (x, y) 149 | * 150 | */ 151 | public Nullable NearestSitePoint (/*proximityMap:BitmapData,*/float x, float y) 152 | { 153 | // uint index = proximityMap.getPixel(x, y); 154 | // if (index > _sites.length - 1) 155 | // { 156 | return null; 157 | // } 158 | // return _sites[index].coord; 159 | } 160 | 161 | } 162 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/SiteList.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d11fa694a445f4fbb9c6ef8f51d7d549 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Triangle.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Delaunay.Utils; 3 | 4 | namespace Delaunay 5 | { 6 | 7 | public sealed class Triangle: IDisposable 8 | { 9 | private List _sites; 10 | public List sites { 11 | get { return this._sites; } 12 | } 13 | 14 | public Triangle (Site a, Site b, Site c) 15 | { 16 | _sites = new List () { a, b, c }; 17 | } 18 | 19 | public void Dispose () 20 | { 21 | _sites.Clear (); 22 | _sites = null; 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Triangle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c86ee3287678f413e99d8256fcbbbd6f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Vertex.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | using Delaunay.LR; 5 | 6 | namespace Delaunay 7 | { 8 | 9 | public sealed class Vertex: ICoord 10 | { 11 | public static readonly Vertex VERTEX_AT_INFINITY = new Vertex (float.NaN, float.NaN); 12 | 13 | private static Stack _pool = new Stack (); 14 | private static Vertex Create (float x, float y) 15 | { 16 | if (float.IsNaN (x) || float.IsNaN (y)) { 17 | return VERTEX_AT_INFINITY; 18 | } 19 | if (_pool.Count > 0) { 20 | return _pool.Pop ().Init (x, y); 21 | } else { 22 | return new Vertex (x, y); 23 | } 24 | } 25 | 26 | 27 | private static int _nvertices = 0; 28 | 29 | private Vector2 _coord; 30 | public Vector2 Coord { 31 | get { return _coord;} 32 | } 33 | private int _vertexIndex; 34 | public int vertexIndex { 35 | get { return _vertexIndex;} 36 | } 37 | 38 | public Vertex (float x, float y) 39 | { 40 | Init (x, y); 41 | } 42 | 43 | private Vertex Init (float x, float y) 44 | { 45 | _coord = new Vector2 (x, y); 46 | return this; 47 | } 48 | 49 | public void Dispose () 50 | { 51 | _pool.Push (this); 52 | } 53 | 54 | public void SetIndex () 55 | { 56 | _vertexIndex = _nvertices++; 57 | } 58 | 59 | public override string ToString () 60 | { 61 | return "Vertex (" + _vertexIndex + ")"; 62 | } 63 | 64 | /** 65 | * This is the only way to make a Vertex 66 | * 67 | * @param halfedge0 68 | * @param halfedge1 69 | * @return 70 | * 71 | */ 72 | public static Vertex Intersect (Halfedge halfedge0, Halfedge halfedge1) 73 | { 74 | Edge edge0, edge1, edge; 75 | Halfedge halfedge; 76 | float determinant, intersectionX, intersectionY; 77 | bool rightOfSite; 78 | 79 | edge0 = halfedge0.edge; 80 | edge1 = halfedge1.edge; 81 | if (edge0 == null || edge1 == null) { 82 | return null; 83 | } 84 | if (edge0.rightSite == edge1.rightSite) { 85 | return null; 86 | } 87 | 88 | determinant = edge0.a * edge1.b - edge0.b * edge1.a; 89 | if (-1.0e-10 < determinant && determinant < 1.0e-10) { 90 | // the edges are parallel 91 | return null; 92 | } 93 | 94 | intersectionX = (edge0.c * edge1.b - edge1.c * edge0.b) / determinant; 95 | intersectionY = (edge1.c * edge0.a - edge0.c * edge1.a) / determinant; 96 | 97 | if (Voronoi.CompareByYThenX (edge0.rightSite, edge1.rightSite) < 0) { 98 | halfedge = halfedge0; 99 | edge = edge0; 100 | } else { 101 | halfedge = halfedge1; 102 | edge = edge1; 103 | } 104 | rightOfSite = intersectionX >= edge.rightSite.x; 105 | if ((rightOfSite && halfedge.leftRight == Side.LEFT) 106 | || (!rightOfSite && halfedge.leftRight == Side.RIGHT)) { 107 | return null; 108 | } 109 | 110 | return Vertex.Create (intersectionX, intersectionY); 111 | } 112 | 113 | public float x { 114 | get { return _coord.x;} 115 | } 116 | public float y { 117 | get{ return _coord.y;} 118 | } 119 | 120 | } 121 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Vertex.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 16e154efbeed043e1865a7d95f623368 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Voronoi.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * The author of this software is Steven Fortune. Copyright (c) 1994 by AT&T 3 | * Bell Laboratories. 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose without fee is hereby granted, provided that this entire notice 6 | * is included in all copies of any software which is or includes a copy 7 | * or modification of this software and in all copies of the supporting 8 | * documentation for such software. 9 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 10 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY 11 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 12 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 13 | */ 14 | 15 | using UnityEngine; 16 | using System; 17 | using System.Collections.Generic; 18 | using Delaunay.Geo; 19 | using Delaunay.Utils; 20 | using Delaunay.LR; 21 | 22 | namespace Delaunay 23 | { 24 | public sealed class Voronoi: Utils.IDisposable 25 | { 26 | private SiteList _sites; 27 | private Dictionary _sitesIndexedByLocation; 28 | private List _triangles; 29 | private List _edges; 30 | 31 | 32 | // TODO generalize this so it doesn't have to be a rectangle; 33 | // then we can make the fractal voronois-within-voronois 34 | private Rect _plotBounds; 35 | public Rect plotBounds { 36 | get { return _plotBounds;} 37 | } 38 | 39 | public void Dispose () 40 | { 41 | int i, n; 42 | if (_sites != null) { 43 | _sites.Dispose (); 44 | _sites = null; 45 | } 46 | if (_triangles != null) { 47 | n = _triangles.Count; 48 | for (i = 0; i < n; ++i) { 49 | _triangles [i].Dispose (); 50 | } 51 | _triangles.Clear (); 52 | _triangles = null; 53 | } 54 | if (_edges != null) { 55 | n = _edges.Count; 56 | for (i = 0; i < n; ++i) { 57 | _edges [i].Dispose (); 58 | } 59 | _edges.Clear (); 60 | _edges = null; 61 | } 62 | // _plotBounds = null; 63 | _sitesIndexedByLocation = null; 64 | } 65 | 66 | public Voronoi (List points, List colors, Rect plotBounds) 67 | { 68 | _sites = new SiteList (); 69 | _sitesIndexedByLocation = new Dictionary (); // XXX: Used to be Dictionary(true) -- weak refs. 70 | AddSites (points, colors); 71 | _plotBounds = plotBounds; 72 | _triangles = new List (); 73 | _edges = new List (); 74 | FortunesAlgorithm (); 75 | } 76 | 77 | private void AddSites (List points, List colors) 78 | { 79 | int length = points.Count; 80 | for (int i = 0; i < length; ++i) { 81 | AddSite (points [i], (colors != null) ? colors [i] : 0, i); 82 | } 83 | } 84 | 85 | private void AddSite (Vector2 p, uint color, int index) 86 | { 87 | if (_sitesIndexedByLocation.ContainsKey (p)) 88 | return; // Prevent duplicate site! (Adapted from https://github.com/nodename/as3delaunay/issues/1) 89 | float weight = UnityEngine.Random.value * 100f; 90 | Site site = Site.Create (p, (uint)index, weight, color); 91 | _sites.Add (site); 92 | _sitesIndexedByLocation [p] = site; 93 | } 94 | 95 | public List Edges () 96 | { 97 | return _edges; 98 | } 99 | 100 | public List Region (Vector2 p) 101 | { 102 | Site site = _sitesIndexedByLocation [p]; 103 | if (site == null) { 104 | return new List (); 105 | } 106 | return site.Region (_plotBounds); 107 | } 108 | 109 | // TODO: bug: if you call this before you call region(), something goes wrong :( 110 | public List NeighborSitesForSite (Vector2 coord) 111 | { 112 | List points = new List (); 113 | Site site = _sitesIndexedByLocation [coord]; 114 | if (site == null) { 115 | return points; 116 | } 117 | List sites = site.NeighborSites (); 118 | Site neighbor; 119 | for (int nIndex =0; nIndex Circles () 127 | { 128 | return _sites.Circles (); 129 | } 130 | 131 | public List VoronoiBoundaryForSite (Vector2 coord) 132 | { 133 | return DelaunayHelpers.VisibleLineSegments (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges)); 134 | } 135 | 136 | public List DelaunayLinesForSite (Vector2 coord) 137 | { 138 | return DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectEdgesForSitePoint (coord, _edges)); 139 | } 140 | 141 | public List VoronoiDiagram () 142 | { 143 | return DelaunayHelpers.VisibleLineSegments (_edges); 144 | } 145 | 146 | public List DelaunayTriangulation (/*BitmapData keepOutMask = null*/) 147 | { 148 | return DelaunayHelpers.DelaunayLinesForEdges (DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges)); 149 | } 150 | 151 | public List Hull () 152 | { 153 | return DelaunayHelpers.DelaunayLinesForEdges (HullEdges ()); 154 | } 155 | 156 | private List HullEdges () 157 | { 158 | return _edges.FindAll (delegate (Edge edge) { 159 | return (edge.IsPartOfConvexHull ()); 160 | }); 161 | } 162 | 163 | public List HullPointsInOrder () 164 | { 165 | List hullEdges = HullEdges (); 166 | 167 | List points = new List (); 168 | if (hullEdges.Count == 0) { 169 | return points; 170 | } 171 | 172 | EdgeReorderer reorderer = new EdgeReorderer (hullEdges, VertexOrSite.SITE); 173 | hullEdges = reorderer.edges; 174 | List orientations = reorderer.edgeOrientations; 175 | reorderer.Dispose (); 176 | 177 | Side orientation; 178 | 179 | int n = hullEdges.Count; 180 | for (int i = 0; i < n; ++i) { 181 | Edge edge = hullEdges [i]; 182 | orientation = orientations [i]; 183 | points.Add (edge.Site (orientation).Coord); 184 | } 185 | return points; 186 | } 187 | 188 | public List SpanningTree (KruskalType type = KruskalType.MINIMUM/*, BitmapData keepOutMask = null*/) 189 | { 190 | List edges = DelaunayHelpers.SelectNonIntersectingEdges (/*keepOutMask,*/_edges); 191 | List segments = DelaunayHelpers.DelaunayLinesForEdges (edges); 192 | return DelaunayHelpers.Kruskal (segments, type); 193 | } 194 | 195 | public List> Regions () 196 | { 197 | return _sites.Regions (_plotBounds); 198 | } 199 | 200 | public List SiteColors (/*BitmapData referenceImage = null*/) 201 | { 202 | return _sites.SiteColors (/*referenceImage*/); 203 | } 204 | 205 | /** 206 | * 207 | * @param proximityMap a BitmapData whose regions are filled with the site index values; see PlanePointsCanvas::fillRegions() 208 | * @param x 209 | * @param y 210 | * @return coordinates of nearest Site to (x, y) 211 | * 212 | */ 213 | public Nullable NearestSitePoint (/*BitmapData proximityMap,*/float x, float y) 214 | { 215 | return _sites.NearestSitePoint (/*proximityMap,*/x, y); 216 | } 217 | 218 | public List SiteCoords () 219 | { 220 | return _sites.SiteCoords (); 221 | } 222 | 223 | private Site fortunesAlgorithm_bottomMostSite; 224 | private void FortunesAlgorithm () 225 | { 226 | Site newSite, bottomSite, topSite, tempSite; 227 | Vertex v, vertex; 228 | Vector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian 229 | Side leftRight; 230 | Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; 231 | Edge edge; 232 | 233 | Rect dataBounds = _sites.GetSitesBounds (); 234 | 235 | int sqrt_nsites = (int)(Mathf.Sqrt (_sites.Count + 4)); 236 | HalfedgePriorityQueue heap = new HalfedgePriorityQueue (dataBounds.y, dataBounds.height, sqrt_nsites); 237 | EdgeList edgeList = new EdgeList (dataBounds.x, dataBounds.width, sqrt_nsites); 238 | List halfEdges = new List (); 239 | List vertices = new List (); 240 | 241 | fortunesAlgorithm_bottomMostSite = _sites.Next (); 242 | newSite = _sites.Next (); 243 | 244 | for (;;) { 245 | if (heap.Empty () == false) { 246 | newintstar = heap.Min (); 247 | } 248 | 249 | if (newSite != null 250 | && (heap.Empty () || CompareByYThenX (newSite, newintstar) < 0)) { 251 | /* new site is smallest */ 252 | //trace("smallest: new site " + newSite); 253 | 254 | // Step 8: 255 | lbnd = edgeList.EdgeListLeftNeighbor (newSite.Coord); // the Halfedge just to the left of newSite 256 | //trace("lbnd: " + lbnd); 257 | rbnd = lbnd.edgeListRightNeighbor; // the Halfedge just to the right 258 | //trace("rbnd: " + rbnd); 259 | bottomSite = FortunesAlgorithm_rightRegion (lbnd); // this is the same as leftRegion(rbnd) 260 | // this Site determines the region containing the new site 261 | //trace("new Site is in region of existing site: " + bottomSite); 262 | 263 | // Step 9: 264 | edge = Edge.CreateBisectingEdge (bottomSite, newSite); 265 | //trace("new edge: " + edge); 266 | _edges.Add (edge); 267 | 268 | bisector = Halfedge.Create (edge, Side.LEFT); 269 | halfEdges.Add (bisector); 270 | // inserting two Halfedges into edgeList constitutes Step 10: 271 | // insert bisector to the right of lbnd: 272 | edgeList.Insert (lbnd, bisector); 273 | 274 | // first half of Step 11: 275 | if ((vertex = Vertex.Intersect (lbnd, bisector)) != null) { 276 | vertices.Add (vertex); 277 | heap.Remove (lbnd); 278 | lbnd.vertex = vertex; 279 | lbnd.ystar = vertex.y + newSite.Dist (vertex); 280 | heap.Insert (lbnd); 281 | } 282 | 283 | lbnd = bisector; 284 | bisector = Halfedge.Create (edge, Side.RIGHT); 285 | halfEdges.Add (bisector); 286 | // second Halfedge for Step 10: 287 | // insert bisector to the right of lbnd: 288 | edgeList.Insert (lbnd, bisector); 289 | 290 | // second half of Step 11: 291 | if ((vertex = Vertex.Intersect (bisector, rbnd)) != null) { 292 | vertices.Add (vertex); 293 | bisector.vertex = vertex; 294 | bisector.ystar = vertex.y + newSite.Dist (vertex); 295 | heap.Insert (bisector); 296 | } 297 | 298 | newSite = _sites.Next (); 299 | } else if (heap.Empty () == false) { 300 | /* intersection is smallest */ 301 | lbnd = heap.ExtractMin (); 302 | llbnd = lbnd.edgeListLeftNeighbor; 303 | rbnd = lbnd.edgeListRightNeighbor; 304 | rrbnd = rbnd.edgeListRightNeighbor; 305 | bottomSite = FortunesAlgorithm_leftRegion (lbnd); 306 | topSite = FortunesAlgorithm_rightRegion (rbnd); 307 | // these three sites define a Delaunay triangle 308 | // (not actually using these for anything...) 309 | //_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd))); 310 | 311 | v = lbnd.vertex; 312 | v.SetIndex (); 313 | lbnd.edge.SetVertex ((Side)lbnd.leftRight, v); 314 | rbnd.edge.SetVertex ((Side)rbnd.leftRight, v); 315 | edgeList.Remove (lbnd); 316 | heap.Remove (rbnd); 317 | edgeList.Remove (rbnd); 318 | leftRight = Side.LEFT; 319 | if (bottomSite.y > topSite.y) { 320 | tempSite = bottomSite; 321 | bottomSite = topSite; 322 | topSite = tempSite; 323 | leftRight = Side.RIGHT; 324 | } 325 | edge = Edge.CreateBisectingEdge (bottomSite, topSite); 326 | _edges.Add (edge); 327 | bisector = Halfedge.Create (edge, leftRight); 328 | halfEdges.Add (bisector); 329 | edgeList.Insert (llbnd, bisector); 330 | edge.SetVertex (SideHelper.Other (leftRight), v); 331 | if ((vertex = Vertex.Intersect (llbnd, bisector)) != null) { 332 | vertices.Add (vertex); 333 | heap.Remove (llbnd); 334 | llbnd.vertex = vertex; 335 | llbnd.ystar = vertex.y + bottomSite.Dist (vertex); 336 | heap.Insert (llbnd); 337 | } 338 | if ((vertex = Vertex.Intersect (bisector, rrbnd)) != null) { 339 | vertices.Add (vertex); 340 | bisector.vertex = vertex; 341 | bisector.ystar = vertex.y + bottomSite.Dist (vertex); 342 | heap.Insert (bisector); 343 | } 344 | } else { 345 | break; 346 | } 347 | } 348 | 349 | // heap should be empty now 350 | heap.Dispose (); 351 | edgeList.Dispose (); 352 | 353 | for (int hIndex = 0; hIndex s2.y) 395 | return 1; 396 | if (s1.x < s2.x) 397 | return -1; 398 | if (s1.x > s2.x) 399 | return 1; 400 | return 0; 401 | } 402 | 403 | public static int CompareByYThenX (Site s1, Vector2 s2) 404 | { 405 | if (s1.y < s2.y) 406 | return -1; 407 | if (s1.y > s2.y) 408 | return 1; 409 | if (s1.x < s2.x) 410 | return -1; 411 | if (s1.x > s2.x) 412 | return 1; 413 | return 0; 414 | } 415 | 416 | } 417 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/Delaunay/Voronoi.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a659b037ca774ad4b255ac68dbe65ae 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ee5f0dcc71544e1dade82ac72f7fc3d 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Circle.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class Circle 9 | { 10 | public Vector2 center; 11 | public float radius; 12 | 13 | public Circle (float centerX, float centerY, float radius) 14 | { 15 | this.center = new Vector2 (centerX, centerY); 16 | this.radius = radius; 17 | } 18 | 19 | public override string ToString () 20 | { 21 | return "Circle (center: " + center.ToString () + "; radius: " + radius.ToString () + ")"; 22 | } 23 | 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Circle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5300884d68b94e1c958b6328944dcca 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/LineSegment.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class LineSegment 9 | { 10 | public static int CompareLengths_MAX (LineSegment segment0, LineSegment segment1) 11 | { 12 | float length0 = Vector2.Distance ((Vector2)segment0.p0, (Vector2)segment0.p1); 13 | float length1 = Vector2.Distance ((Vector2)segment1.p0, (Vector2)segment1.p1); 14 | if (length0 < length1) { 15 | return 1; 16 | } 17 | if (length0 > length1) { 18 | return -1; 19 | } 20 | return 0; 21 | } 22 | 23 | public static int CompareLengths (LineSegment edge0, LineSegment edge1) 24 | { 25 | return - CompareLengths_MAX (edge0, edge1); 26 | } 27 | 28 | public Nullable p0; 29 | public Nullable p1; 30 | 31 | public LineSegment (Nullable p0, Nullable p1) 32 | { 33 | this.p0 = p0; 34 | this.p1 = p1; 35 | } 36 | 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/LineSegment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 76312350a2abb4fa9a9926fc7da2287d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Polygon.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace Delaunay 5 | { 6 | namespace Geo 7 | { 8 | public sealed class Polygon 9 | { 10 | private List _vertices; 11 | 12 | public Polygon (List vertices) 13 | { 14 | _vertices = vertices; 15 | } 16 | 17 | public float Area () 18 | { 19 | return Mathf.Abs (SignedDoubleArea () * 0.5f); // XXX: I'm a bit nervous about this; not sure what the * 0.5 is for, bithacking? 20 | } 21 | 22 | public Winding Winding () 23 | { 24 | float signedDoubleArea = SignedDoubleArea (); 25 | if (signedDoubleArea < 0) { 26 | return Geo.Winding.CLOCKWISE; 27 | } 28 | if (signedDoubleArea > 0) { 29 | return Geo.Winding.COUNTERCLOCKWISE; 30 | } 31 | return Geo.Winding.NONE; 32 | } 33 | 34 | private float SignedDoubleArea () // XXX: I'm a bit nervous about this because Actionscript represents everything as doubles, not floats 35 | { 36 | int index, nextIndex; 37 | int n = _vertices.Count; 38 | Vector2 point, next; 39 | float signedDoubleArea = 0; // Losing lots of precision? 40 | for (index = 0; index < n; ++index) { 41 | nextIndex = (index + 1) % n; 42 | point = _vertices [index]; 43 | next = _vertices [nextIndex]; 44 | signedDoubleArea += point.x * next.y - next.x * point.y; 45 | } 46 | return signedDoubleArea; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Polygon.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e59bb833c9cf045e992b44a5e23837cb 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Winding.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace Geo { 4 | public enum Winding 5 | { 6 | NONE = 0, CLOCKWISE, COUNTERCLOCKWISE 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/geom/Winding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a38f1425b42547898d3b2ef6c865e05 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6505f93572a1d41a38b2f1aeee65897b 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/utils/IDisposable.cs: -------------------------------------------------------------------------------- 1 | namespace Delaunay 2 | { 3 | namespace Utils 4 | { 5 | public interface IDisposable 6 | { 7 | void Dispose (); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /demo/Assets/Unity-delaunay/utils/IDisposable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7cb01ead474dc485fa87ef0e202dcc6d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/Assets/VoronoiDemo.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Delaunay; 4 | using Delaunay.Geo; 5 | 6 | public class VoronoiDemo : MonoBehaviour 7 | { 8 | [SerializeField] 9 | private int 10 | m_pointCount = 300; 11 | 12 | private List m_points; 13 | private float m_mapWidth = 100; 14 | private float m_mapHeight = 50; 15 | private List m_edges = null; 16 | private List m_spanningTree; 17 | private List m_delaunayTriangulation; 18 | 19 | void Awake () 20 | { 21 | Demo (); 22 | } 23 | 24 | void Update () 25 | { 26 | if (Input.anyKeyDown) { 27 | Demo (); 28 | } 29 | } 30 | 31 | private void Demo () 32 | { 33 | 34 | List colors = new List (); 35 | m_points = new List (); 36 | 37 | for (int i = 0; i < m_pointCount; i++) { 38 | colors.Add (0); 39 | m_points.Add (new Vector2 ( 40 | UnityEngine.Random.Range (0, m_mapWidth), 41 | UnityEngine.Random.Range (0, m_mapHeight)) 42 | ); 43 | } 44 | Delaunay.Voronoi v = new Delaunay.Voronoi (m_points, colors, new Rect (0, 0, m_mapWidth, m_mapHeight)); 45 | m_edges = v.VoronoiDiagram (); 46 | 47 | m_spanningTree = v.SpanningTree (KruskalType.MINIMUM); 48 | m_delaunayTriangulation = v.DelaunayTriangulation (); 49 | } 50 | 51 | void OnDrawGizmos () 52 | { 53 | Gizmos.color = Color.red; 54 | if (m_points != null) { 55 | for (int i = 0; i < m_points.Count; i++) { 56 | Gizmos.DrawSphere (m_points [i], 0.2f); 57 | } 58 | } 59 | 60 | if (m_edges != null) { 61 | Gizmos.color = Color.white; 62 | for (int i = 0; i< m_edges.Count; i++) { 63 | Vector2 left = (Vector2)m_edges [i].p0; 64 | Vector2 right = (Vector2)m_edges [i].p1; 65 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 66 | } 67 | } 68 | 69 | Gizmos.color = Color.magenta; 70 | if (m_delaunayTriangulation != null) { 71 | for (int i = 0; i< m_delaunayTriangulation.Count; i++) { 72 | Vector2 left = (Vector2)m_delaunayTriangulation [i].p0; 73 | Vector2 right = (Vector2)m_delaunayTriangulation [i].p1; 74 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 75 | } 76 | } 77 | 78 | if (m_spanningTree != null) { 79 | Gizmos.color = Color.green; 80 | for (int i = 0; i< m_spanningTree.Count; i++) { 81 | LineSegment seg = m_spanningTree [i]; 82 | Vector2 left = (Vector2)seg.p0; 83 | Vector2 right = (Vector2)seg.p1; 84 | Gizmos.DrawLine ((Vector3)left, (Vector3)right); 85 | } 86 | } 87 | 88 | Gizmos.color = Color.yellow; 89 | Gizmos.DrawLine (new Vector2 (0, 0), new Vector2 (0, m_mapHeight)); 90 | Gizmos.DrawLine (new Vector2 (0, 0), new Vector2 (m_mapWidth, 0)); 91 | Gizmos.DrawLine (new Vector2 (m_mapWidth, 0), new Vector2 (m_mapWidth, m_mapHeight)); 92 | Gizmos.DrawLine (new Vector2 (0, m_mapHeight), new Vector2 (m_mapWidth, m_mapHeight)); 93 | } 94 | } -------------------------------------------------------------------------------- /demo/Assets/VoronoiDemo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6b8eb48d5779546089555c7b0bd5341e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /demo/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | m_SpeedOfSound: 347 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_DSPBufferSize: 0 12 | m_DisableAudio: 0 13 | -------------------------------------------------------------------------------- /demo/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042, z: 0} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_BounceThreshold: 2 9 | m_SleepVelocity: .150000006 10 | m_SleepAngularVelocity: .140000001 11 | m_MaxAngularVelocity: 7 12 | m_MinPenetrationForPenalty: .00999999978 13 | m_SolverIterationCount: 6 14 | m_RaycastsHitTriggers: 1 15 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 16 | -------------------------------------------------------------------------------- /demo/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: [] 8 | -------------------------------------------------------------------------------- /demo/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_ExternalVersionControlSupport: Hidden Meta Files 8 | m_SerializationMode: 2 9 | m_WebSecurityEmulationEnabled: 0 10 | m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d 11 | m_DefaultBehaviorMode: 1 12 | m_SpritePackerMode: 0 13 | -------------------------------------------------------------------------------- /demo/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | m_AlwaysIncludedShaders: 7 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 8 | -------------------------------------------------------------------------------- /demo/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | m_Axes: 7 | - serializedVersion: 3 8 | m_Name: Horizontal 9 | descriptiveName: 10 | descriptiveNegativeName: 11 | negativeButton: left 12 | positiveButton: right 13 | altNegativeButton: a 14 | altPositiveButton: d 15 | gravity: 3 16 | dead: .00100000005 17 | sensitivity: 3 18 | snap: 1 19 | invert: 0 20 | type: 0 21 | axis: 0 22 | joyNum: 0 23 | - serializedVersion: 3 24 | m_Name: Vertical 25 | descriptiveName: 26 | descriptiveNegativeName: 27 | negativeButton: down 28 | positiveButton: up 29 | altNegativeButton: s 30 | altPositiveButton: w 31 | gravity: 3 32 | dead: .00100000005 33 | sensitivity: 3 34 | snap: 1 35 | invert: 0 36 | type: 0 37 | axis: 0 38 | joyNum: 0 39 | - serializedVersion: 3 40 | m_Name: Fire1 41 | descriptiveName: 42 | descriptiveNegativeName: 43 | negativeButton: 44 | positiveButton: left ctrl 45 | altNegativeButton: 46 | altPositiveButton: mouse 0 47 | gravity: 1000 48 | dead: .00100000005 49 | sensitivity: 1000 50 | snap: 0 51 | invert: 0 52 | type: 0 53 | axis: 0 54 | joyNum: 0 55 | - serializedVersion: 3 56 | m_Name: Fire2 57 | descriptiveName: 58 | descriptiveNegativeName: 59 | negativeButton: 60 | positiveButton: left alt 61 | altNegativeButton: 62 | altPositiveButton: mouse 1 63 | gravity: 1000 64 | dead: .00100000005 65 | sensitivity: 1000 66 | snap: 0 67 | invert: 0 68 | type: 0 69 | axis: 0 70 | joyNum: 0 71 | - serializedVersion: 3 72 | m_Name: Fire3 73 | descriptiveName: 74 | descriptiveNegativeName: 75 | negativeButton: 76 | positiveButton: left cmd 77 | altNegativeButton: 78 | altPositiveButton: mouse 2 79 | gravity: 1000 80 | dead: .00100000005 81 | sensitivity: 1000 82 | snap: 0 83 | invert: 0 84 | type: 0 85 | axis: 0 86 | joyNum: 0 87 | - serializedVersion: 3 88 | m_Name: Jump 89 | descriptiveName: 90 | descriptiveNegativeName: 91 | negativeButton: 92 | positiveButton: space 93 | altNegativeButton: 94 | altPositiveButton: 95 | gravity: 1000 96 | dead: .00100000005 97 | sensitivity: 1000 98 | snap: 0 99 | invert: 0 100 | type: 0 101 | axis: 0 102 | joyNum: 0 103 | - serializedVersion: 3 104 | m_Name: Mouse X 105 | descriptiveName: 106 | descriptiveNegativeName: 107 | negativeButton: 108 | positiveButton: 109 | altNegativeButton: 110 | altPositiveButton: 111 | gravity: 0 112 | dead: 0 113 | sensitivity: .100000001 114 | snap: 0 115 | invert: 0 116 | type: 1 117 | axis: 0 118 | joyNum: 0 119 | - serializedVersion: 3 120 | m_Name: Mouse Y 121 | descriptiveName: 122 | descriptiveNegativeName: 123 | negativeButton: 124 | positiveButton: 125 | altNegativeButton: 126 | altPositiveButton: 127 | gravity: 0 128 | dead: 0 129 | sensitivity: .100000001 130 | snap: 0 131 | invert: 0 132 | type: 1 133 | axis: 1 134 | joyNum: 0 135 | - serializedVersion: 3 136 | m_Name: Mouse ScrollWheel 137 | descriptiveName: 138 | descriptiveNegativeName: 139 | negativeButton: 140 | positiveButton: 141 | altNegativeButton: 142 | altPositiveButton: 143 | gravity: 0 144 | dead: 0 145 | sensitivity: .100000001 146 | snap: 0 147 | invert: 0 148 | type: 1 149 | axis: 2 150 | joyNum: 0 151 | - serializedVersion: 3 152 | m_Name: Horizontal 153 | descriptiveName: 154 | descriptiveNegativeName: 155 | negativeButton: 156 | positiveButton: 157 | altNegativeButton: 158 | altPositiveButton: 159 | gravity: 0 160 | dead: .189999998 161 | sensitivity: 1 162 | snap: 0 163 | invert: 0 164 | type: 2 165 | axis: 0 166 | joyNum: 0 167 | - serializedVersion: 3 168 | m_Name: Vertical 169 | descriptiveName: 170 | descriptiveNegativeName: 171 | negativeButton: 172 | positiveButton: 173 | altNegativeButton: 174 | altPositiveButton: 175 | gravity: 0 176 | dead: .189999998 177 | sensitivity: 1 178 | snap: 0 179 | invert: 1 180 | type: 2 181 | axis: 1 182 | joyNum: 0 183 | - serializedVersion: 3 184 | m_Name: Fire1 185 | descriptiveName: 186 | descriptiveNegativeName: 187 | negativeButton: 188 | positiveButton: joystick button 0 189 | altNegativeButton: 190 | altPositiveButton: 191 | gravity: 1000 192 | dead: .00100000005 193 | sensitivity: 1000 194 | snap: 0 195 | invert: 0 196 | type: 0 197 | axis: 0 198 | joyNum: 0 199 | - serializedVersion: 3 200 | m_Name: Fire2 201 | descriptiveName: 202 | descriptiveNegativeName: 203 | negativeButton: 204 | positiveButton: joystick button 1 205 | altNegativeButton: 206 | altPositiveButton: 207 | gravity: 1000 208 | dead: .00100000005 209 | sensitivity: 1000 210 | snap: 0 211 | invert: 0 212 | type: 0 213 | axis: 0 214 | joyNum: 0 215 | - serializedVersion: 3 216 | m_Name: Fire3 217 | descriptiveName: 218 | descriptiveNegativeName: 219 | negativeButton: 220 | positiveButton: joystick button 2 221 | altNegativeButton: 222 | altPositiveButton: 223 | gravity: 1000 224 | dead: .00100000005 225 | sensitivity: 1000 226 | snap: 0 227 | invert: 0 228 | type: 0 229 | axis: 0 230 | joyNum: 0 231 | - serializedVersion: 3 232 | m_Name: Jump 233 | descriptiveName: 234 | descriptiveNegativeName: 235 | negativeButton: 236 | positiveButton: joystick button 3 237 | altNegativeButton: 238 | altPositiveButton: 239 | gravity: 1000 240 | dead: .00100000005 241 | sensitivity: 1000 242 | snap: 0 243 | invert: 0 244 | type: 0 245 | axis: 0 246 | joyNum: 0 247 | -------------------------------------------------------------------------------- /demo/ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshLayers: 5 | m_ObjectHideFlags: 0 6 | Built-in Layer 0: 7 | name: Default 8 | cost: 1 9 | editType: 2 10 | Built-in Layer 1: 11 | name: Not Walkable 12 | cost: 1 13 | editType: 0 14 | Built-in Layer 2: 15 | name: Jump 16 | cost: 2 17 | editType: 2 18 | User Layer 0: 19 | name: 20 | cost: 1 21 | editType: 3 22 | User Layer 1: 23 | name: 24 | cost: 1 25 | editType: 3 26 | User Layer 2: 27 | name: 28 | cost: 1 29 | editType: 3 30 | User Layer 3: 31 | name: 32 | cost: 1 33 | editType: 3 34 | User Layer 4: 35 | name: 36 | cost: 1 37 | editType: 3 38 | User Layer 5: 39 | name: 40 | cost: 1 41 | editType: 3 42 | User Layer 6: 43 | name: 44 | cost: 1 45 | editType: 3 46 | User Layer 7: 47 | name: 48 | cost: 1 49 | editType: 3 50 | User Layer 8: 51 | name: 52 | cost: 1 53 | editType: 3 54 | User Layer 9: 55 | name: 56 | cost: 1 57 | editType: 3 58 | User Layer 10: 59 | name: 60 | cost: 1 61 | editType: 3 62 | User Layer 11: 63 | name: 64 | cost: 1 65 | editType: 3 66 | User Layer 12: 67 | name: 68 | cost: 1 69 | editType: 3 70 | User Layer 13: 71 | name: 72 | cost: 1 73 | editType: 3 74 | User Layer 14: 75 | name: 76 | cost: 1 77 | editType: 3 78 | User Layer 15: 79 | name: 80 | cost: 1 81 | editType: 3 82 | User Layer 16: 83 | name: 84 | cost: 1 85 | editType: 3 86 | User Layer 17: 87 | name: 88 | cost: 1 89 | editType: 3 90 | User Layer 18: 91 | name: 92 | cost: 1 93 | editType: 3 94 | User Layer 19: 95 | name: 96 | cost: 1 97 | editType: 3 98 | User Layer 20: 99 | name: 100 | cost: 1 101 | editType: 3 102 | User Layer 21: 103 | name: 104 | cost: 1 105 | editType: 3 106 | User Layer 22: 107 | name: 108 | cost: 1 109 | editType: 3 110 | User Layer 23: 111 | name: 112 | cost: 1 113 | editType: 3 114 | User Layer 24: 115 | name: 116 | cost: 1 117 | editType: 3 118 | User Layer 25: 119 | name: 120 | cost: 1 121 | editType: 3 122 | User Layer 26: 123 | name: 124 | cost: 1 125 | editType: 3 126 | User Layer 27: 127 | name: 128 | cost: 1 129 | editType: 3 130 | User Layer 28: 131 | name: 132 | cost: 1 133 | editType: 3 134 | -------------------------------------------------------------------------------- /demo/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /demo/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_VelocityIterations: 8 9 | m_PositionIterations: 3 10 | m_VelocityThreshold: 1 11 | m_MaxLinearCorrection: .200000003 12 | m_MaxAngularCorrection: 8 13 | m_MaxTranslationSpeed: 100 14 | m_MaxRotationSpeed: 360 15 | m_BaumgarteScale: .200000003 16 | m_BaumgarteTimeOfImpactScale: .75 17 | m_TimeToSleep: .5 18 | m_LinearSleepTolerance: .00999999978 19 | m_AngularSleepTolerance: 2 20 | m_RaycastsHitTriggers: 1 21 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 22 | -------------------------------------------------------------------------------- /demo/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | AndroidProfiler: 0 8 | defaultScreenOrientation: 0 9 | targetDevice: 2 10 | targetGlesGraphics: 1 11 | targetResolution: 0 12 | accelerometerFrequency: 60 13 | companyName: DefaultCompany 14 | productName: demo 15 | defaultCursor: {fileID: 0} 16 | cursorHotspot: {x: 0, y: 0} 17 | defaultScreenWidth: 1024 18 | defaultScreenHeight: 768 19 | defaultScreenWidthWeb: 960 20 | defaultScreenHeightWeb: 600 21 | m_RenderingPath: 1 22 | m_MobileRenderingPath: 1 23 | m_ActiveColorSpace: 0 24 | m_MTRendering: 1 25 | m_MobileMTRendering: 0 26 | m_UseDX11: 1 27 | m_Stereoscopic3D: 0 28 | iosShowActivityIndicatorOnLoading: -1 29 | androidShowActivityIndicatorOnLoading: -1 30 | displayResolutionDialog: 1 31 | allowedAutorotateToPortrait: 1 32 | allowedAutorotateToPortraitUpsideDown: 1 33 | allowedAutorotateToLandscapeRight: 1 34 | allowedAutorotateToLandscapeLeft: 1 35 | useOSAutorotation: 1 36 | use32BitDisplayBuffer: 1 37 | use24BitDepthBuffer: 1 38 | defaultIsFullScreen: 1 39 | defaultIsNativeResolution: 1 40 | runInBackground: 0 41 | captureSingleScreen: 0 42 | Override IPod Music: 0 43 | Prepare IOS For Recording: 0 44 | enableHWStatistics: 1 45 | usePlayerLog: 1 46 | stripPhysics: 0 47 | forceSingleInstance: 0 48 | resizableWindow: 0 49 | useMacAppStoreValidation: 0 50 | gpuSkinning: 0 51 | xboxPIXTextureCapture: 0 52 | xboxEnableAvatar: 0 53 | xboxEnableKinect: 0 54 | xboxEnableKinectAutoTracking: 0 55 | xboxEnableFitness: 0 56 | macFullscreenMode: 2 57 | xboxSpeechDB: 0 58 | xboxEnableHeadOrientation: 0 59 | xboxEnableGuest: 0 60 | videoMemoryForVertexBuffers: 0 61 | m_SupportedAspectRatios: 62 | 4:3: 1 63 | 5:4: 1 64 | 16:10: 1 65 | 16:9: 1 66 | Others: 1 67 | iPhoneBundleIdentifier: com.Company.ProductName 68 | metroEnableIndependentInputSource: 0 69 | metroEnableLowLatencyPresentationAPI: 0 70 | productGUID: 0af961f893b0243a1953a65081cbafc9 71 | iPhoneBundleVersion: 1.0 72 | AndroidBundleVersionCode: 1 73 | AndroidMinSdkVersion: 9 74 | AndroidPreferredInstallLocation: 1 75 | aotOptions: 76 | apiCompatibilityLevel: 2 77 | iPhoneStrippingLevel: 0 78 | iPhoneScriptCallOptimization: 0 79 | ForceInternetPermission: 0 80 | ForceSDCardPermission: 0 81 | CreateWallpaper: 0 82 | APKExpansionFiles: 0 83 | StripUnusedMeshComponents: 0 84 | iPhoneSdkVersion: 988 85 | iPhoneTargetOSVersion: 16 86 | uIPrerenderedIcon: 0 87 | uIRequiresPersistentWiFi: 0 88 | uIStatusBarHidden: 1 89 | uIExitOnSuspend: 0 90 | uIStatusBarStyle: 0 91 | iPhoneSplashScreen: {fileID: 0} 92 | iPhoneHighResSplashScreen: {fileID: 0} 93 | iPhoneTallHighResSplashScreen: {fileID: 0} 94 | iPadPortraitSplashScreen: {fileID: 0} 95 | iPadHighResPortraitSplashScreen: {fileID: 0} 96 | iPadLandscapeSplashScreen: {fileID: 0} 97 | iPadHighResLandscapeSplashScreen: {fileID: 0} 98 | AndroidTargetDevice: 0 99 | AndroidSplashScreenScale: 0 100 | AndroidKeystoreName: 101 | AndroidKeyaliasName: 102 | resolutionDialogBanner: {fileID: 0} 103 | m_BuildTargetIcons: [] 104 | m_BuildTargetBatching: [] 105 | webPlayerTemplate: APPLICATION:Default 106 | m_TemplateCustomTags: {} 107 | XboxTitleId: 108 | XboxImageXexPath: 109 | XboxSpaPath: 110 | XboxGenerateSpa: 0 111 | XboxDeployKinectResources: 0 112 | XboxSplashScreen: {fileID: 0} 113 | xboxEnableSpeech: 0 114 | xboxAdditionalTitleMemorySize: 0 115 | xboxDeployKinectHeadOrientation: 0 116 | xboxDeployKinectHeadPosition: 0 117 | ps3TitleConfigPath: 118 | ps3DLCConfigPath: 119 | ps3ThumbnailPath: 120 | ps3BackgroundPath: 121 | ps3SoundPath: 122 | ps3TrophyCommId: 123 | ps3NpCommunicationPassphrase: 124 | ps3TrophyPackagePath: 125 | ps3BootCheckMaxSaveGameSizeKB: 128 126 | ps3TrophyCommSig: 127 | ps3SaveGameSlots: 1 128 | ps3TrialMode: 0 129 | psp2Splashimage: {fileID: 0} 130 | psp2LiveAreaGate: {fileID: 0} 131 | psp2LiveAreaBackround: {fileID: 0} 132 | psp2NPTrophyPackPath: 133 | psp2NPCommsID: 134 | psp2NPCommsPassphrase: 135 | psp2NPCommsSig: 136 | psp2ParamSfxPath: 137 | psp2PackagePassword: 138 | psp2DLCConfigPath: 139 | psp2ThumbnailPath: 140 | psp2BackgroundPath: 141 | psp2SoundPath: 142 | psp2TrophyCommId: 143 | psp2TrophyPackagePath: 144 | psp2PackagedResourcesPath: 145 | flashStrippingLevel: 2 146 | spritePackerPolicy: 147 | scriptingDefineSymbols: {} 148 | metroPackageName: demo 149 | metroPackageLogo: 150 | metroPackageLogo140: 151 | metroPackageLogo180: 152 | metroPackageVersion: 153 | metroCertificatePath: 154 | metroCertificatePassword: 155 | metroCertificateSubject: 156 | metroCertificateIssuer: 157 | metroCertificateNotAfter: 0000000000000000 158 | metroApplicationDescription: demo 159 | metroTileLogo80: 160 | metroTileLogo: 161 | metroTileLogo140: 162 | metroTileLogo180: 163 | metroTileWideLogo80: 164 | metroTileWideLogo: 165 | metroTileWideLogo140: 166 | metroTileWideLogo180: 167 | metroTileSmallLogo80: 168 | metroTileSmallLogo: 169 | metroTileSmallLogo140: 170 | metroTileSmallLogo180: 171 | metroSmallTile80: 172 | metroSmallTile: 173 | metroSmallTile140: 174 | metroSmallTile180: 175 | metroLargeTile80: 176 | metroLargeTile: 177 | metroLargeTile140: 178 | metroLargeTile180: 179 | metroTileShortName: 180 | metroCommandLineArgsFile: 181 | metroTileShowName: 0 182 | metroMediumTileShowName: 0 183 | metroLargeTileShowName: 0 184 | metroWideTileShowName: 0 185 | metroDefaultTileSize: 1 186 | metroTileForegroundText: 1 187 | metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 188 | metroSplashScreenImage: 189 | metroSplashScreenImage140: 190 | metroSplashScreenImage180: 191 | metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 192 | metroSplashScreenUseBackgroundColor: 0 193 | metroCapabilities: {} 194 | metroUnprocessedPlugins: [] 195 | metroCompilationOverrides: 1 196 | blackberryDeviceAddress: 197 | blackberryDevicePassword: 198 | blackberryTokenPath: 199 | blackberryTokenExires: 200 | blackberryTokenAuthor: 201 | blackberryTokenAuthorId: 202 | blackberryAuthorId: 203 | blackberryCskPassword: 204 | blackberrySaveLogPath: 205 | blackberryAuthorIdOveride: 0 206 | blackberrySharedPermissions: 0 207 | blackberryCameraPermissions: 0 208 | blackberryGPSPermissions: 0 209 | blackberryDeviceIDPermissions: 0 210 | blackberryMicrophonePermissions: 0 211 | blackberryGamepadSupport: 0 212 | blackberryBuildId: 0 213 | blackberryLandscapeSplashScreen: {fileID: 0} 214 | blackberryPortraitSplashScreen: {fileID: 0} 215 | blackberrySquareSplashScreen: {fileID: 0} 216 | tizenProductDescription: 217 | tizenProductURL: 218 | tizenCertificatePath: 219 | tizenCertificatePassword: 220 | tizenGPSPermissions: 0 221 | tizenMicrophonePermissions: 0 222 | stvDeviceAddress: 223 | firstStreamedLevelWithResources: 0 224 | unityRebuildLibraryVersion: 9 225 | unityForwardCompatibleVersion: 39 226 | unityStandardAssetsVersion: 0 227 | -------------------------------------------------------------------------------- /demo/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 3 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | blendWeights: 1 18 | textureQuality: 1 19 | anisotropicTextures: 0 20 | antiAliasing: 0 21 | softParticles: 0 22 | softVegetation: 0 23 | vSyncCount: 0 24 | lodBias: .300000012 25 | maximumLODLevel: 0 26 | particleRaycastBudget: 4 27 | excludedTargetPlatforms: [] 28 | - serializedVersion: 2 29 | name: Fast 30 | pixelLightCount: 0 31 | shadows: 0 32 | shadowResolution: 0 33 | shadowProjection: 1 34 | shadowCascades: 1 35 | shadowDistance: 20 36 | blendWeights: 2 37 | textureQuality: 0 38 | anisotropicTextures: 0 39 | antiAliasing: 0 40 | softParticles: 0 41 | softVegetation: 0 42 | vSyncCount: 0 43 | lodBias: .400000006 44 | maximumLODLevel: 0 45 | particleRaycastBudget: 16 46 | excludedTargetPlatforms: [] 47 | - serializedVersion: 2 48 | name: Simple 49 | pixelLightCount: 1 50 | shadows: 1 51 | shadowResolution: 0 52 | shadowProjection: 1 53 | shadowCascades: 1 54 | shadowDistance: 20 55 | blendWeights: 2 56 | textureQuality: 0 57 | anisotropicTextures: 1 58 | antiAliasing: 0 59 | softParticles: 0 60 | softVegetation: 0 61 | vSyncCount: 0 62 | lodBias: .699999988 63 | maximumLODLevel: 0 64 | particleRaycastBudget: 64 65 | excludedTargetPlatforms: [] 66 | - serializedVersion: 2 67 | name: Good 68 | pixelLightCount: 2 69 | shadows: 2 70 | shadowResolution: 1 71 | shadowProjection: 1 72 | shadowCascades: 2 73 | shadowDistance: 40 74 | blendWeights: 2 75 | textureQuality: 0 76 | anisotropicTextures: 1 77 | antiAliasing: 0 78 | softParticles: 0 79 | softVegetation: 1 80 | vSyncCount: 1 81 | lodBias: 1 82 | maximumLODLevel: 0 83 | particleRaycastBudget: 256 84 | excludedTargetPlatforms: [] 85 | - serializedVersion: 2 86 | name: Beautiful 87 | pixelLightCount: 3 88 | shadows: 2 89 | shadowResolution: 2 90 | shadowProjection: 1 91 | shadowCascades: 2 92 | shadowDistance: 70 93 | blendWeights: 4 94 | textureQuality: 0 95 | anisotropicTextures: 2 96 | antiAliasing: 2 97 | softParticles: 1 98 | softVegetation: 1 99 | vSyncCount: 1 100 | lodBias: 1.5 101 | maximumLODLevel: 0 102 | particleRaycastBudget: 1024 103 | excludedTargetPlatforms: [] 104 | - serializedVersion: 2 105 | name: Fantastic 106 | pixelLightCount: 4 107 | shadows: 2 108 | shadowResolution: 2 109 | shadowProjection: 1 110 | shadowCascades: 4 111 | shadowDistance: 150 112 | blendWeights: 4 113 | textureQuality: 0 114 | anisotropicTextures: 2 115 | antiAliasing: 2 116 | softParticles: 1 117 | softVegetation: 1 118 | vSyncCount: 1 119 | lodBias: 2 120 | maximumLODLevel: 0 121 | particleRaycastBudget: 4096 122 | excludedTargetPlatforms: [] 123 | m_PerPlatformDefaultQuality: 124 | Android: 2 125 | BlackBerry: 2 126 | FlashPlayer: 3 127 | GLES Emulation: 3 128 | PS3: 3 129 | PS4: 3 130 | PSM: 3 131 | PSP2: 3 132 | Samsung TV: 2 133 | Standalone: 3 134 | Tizen: 2 135 | WP8: 3 136 | Web: 3 137 | Windows Store Apps: 3 138 | XBOX360: 3 139 | XboxOne: 3 140 | iPhone: 2 141 | -------------------------------------------------------------------------------- /demo/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | tags: 6 | - 7 | Builtin Layer 0: Default 8 | Builtin Layer 1: TransparentFX 9 | Builtin Layer 2: Ignore Raycast 10 | Builtin Layer 3: 11 | Builtin Layer 4: Water 12 | Builtin Layer 5: UI 13 | Builtin Layer 6: 14 | Builtin Layer 7: 15 | User Layer 8: 16 | User Layer 9: 17 | User Layer 10: 18 | User Layer 11: 19 | User Layer 12: 20 | User Layer 13: 21 | User Layer 14: 22 | User Layer 15: 23 | User Layer 16: 24 | User Layer 17: 25 | User Layer 18: 26 | User Layer 19: 27 | User Layer 20: 28 | User Layer 21: 29 | User Layer 22: 30 | User Layer 23: 31 | User Layer 24: 32 | User Layer 25: 33 | User Layer 26: 34 | User Layer 27: 35 | User Layer 28: 36 | User Layer 29: 37 | User Layer 30: 38 | User Layer 31: 39 | m_SortingLayers: 40 | - name: Default 41 | userID: 0 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /demo/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: .0199999996 7 | Maximum Allowed Timestep: .333333343 8 | m_TimeScale: 1 9 | -------------------------------------------------------------------------------- /spanning_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jceipek/Unity-delaunay/6f3c0a635834c75b5f28f595ef56839a9bdb7fec/spanning_graph.png -------------------------------------------------------------------------------- /triangulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jceipek/Unity-delaunay/6f3c0a635834c75b5f28f595ef56839a9bdb7fec/triangulation.png --------------------------------------------------------------------------------