├── .gitignore
├── README.md
├── samples
├── Basic
│ ├── include
│ │ └── Resources.h
│ ├── resources
│ │ └── cinder_app_icon.ico
│ ├── src
│ │ └── BasicApp.cpp
│ └── vc2013
│ │ ├── Basic.sln
│ │ ├── Basic.vcxproj
│ │ ├── Basic.vcxproj.filters
│ │ └── Resources.rc
└── SpherePoints
│ ├── include
│ └── Resources.h
│ ├── resources
│ └── cinder_app_icon.ico
│ ├── src
│ └── SpherePointsApp.cpp
│ └── vc2013
│ ├── Resources.rc
│ ├── SpherePoints.sln
│ ├── SpherePoints.vcxproj
│ └── SpherePoints.vcxproj.filters
└── src
├── CiDelaunay.cpp
├── CiDelaunay.h
└── Delaunay
├── Delaunay.cpp
└── Delaunay.h
/.gitignore:
--------------------------------------------------------------------------------
1 | x64
2 | *.suo
3 | *.opensdf
4 | *.sdf
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Cinder-Delaunay
6 |
7 | Simple Delaunay triangulator for Cinder based on [Triangulate by Paul Bourke](http://paulbourke.net/papers/triangulate/) and [Gilles Dumoulin's C++ implementation](http://paulbourke.net/papers/triangulate/cpp.zip). Requires [Cinder glNext](https://github.com/cinder/Cinder/tree/glNext)
8 |
9 | ## Installation
10 | Clone into your blocks repo and add the following references to your project:
11 | * <cinder_root>\blocks\Cinder-Delaunay\src
12 | * <cinder_root>\blocks\Cinder-Delaunay\src\Delaunay
13 |
14 | ## Use
15 | Cinder-Delaunay has one main function, CiDelaunay::triangulate. Using it is as simple as:
16 |
17 | ```
18 | TriMeshRef triangulatedPoints;
19 |
20 | void DelaunayApp::setup()
21 | {
22 | vector pointsToTriangulate;
23 |
24 | //fill vector with points,
25 | //then call:
26 | triangulatedPoints = CiDelaunay::triangulate(pointsToTriangulate);
27 | }
28 |
29 | void DelaunayApp::draw()
30 | {
31 | gl::enableWireframe();
32 | gl::draw(triangulatedPoints);
33 |
34 | //or whatever you want to do with it
35 | }
36 | ```
37 | Questions, comments, diatribes, feature requests, bugs'n'sugs? Send 'em to seth.gibson1@gmail.com. Also, I love PRs.
38 |
39 |
40 |
--------------------------------------------------------------------------------
/samples/Basic/include/Resources.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "cinder/CinderResources.h"
3 |
4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE )
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/Basic/resources/cinder_app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SethGibson/Cinder-Delaunay/cede54c907a6d9429ce985820df2875a90594179/samples/Basic/resources/cinder_app_icon.ico
--------------------------------------------------------------------------------
/samples/Basic/src/BasicApp.cpp:
--------------------------------------------------------------------------------
1 | #include "cinder/app/App.h"
2 | #include "cinder/app/RendererGl.h"
3 | #include "cinder/gl/gl.h"
4 | #include "cinder/gl/Batch.h"
5 | #include "cinder/gl/Shader.h"
6 | #include "cinder/Camera.h"
7 | #include "cinder/CameraUi.h"
8 | #include "cinder/Rand.h"
9 |
10 | #include "CiDelaunay.h"
11 |
12 | using namespace ci;
13 | using namespace ci::app;
14 | using namespace std;
15 |
16 | class BasicApp : public App
17 | {
18 | public:
19 | void setup() override;
20 | void update() override;
21 | void draw() override;
22 |
23 | private:
24 | void drawWorld(vec3 pCenter, vec3 pBounds, float pScale);
25 |
26 | vector mPoints;
27 |
28 | CameraPersp mCamera;
29 | CameraUi mCamUI;
30 |
31 | gl::VboRef mVbo;
32 | gl::VboMeshRef mMesh;
33 | gl::BatchRef mBatch;
34 |
35 | TriMeshRef mTris;
36 | };
37 |
38 | int S_NUM_PTS = 1000;
39 | void BasicApp::setup()
40 | {
41 | getWindow()->setSize(1280, 720);
42 |
43 |
44 |
45 | vec3 cEyePos(0, 0, 10);
46 | mCamera.setPerspective(45.0f, getWindowAspectRatio(), 0.1f, 100.0f);
47 | mCamera.lookAt(cEyePos, vec3(0), vec3(0, 1, 0));
48 | mCamera.setPivotDistance(length(cEyePos));
49 | mCamUI = CameraUi(&mCamera, getWindow());
50 |
51 | for (int i = 0; i < S_NUM_PTS; ++i)
52 | {
53 | mPoints.push_back(vec3(randFloat(-5, 5), randFloat(-5, 5), randFloat(0, 2)));
54 | }
55 |
56 | geom::BufferLayout cLayout;
57 | cLayout.append(geom::POSITION, 3, 0, 0, 0);
58 | mVbo = gl::Vbo::create(GL_ARRAY_BUFFER, mPoints, GL_STATIC_DRAW);
59 | mMesh = gl::VboMesh::create(S_NUM_PTS, GL_POINTS, { { cLayout, mVbo } });
60 |
61 | string cVertShader =
62 | "uniform mat4 ciModelViewProjection;"
63 | "in vec4 ciPosition;"
64 | "void main()"
65 | "{ gl_Position = ciModelViewProjection*ciPosition; }";
66 | string cFragShader =
67 | "out vec4 Color;"
68 | "void main()"
69 | "{ Color = vec4(1,1,1,1); }";
70 |
71 | gl::GlslProgRef cShader = gl::GlslProg::create(cVertShader, cFragShader);
72 | mBatch = gl::Batch::create(mMesh, cShader);
73 |
74 | mTris = CiDelaunay::triangulate(mPoints);
75 |
76 | }
77 |
78 | void BasicApp::update()
79 | {
80 | }
81 |
82 | void BasicApp::draw()
83 | {
84 | gl::clear( Color( 0, 0, 0 ) );
85 | gl::setMatrices(mCamera);
86 |
87 | drawWorld(vec3(0), vec3(10), 2.0f);
88 | gl::pointSize(4.0f);
89 | mBatch->draw();
90 |
91 | gl::color(Color(0, 1, 1));
92 | gl::enableWireframe();
93 | gl::draw(*mTris.get());
94 |
95 |
96 | }
97 |
98 | void BasicApp::drawWorld(vec3 pCenter, vec3 pBounds, float pScale)
99 | {
100 | gl::color(Color::white());
101 | gl::drawStrokedCube(pCenter, pBounds);
102 |
103 | gl::color(Color(1, 0, 0));
104 | gl::drawLine(pCenter, vec3(pScale, 0, 0));
105 | gl::color(Color(0, 1, 0));
106 | gl::drawLine(pCenter, vec3(0, pScale, 0));
107 | gl::color(Color(0, 0, 1));
108 | gl::drawLine(pCenter, vec3(0, 0, pScale));
109 | }
110 |
111 | CINDER_APP( BasicApp, RendererGl )
112 |
--------------------------------------------------------------------------------
/samples/Basic/vc2013/Basic.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2013
3 | VisualStudioVersion = 12.0.31101.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Basic", "Basic.vcxproj", "{A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|x64 = Debug|x64
10 | Release|x64 = Release|x64
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}.Debug|x64.ActiveCfg = Debug|x64
14 | {A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}.Debug|x64.Build.0 = Debug|x64
15 | {A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}.Release|x64.ActiveCfg = Release|x64
16 | {A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}.Release|x64.Build.0 = Release|x64
17 | EndGlobalSection
18 | GlobalSection(SolutionProperties) = preSolution
19 | HideSolutionNode = FALSE
20 | EndGlobalSection
21 | EndGlobal
22 |
--------------------------------------------------------------------------------
/samples/Basic/vc2013/Basic.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {A9C8E0C3-C9D3-4AC3-90AF-7773151D4E63}
15 | Basic
16 | Win32Proj
17 |
18 |
19 |
20 | Application
21 | false
22 | v120
23 | Unicode
24 | true
25 |
26 |
27 | Application
28 | true
29 | v120
30 | Unicode
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | <_ProjectFileVersion>10.0.30319.1
43 | true
44 | false
45 |
46 |
47 |
48 | Disabled
49 | ..\include;$(CINDER_DEV)\include;$(CINDER_DEV)\boost;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src\Delaunay
50 | WIN32;_DEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
51 | EnableFastChecks
52 | MultiThreadedDebug
53 |
54 | Level3
55 | ProgramDatabase
56 | true
57 |
58 |
59 | "..\..\..\..\..\..\Cinder\include";..\include
60 |
61 |
62 | cinder-$(PlatformToolset)_d.lib;OpenGL32.lib;%(AdditionalDependencies)
63 | $(CINDER_DEV)\lib\msw\$(PlatformTarget)
64 | true
65 | Windows
66 | false
67 |
68 | LIBCMT;LIBCPMT
69 |
70 |
71 |
72 |
73 | ..\include;$(CINDER_DEV)\include;$(CINDER_DEV)\boost;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src\Delaunay
74 | WIN32;NDEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
75 | MultiThreaded
76 |
77 | Level3
78 | ProgramDatabase
79 | true
80 |
81 |
82 | true
83 |
84 |
85 | "..\..\..\..\..\..\Cinder\include";..\include
86 |
87 |
88 | cinder-$(PlatformToolset).lib;OpenGL32.lib;%(AdditionalDependencies)
89 | $(CINDER_DEV)\lib\msw\$(PlatformTarget)
90 | false
91 | true
92 | Windows
93 | true
94 |
95 | false
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/samples/Basic/vc2013/Basic.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
15 |
16 |
17 | {78f5f618-3b07-485c-85a6-73fcc776b124}
18 |
19 |
20 | {8c73c72e-8661-4048-962a-198d9afd3fa6}
21 |
22 |
23 | {894e9b6d-a79b-4ee2-990f-904822b3bd47}
24 |
25 |
26 |
27 |
28 | Source Files
29 |
30 |
31 | Source Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | Source Files\blocks\Cinder-Delaunay
38 |
39 |
40 | Source Files\blocks\Cinder-Delaunay\src
41 |
42 |
43 |
44 |
45 | Header Files
46 |
47 |
48 | Source Files\blocks\Cinder-Delaunay
49 |
50 |
51 | Source Files\blocks\Cinder-Delaunay\src
52 |
53 |
54 |
55 |
56 | Resource Files
57 |
58 |
59 |
--------------------------------------------------------------------------------
/samples/Basic/vc2013/Resources.rc:
--------------------------------------------------------------------------------
1 | #include "../include/Resources.h"
2 |
3 | 1 ICON "..\\resources\\cinder_app_icon.ico"
4 |
--------------------------------------------------------------------------------
/samples/SpherePoints/include/Resources.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "cinder/CinderResources.h"
3 |
4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE )
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/SpherePoints/resources/cinder_app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SethGibson/Cinder-Delaunay/cede54c907a6d9429ce985820df2875a90594179/samples/SpherePoints/resources/cinder_app_icon.ico
--------------------------------------------------------------------------------
/samples/SpherePoints/src/SpherePointsApp.cpp:
--------------------------------------------------------------------------------
1 | #include "cinder/app/App.h"
2 | #include "cinder/app/RendererGl.h"
3 | #include "cinder/Camera.h"
4 | #include "cinder/CameraUi.h"
5 | #include "cinder/gl/gl.h"
6 | #include "cinder/gl/Batch.h"
7 | #include "cinder/gl/GlslProg.h"
8 | #include "cinder/Rand.h"
9 | #include "CiDelaunay.h"
10 |
11 | using namespace ci;
12 | using namespace ci::app;
13 | using namespace std;
14 |
15 | class SpherePointsApp : public App
16 | {
17 | public:
18 | void setup() override;
19 | void mouseDown( MouseEvent event ) override;
20 | void update() override;
21 | void draw() override;
22 |
23 | private:
24 | void drawWorld(vec3 pCenter, vec3 pBounds, float pAxes);
25 |
26 | vector mSpherePoints;
27 | gl::BatchRef mBatch;
28 | CameraPersp mCamera;
29 | CameraUi mCamUI;
30 |
31 | TriMeshRef mTris;
32 | };
33 |
34 | int S_NUM_PTS = 1000;
35 |
36 | void SpherePointsApp::setup()
37 | {
38 | getWindow()->setSize(1280, 720);
39 |
40 | for (int i = 0; i < S_NUM_PTS; ++i)
41 | {
42 | float z = randFloat(-1.f, 1.f);
43 | float t = randFloat(0, 2.0f*M_PI);
44 | float r = math::sqrt(1.0f - z*z);
45 | float x = r*cos(t);
46 | float y = r*sin(t);
47 | if (x!=0&&y!=0&&z!=0)
48 | mSpherePoints.push_back(vec3(x*5.f, y*5.f, math::abs(z*5.f)));
49 |
50 | }
51 |
52 | gl::VboRef cVbo = gl::Vbo::create(GL_ARRAY_BUFFER, mSpherePoints, GL_STATIC_DRAW);
53 | geom::BufferLayout cAttribs;
54 | cAttribs.append(geom::POSITION,3,0,0,0);
55 | gl::VboMeshRef cMesh = gl::VboMesh::create(S_NUM_PTS, GL_POINTS, { { cAttribs, cVbo } });
56 |
57 | string cVertShader =
58 | "uniform mat4 ciModelViewProjection;"
59 | "in vec4 ciPosition;"
60 | "void main(){"
61 | "gl_Position = ciModelViewProjection*ciPosition;}";
62 | string cFragShader =
63 | "out vec4 Color;"
64 | "void main(){"
65 | "Color = vec4(1,1,1,1);}";
66 |
67 | mBatch = gl::Batch::create(cMesh, gl::GlslProg::create(cVertShader, cFragShader));
68 |
69 |
70 | vec3 cEyePos(0, 0, 10);
71 | mCamera.setPerspective(45.0f, getWindowAspectRatio(), 0.1f, 100.0f);
72 | mCamera.lookAt(cEyePos, vec3(0), vec3(0, 1, 0));
73 | mCamera.setPivotDistance(length(cEyePos));
74 | mCamUI = CameraUi(&mCamera, getWindow());
75 |
76 | mTris = CiDelaunay::triangulate(mSpherePoints);
77 | }
78 |
79 | void SpherePointsApp::mouseDown( MouseEvent event )
80 | {
81 | }
82 |
83 | void SpherePointsApp::update()
84 | {
85 | }
86 |
87 | void SpherePointsApp::draw()
88 | {
89 | gl::clear( Color( 0, 0, 0 ) );
90 | gl::setMatrices(mCamera);
91 |
92 | drawWorld(vec3(0), vec3(10), 2.0f);
93 |
94 | gl::color(Color(0, 0.5f, 0.8f));
95 | gl::enableWireframe();
96 | gl::draw(*mTris);
97 | gl::disableWireframe();
98 |
99 | gl::color(Color::white());
100 | gl::pointSize(3.0f);
101 | mBatch->draw();
102 | }
103 |
104 | void SpherePointsApp::drawWorld(vec3 pCenter, vec3 pBounds, float pAxes)
105 | {
106 | gl::pushMatrices();
107 | gl::translate(pCenter);
108 | gl::color(Color::white());
109 | gl::drawStrokedCube(vec3(0), pBounds);
110 |
111 | gl::color(Color(1, 0, 0));
112 | gl::drawLine(vec3(0), vec3(pAxes,0,0));
113 | gl::color(Color(0, 1, 0));
114 | gl::drawLine(vec3(0), vec3(0, pAxes, 0));
115 | gl::color(Color(0, 0, 1));
116 | gl::drawLine(vec3(0), vec3(0, 0, pAxes));
117 | gl::popMatrices();
118 |
119 | }
120 | CINDER_APP( SpherePointsApp, RendererGl )
121 |
--------------------------------------------------------------------------------
/samples/SpherePoints/vc2013/Resources.rc:
--------------------------------------------------------------------------------
1 | #include "../include/Resources.h"
2 |
3 | 1 ICON "..\\resources\\cinder_app_icon.ico"
4 |
--------------------------------------------------------------------------------
/samples/SpherePoints/vc2013/SpherePoints.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2013
3 | VisualStudioVersion = 12.0.31101.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SpherePoints", "SpherePoints.vcxproj", "{B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|x64 = Debug|x64
10 | Release|x64 = Release|x64
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}.Debug|x64.ActiveCfg = Debug|x64
14 | {B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}.Debug|x64.Build.0 = Debug|x64
15 | {B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}.Release|x64.ActiveCfg = Release|x64
16 | {B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}.Release|x64.Build.0 = Release|x64
17 | EndGlobalSection
18 | GlobalSection(SolutionProperties) = preSolution
19 | HideSolutionNode = FALSE
20 | EndGlobalSection
21 | EndGlobal
22 |
--------------------------------------------------------------------------------
/samples/SpherePoints/vc2013/SpherePoints.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {B76A7C5C-999A-4FF1-82E7-B6C91DFC14F0}
15 | SpherePoints
16 | Win32Proj
17 |
18 |
19 |
20 | Application
21 | false
22 | v120
23 | Unicode
24 | true
25 |
26 |
27 | Application
28 | true
29 | v120
30 | Unicode
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | <_ProjectFileVersion>10.0.30319.1
43 | true
44 | false
45 |
46 |
47 |
48 | Disabled
49 | ..\include;$(CINDER_DEV)\include;$(CINDER_DEV)\boost;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src\Delaunay
50 | WIN32;_DEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
51 | EnableFastChecks
52 | MultiThreadedDebug
53 |
54 | Level3
55 | ProgramDatabase
56 | true
57 |
58 |
59 | "$(CINDER_DEV)\include";..\include
60 |
61 |
62 | cinder-$(PlatformToolset)_d.lib;OpenGL32.lib;%(AdditionalDependencies)
63 | "$(CINDER_DEV)\lib\msw\$(PlatformTarget)"
64 | true
65 | Windows
66 | false
67 |
68 | LIBCMT;LIBCPMT
69 |
70 |
71 |
72 |
73 | ..\include;$(CINDER_DEV)\include;$(CINDER_DEV)\boost;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src;$(CINDER_BLOCKS)\blocks\Cinder-Delaunay\src\Delaunay
74 | WIN32;NDEBUG;_WINDOWS;NOMINMAX;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)
75 | MultiThreaded
76 |
77 | Level3
78 | ProgramDatabase
79 | true
80 |
81 |
82 | true
83 |
84 |
85 | "$(CINDER_DEV)\include";..\include
86 |
87 |
88 | cinder-$(PlatformToolset).lib;OpenGL32.lib;%(AdditionalDependencies)
89 | "$(CINDER_DEV)\lib\msw\$(PlatformTarget)"
90 | false
91 | true
92 | Windows
93 | true
94 |
95 | false
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/samples/SpherePoints/vc2013/SpherePoints.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
15 |
16 |
17 | {997e16a9-31d0-49d0-9d19-527f27ab32c2}
18 |
19 |
20 | {9fcf9b4c-0d2d-475a-a35f-d27c3c9da86e}
21 |
22 |
23 |
24 |
25 | Source Files
26 |
27 |
28 | Source Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Source Files\blocks\Cinder-Delaunay
35 |
36 |
37 | Source Files\blocks\Cinder-Delaunay
38 |
39 |
40 |
41 |
42 | Header Files
43 |
44 |
45 | Source Files\blocks\Cinder-Delaunay
46 |
47 |
48 | Source Files\blocks\Cinder-Delaunay
49 |
50 |
51 |
52 |
53 | Resource Files
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/CiDelaunay.cpp:
--------------------------------------------------------------------------------
1 | #include "CiDelaunay.h"
2 |
3 | ////////////////////////////////////////////////////////////////////////
4 | // Wrapper for Delaunay::CircumCircle
5 | // Params:
6 | // vec2 pP: point to check
7 | // vec2 *pCP: vec2[3] containing the points of the CircumCircle
8 | // Returns:
9 | // pair.first: true if pP is inside pCP
10 | // pair.second: x = CircumCircle center x
11 | // y = CircumCircle center y
12 | // z=CircumCircle radius
13 | ////////////////////////////////////////////////////////////////////////
14 | pair
15 | CiDelaunay::isPointinCircumCircle(vec2 pP, vec2 *pCP)
16 | {
17 |
18 | double cCX, cCY, cCR;
19 | bool cIsInCircle = CircumCircle(pP.x, pP.y, pCP[0].x, pCP[0].y, pCP[1].x, pCP[1].y, pCP[2].x, pCP[2].y, cCX, cCY, cCR);
20 |
21 | return make_pair(cIsInCircle, vec3(cCX, cCY, cCR));
22 |
23 | }
24 | /*
25 | ///////////////////////////////////////////////////////////////////////////////
26 | // Triangulate() :
27 | // Triangulation subroutine
28 | // Takes as input NV vertices in array pxyz
29 | // Returned is a list of ntri triangular faces in the array v
30 | // These triangles are arranged in a consistent clockwise order.
31 | // The triangle array 'v' should be malloced to 3 * nv
32 | // The vertex array pxyz must be big enough to hold 3 more points
33 | // The vertex array must be sorted in increasing x values say
34 | //
35 | // qsort(p,nv,sizeof(XYZ),XYZCompare);
36 | ///////////////////////////////////////////////////////////////////////////////
37 | int Triangulate(int nv, XYZ pxyz[], ITRIANGLE v[], int &ntri){
38 | */
39 | TriMeshRef
40 | CiDelaunay::triangulate(vector pVertices)
41 | {
42 | vector cXYZVerts;
43 | vector cTriangles;
44 |
45 | vector cVtxOutput;
46 | vector cIdxOutput;
47 |
48 | int cOutTriCount = -1;
49 |
50 | for (auto v = pVertices.begin(); v != pVertices.end();++v)
51 | {
52 | cXYZVerts.push_back(toXYZ(*v));
53 | }
54 |
55 | cXYZVerts.push_back(XYZ()); cXYZVerts.push_back(XYZ()); cXYZVerts.push_back(XYZ());
56 | cTriangles.resize(cXYZVerts.size() * 3);
57 | qsort(cXYZVerts.data(), cXYZVerts.size(), sizeof(XYZ), XYZCompare);
58 |
59 | Triangulate(pVertices.size(), cXYZVerts.data(), &cTriangles[0], cOutTriCount);
60 |
61 | for (auto xyz = cXYZVerts.begin(); xyz != cXYZVerts.end(); ++xyz)
62 | {
63 | cVtxOutput.push_back(fromXYZ(*xyz));
64 | }
65 |
66 | for (auto tri = cTriangles.begin(); tri != cTriangles.end(); ++tri)
67 | {
68 | cIdxOutput.push_back(tri->p1);
69 | cIdxOutput.push_back(tri->p2);
70 | cIdxOutput.push_back(tri->p3);
71 | }
72 |
73 | TriMeshRef cTriangulatedMesh = TriMesh::create(TriMesh::Format().positions(3));
74 | cTriangulatedMesh->appendVertices(cVtxOutput.data(), cVtxOutput.size());
75 | cTriangulatedMesh->appendIndices(cIdxOutput.data(), cIdxOutput.size());
76 |
77 | return cTriangulatedMesh;
78 | }
79 |
80 | // Utilities
81 |
82 | vec3 CiDelaunay::fromXYZ(XYZ pInput)
83 | {
84 | return vec3(pInput.x, pInput.y, pInput.z);
85 | }
86 |
87 | XYZ CiDelaunay::toXYZ(vec3 pInput)
88 | {
89 | XYZ ret;
90 | ret.x = pInput.x; ret.y = pInput.y; ret.z = pInput.z;
91 | return ret;
92 | }
93 |
94 | ivec2 CiDelaunay::fromIEDGE(IEDGE pInput)
95 | {
96 | return ivec2(pInput.p1, pInput.p2);
97 | }
98 |
99 | IEDGE CiDelaunay::toIEDGE(ivec2 pInput)
100 | {
101 | IEDGE ret;
102 | ret.p1 = pInput.x; ret.p2 = pInput.y;
103 | return ret;
104 | }
105 |
106 | ivec3 CiDelaunay::fromITRIANGLE(ITRIANGLE pInput)
107 | {
108 | return ivec3(pInput.p1, pInput.p2, pInput.p3);
109 | }
110 |
111 | ITRIANGLE CiDelaunay::toITRIANGLE(ivec3 pInput)
112 | {
113 | ITRIANGLE ret;
114 | ret.p1 = pInput.x; ret.p2 = pInput.y; ret.p3 = pInput.z;
115 | return ret;
116 | }
117 |
--------------------------------------------------------------------------------
/src/CiDelaunay.h:
--------------------------------------------------------------------------------
1 | #ifndef __CI_DELAUNAY__
2 | #define __CI_DELAUNAY__
3 |
4 | #include
5 | #include "cinder\Vector.h"
6 | #include "cinder\CinderGlm.h"
7 | #include "cinder\TriMesh.h"
8 | #include "Delaunay.h"
9 |
10 | using namespace std;
11 | using namespace ci;
12 |
13 |
14 | namespace CiDelaunay
15 | {
16 |
17 | vec3 fromXYZ(XYZ pInput);
18 | XYZ toXYZ(vec3 pInput);
19 |
20 | ivec2 fromIEDGE(IEDGE pInput);
21 | IEDGE toIEDGE(ivec2 pInput);
22 |
23 | ivec3 fromITRIANGLE(ITRIANGLE pInput);
24 | ITRIANGLE toITRIANGLE(ivec3 pInput);
25 |
26 | pair isPointinCircumCircle(vec2 pPt, vec2 *pCP);
27 | TriMeshRef triangulate(vector pVertices);
28 | };
29 | #endif
--------------------------------------------------------------------------------
/src/Delaunay/Delaunay.cpp:
--------------------------------------------------------------------------------
1 | #include "Delaunay.h"
2 |
3 | using namespace std;
4 |
5 | ////////////////////////////////////////////////////////////////////////
6 | // CircumCircle() :
7 | // Return true if a point (xp,yp) is inside the circumcircle made up
8 | // of the points (x1,y1), (x2,y2), (x3,y3)
9 | // The circumcircle centre is returned in (xc,yc) and the radius r
10 | // Note : A point on the edge is inside the circumcircle
11 | ////////////////////////////////////////////////////////////////////////
12 |
13 | int CircumCircle(double xp, double yp, double x1, double y1, double x2,
14 | double y2, double x3, double y3, double &xc, double &yc, double &r){
15 | double m1, m2, mx1, mx2, my1, my2;
16 | double dx, dy, rsqr, drsqr;
17 |
18 | /* Check for coincident points */
19 | if(abs(y1 - y2) < EPSILON && abs(y2 - y3) < EPSILON)
20 | return(false);
21 | if(abs(y2-y1) < EPSILON){
22 | m2 = - (x3 - x2) / (y3 - y2);
23 | mx2 = (x2 + x3) / 2.0;
24 | my2 = (y2 + y3) / 2.0;
25 | xc = (x2 + x1) / 2.0;
26 | yc = m2 * (xc - mx2) + my2;
27 | }else if(abs(y3 - y2) < EPSILON){
28 | m1 = - (x2 - x1) / (y2 - y1);
29 | mx1 = (x1 + x2) / 2.0;
30 | my1 = (y1 + y2) / 2.0;
31 | xc = (x3 + x2) / 2.0;
32 | yc = m1 * (xc - mx1) + my1;
33 | }else{
34 | m1 = - (x2 - x1) / (y2 - y1);
35 | m2 = - (x3 - x2) / (y3 - y2);
36 | mx1 = (x1 + x2) / 2.0;
37 | mx2 = (x2 + x3) / 2.0;
38 | my1 = (y1 + y2) / 2.0;
39 | my2 = (y2 + y3) / 2.0;
40 | xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
41 | yc = m1 * (xc - mx1) + my1;
42 | }
43 | dx = x2 - xc;
44 | dy = y2 - yc;
45 | rsqr = dx * dx + dy * dy;
46 | r = sqrt(rsqr);
47 | dx = xp - xc;
48 | dy = yp - yc;
49 | drsqr = dx * dx + dy * dy;
50 | return((drsqr <= rsqr) ? true : false);
51 | }
52 | ///////////////////////////////////////////////////////////////////////////////
53 | // Triangulate() :
54 | // Triangulation subroutine
55 | // Takes as input NV vertices in array pxyz
56 | // Returned is a list of ntri triangular faces in the array v
57 | // These triangles are arranged in a consistent clockwise order.
58 | // The triangle array 'v' should be malloced to 3 * nv
59 | // The vertex array pxyz must be big enough to hold 3 more points
60 | // The vertex array must be sorted in increasing x values say
61 | //
62 | // qsort(p,nv,sizeof(XYZ),XYZCompare);
63 | ///////////////////////////////////////////////////////////////////////////////
64 |
65 | int Triangulate(int nv, XYZ pxyz[], ITRIANGLE v[], int &ntri){
66 | int *complete = NULL;
67 | IEDGE *edges = NULL;
68 | IEDGE *p_EdgeTemp;
69 | int nedge = 0;
70 | int trimax, emax = 200;
71 | int status = 0;
72 | int inside;
73 | int i, j, k;
74 | double xp, yp, x1, y1, x2, y2, x3, y3, xc, yc, r;
75 | double xmin, xmax, ymin, ymax, xmid, ymid;
76 | double dx, dy, dmax;
77 |
78 | /* Allocate memory for the completeness list, flag for each triangle */
79 | trimax = 4 * nv;
80 | complete = new int[trimax];
81 | /* Allocate memory for the edge list */
82 | edges = new IEDGE[emax];
83 | /*
84 | Find the maximum and minimum vertex bounds.
85 | This is to allow calculation of the bounding triangle
86 | */
87 | xmin = pxyz[0].x;
88 | ymin = pxyz[0].y;
89 | xmax = xmin;
90 | ymax = ymin;
91 | for(i = 1; i < nv; i++){
92 | if (pxyz[i].x < xmin) xmin = pxyz[i].x;
93 | if (pxyz[i].x > xmax) xmax = pxyz[i].x;
94 | if (pxyz[i].y < ymin) ymin = pxyz[i].y;
95 | if (pxyz[i].y > ymax) ymax = pxyz[i].y;
96 | }
97 | dx = xmax - xmin;
98 | dy = ymax - ymin;
99 | dmax = (dx > dy) ? dx : dy;
100 | xmid = (xmax + xmin) / 2.0;
101 | ymid = (ymax + ymin) / 2.0;
102 | /*
103 | Set up the supertriangle
104 | his is a triangle which encompasses all the sample points.
105 | The supertriangle coordinates are added to the end of the
106 | vertex list. The supertriangle is the first triangle in
107 | the triangle list.
108 | */
109 | pxyz[nv+0].x = xmid - 20 * dmax;
110 | pxyz[nv+0].y = ymid - dmax;
111 | pxyz[nv+1].x = xmid;
112 | pxyz[nv+1].y = ymid + 20 * dmax;
113 | pxyz[nv+2].x = xmid + 20 * dmax;
114 | pxyz[nv+2].y = ymid - dmax;
115 | v[0].p1 = nv;
116 | v[0].p2 = nv+1;
117 | v[0].p3 = nv+2;
118 | complete[0] = false;
119 | ntri = 1;
120 | /*
121 | Include each point one at a time into the existing mesh
122 | */
123 | for(i = 0; i < nv; i++){
124 | xp = pxyz[i].x;
125 | yp = pxyz[i].y;
126 | nedge = 0;
127 | /*
128 | Set up the edge buffer.
129 | If the point (xp,yp) lies inside the circumcircle then the
130 | three edges of that triangle are added to the edge buffer
131 | and that triangle is removed.
132 | */
133 | for(j = 0; j < ntri; j++){
134 | if(complete[j])
135 | continue;
136 | x1 = pxyz[v[j].p1].x;
137 | y1 = pxyz[v[j].p1].y;
138 | x2 = pxyz[v[j].p2].x;
139 | y2 = pxyz[v[j].p2].y;
140 | x3 = pxyz[v[j].p3].x;
141 | y3 = pxyz[v[j].p3].y;
142 | inside = CircumCircle(xp, yp, x1, y1, x2, y2, x3, y3, xc, yc, r);
143 | if (xc + r < xp)
144 | // Suggested
145 | // if (xc + r + EPSILON < xp)
146 | complete[j] = true;
147 | if(inside){
148 | /* Check that we haven't exceeded the edge list size */
149 | if(nedge + 3 >= emax){
150 | emax += 100;
151 | p_EdgeTemp = new IEDGE[emax];
152 | for (int i = 0; i < nedge; i++) { // Fix by John Bowman
153 | p_EdgeTemp[i] = edges[i];
154 | }
155 | delete []edges;
156 | edges = p_EdgeTemp;
157 | }
158 | edges[nedge+0].p1 = v[j].p1;
159 | edges[nedge+0].p2 = v[j].p2;
160 | edges[nedge+1].p1 = v[j].p2;
161 | edges[nedge+1].p2 = v[j].p3;
162 | edges[nedge+2].p1 = v[j].p3;
163 | edges[nedge+2].p2 = v[j].p1;
164 | nedge += 3;
165 | v[j] = v[ntri-1];
166 | complete[j] = complete[ntri-1];
167 | ntri--;
168 | j--;
169 | }
170 | }
171 | /*
172 | Tag multiple edges
173 | Note: if all triangles are specified anticlockwise then all
174 | interior edges are opposite pointing in direction.
175 | */
176 | for(j = 0; j < nedge - 1; j++){
177 | for(k = j + 1; k < nedge; k++){
178 | if((edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1)){
179 | edges[j].p1 = -1;
180 | edges[j].p2 = -1;
181 | edges[k].p1 = -1;
182 | edges[k].p2 = -1;
183 | }
184 | /* Shouldn't need the following, see note above */
185 | if((edges[j].p1 == edges[k].p1) && (edges[j].p2 == edges[k].p2)){
186 | edges[j].p1 = -1;
187 | edges[j].p2 = -1;
188 | edges[k].p1 = -1;
189 | edges[k].p2 = -1;
190 | }
191 | }
192 | }
193 | /*
194 | Form new triangles for the current point
195 | Skipping over any tagged edges.
196 | All edges are arranged in clockwise order.
197 | */
198 | for(j = 0; j < nedge; j++) {
199 | if(edges[j].p1 < 0 || edges[j].p2 < 0)
200 | continue;
201 | v[ntri].p1 = edges[j].p1;
202 | v[ntri].p2 = edges[j].p2;
203 | v[ntri].p3 = i;
204 | complete[ntri] = false;
205 | ntri++;
206 | }
207 | }
208 | /*
209 | Remove triangles with supertriangle vertices
210 | These are triangles which have a vertex number greater than nv
211 | */
212 | for(i = 0; i < ntri; i++) {
213 | if(v[i].p1 >= nv || v[i].p2 >= nv || v[i].p3 >= nv) {
214 | v[i] = v[ntri-1];
215 | ntri--;
216 | i--;
217 | }
218 | }
219 | delete[] edges;
220 | delete[] complete;
221 | return 0;
222 | }
223 |
224 | void randomize(){
225 | srand((time_t) time(NULL));
226 | }
227 |
228 | int random(int n){
229 | return rand()%n;
230 | }
231 |
232 | int XYZCompare(const void *v1, const void *v2){
233 | XYZ *p1, *p2;
234 |
235 | p1 = (XYZ*)v1;
236 | p2 = (XYZ*)v2;
237 | if(p1->x < p2->x)
238 | return(-1);
239 | else if(p1->x > p2->x)
240 | return(1);
241 | else
242 | return(0);
243 | }
244 |
245 | void outputtriangle(int &nv, XYZ p[], ITRIANGLE v[], int &ntri){
246 | int X, Y, i = 0;
247 | int max = 10;
248 | double x, y;
249 |
250 | for(int i = 0; i < ntri; i++){// replace cout by a compatible lineto to trace
251 | cout<<(int)p[v[i].p1].x<<" "<< (int)p[v[i].p1].y<<" "<< (int)p[v[i].p2].x
252 | <<" "<< (int)p[v[i].p2].y<<"\n";
253 | cout<<(int)p[v[i].p2].x<<" "<< (int)p[v[i].p2].y<<" "<< (int)p[v[i].p3].x
254 | <<" "<< (int)p[v[i].p3].y<<"\n";
255 | cout<<(int)p[v[i].p3].x<<" "<< (int)p[v[i].p3].y<<" "<< (int)p[v[i].p1].x
256 | <<" "<< (int)p[v[i].p1].y<<"\n";
257 | }
258 | }
259 |
260 | int main(){
261 | ITRIANGLE *v = NULL;
262 | int max = 10;
263 | XYZ *p = new XYZ[max];
264 | XYZ *p_Temp = NULL;
265 | int nv = 0;
266 | int X, Y;
267 | int i;
268 | int ntri = 0;
269 | double x, y, z;
270 | bool b_Ok = false;
271 |
272 | randomize();
273 | nv = 0;
274 | p = new XYZ[max];
275 | while (nv != n_MaxPoints){
276 | do{
277 | b_Ok = true;
278 | x = (double)random(500);
279 | y = (double)random(500);
280 | for(int n_Cpt = 0; n_Cpt <= nv; n_Cpt++){
281 | if((x == p[n_Cpt].x) && (y == p[n_Cpt].y)) b_Ok = false;
282 | }// to avoid similar points in the array
283 | }while(!b_Ok);
284 | if (nv >= max){
285 | max = max * 2; // double the size of the array if necessary
286 | p_Temp = new XYZ[max];
287 | for (int i = 0; i < nv; i++) {
288 | p_Temp[i] = p[i];
289 | }
290 | delete []p;
291 | p = p_Temp;
292 | }
293 | p[nv].x = x * 1.0;
294 | p[nv].y = y * 1.0;
295 | nv++;
296 | }
297 | p_Temp = new XYZ[nv + 3];
298 | for (int i = 0; i < nv; i++) {
299 | p_Temp[i] = p[i];
300 | }
301 | delete []p;
302 | p = p_Temp;
303 | v = new ITRIANGLE[3 * nv];
304 | qsort(p, nv, sizeof(XYZ), XYZCompare);
305 | Triangulate(nv, p, v, ntri);
306 | outputtriangle(nv, p, v, ntri); // use this fonction to trace the mesh (via
307 | delete []p;// OpenGL, DirectX, ...)
308 | delete []v;
309 | p = NULL;
310 | v = NULL;
311 | system("pause"); // remove under Linux
312 | return 0;
313 | }
314 |
315 |
316 |
317 |
318 |
--------------------------------------------------------------------------------
/src/Delaunay/Delaunay.h:
--------------------------------------------------------------------------------
1 | #ifndef Delaunay_H
2 | #define Delaunay_H
3 |
4 | #include
5 | #include // for C qsort
6 | #include
7 | #include // for random
8 |
9 | const int MaxVertices = 500;
10 | const int MaxTriangles = 1000;
11 | const int n_MaxPoints = 10; // for the test programm
12 | const double EPSILON = 0.000001;
13 |
14 | struct ITRIANGLE
15 | {
16 | int p1, p2, p3;
17 | };
18 |
19 | struct IEDGE
20 | {
21 | int p1, p2;
22 | };
23 |
24 | struct XYZ
25 | {
26 | double x, y, z;
27 | };
28 |
29 | int XYZCompare(const void *v1, const void *v2);
30 | int Triangulate(int nv, XYZ pxyz[], ITRIANGLE v[], int &ntri);
31 | int CircumCircle(double, double, double, double, double, double, double,
32 | double, double&, double&, double&);
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------