Commit v1.0 of openGJK
parent
f0faa98e03
commit
bcc7cc6e2a
|
@ -0,0 +1,76 @@
|
|||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
# ##### # # # #
|
||||
# #### ##### ###### # # # # # # # #
|
||||
# # # # # # ## # # # # # #
|
||||
# # # # # ##### # # # # #### # ### #
|
||||
# # # ##### # # # # # # # # # # #
|
||||
# # # # # # ## # # # # # # #
|
||||
# #### # ###### # # ##### ##### # # #
|
||||
# #
|
||||
# Mattia Montanari | University of Oxford 2018 #
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(openGJK)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
message("[${CMAKE_PROJECT_NAME}] Welcome, please change user options if needed.")
|
||||
|
||||
# APPLY DEFAULT SETTINGS
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message("[${CMAKE_PROJECT_NAME}] Use default CMAKE_BUILD_TYPE")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
|
||||
# PLATFORM-SPECIFIC SETTING
|
||||
if (UNIX)
|
||||
find_library(M_LIB m)
|
||||
set(CMAKE_C_FLAGS "-lm")
|
||||
set(CMAKE_CXX_FLAGS "-lm")
|
||||
else ()
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
endif ()
|
||||
|
||||
# COMPILER SETTING
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
ELSEIF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
ENDIF()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
# using GCC
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -finline-functions")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Werror")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -finline-functions")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -Werror")
|
||||
|
||||
add_compile_options(-static-libgcc -static-libstdc++ )
|
||||
add_definitions(-DMT)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall /WX /wd4131 /wd4701 /wd4255 /wd4710 /wd4820 /wd4711")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall /WX /wd4131 /wd4701 /wd4255 /wd4710 /wd4820 /wd4711")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1")
|
||||
set(CMAKE_C_FLAGS_RELEASE "/Ox")
|
||||
|
||||
set(CMAKE_SUPPRESS_REGENERATION true)
|
||||
|
||||
endif()
|
||||
|
||||
# DEBUG FLAGS
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_definitions(-DDEBUG)
|
||||
ENDIF()
|
||||
|
||||
# INCLUDE LIBRARY AND EXAMPLE DIR
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(example1_c)
|
232
README.md
232
README.md
|
@ -1,2 +1,230 @@
|
|||
# openGJK
|
||||
Fast and reliable implementation of the Gilbert-Johnson-Keerthi (GJK) algorithm for C, C# and Matlab
|
||||
|
||||
openGJK {#mainpage}
|
||||
=======
|
||||
|
||||
The openGJK library uses the Gilbert-Johnson-Keerthi (GJK) algorithm to
|
||||
compute the minimum distance between convex polytopes. The
|
||||
implementation follows the description presented in
|
||||
"[Improving the GJK Algorithm for Faster and More Reliable Distance
|
||||
Queries Between Convex Objects. ACM Trans. on Graph. 2017](https://dl.acm.org/citation.cfm?id=3083724)" and has been tested
|
||||
on Unix and Windows systems for C, C# and Matlab programs.
|
||||
|
||||
This library offers researchers a tool that works
|
||||
out of the box: you can import it in your program and use it to measure
|
||||
the distance between two convex polytopes in 3D. All it needs are the
|
||||
coordinates of the vertices describing the two bodies.
|
||||
This library is not optimised for production, but it does provide a comprehensive and robust implementation. It is sufficiently fast for
|
||||
most applications, and you can also build from here to suite your own
|
||||
application. For instance, openGJK is not for incremental and is not
|
||||
for NURBS, but it offers a good starting point for such specific
|
||||
applications.
|
||||
|
||||
## Getting Started
|
||||
Using openGJK is very simple. This guide will help you getting
|
||||
started compiling and using openGJK.
|
||||
|
||||
### When should I use openGJK?
|
||||
|
||||
OpenGJK is designed with accuracy and robustness in mind and is
|
||||
suitable for engineering simulations. Good use of this library
|
||||
include the finite element method (FEM) and discrete element method (DEM).
|
||||
|
||||
Basically, openGJK can measure the distance between **any convex polytope**. For example:
|
||||
- line segments
|
||||
- triangles
|
||||
- tetrahedrons
|
||||
- cubes.
|
||||
|
||||
### Installing the openGJK library
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
1. A compiler (gnu or Microsoft Visual Studio for C)
|
||||
2. CMake version 3.5 or above
|
||||
3. Only for the Matlab interface you will need to build mex files (find out the requisites from [Mathworks documentation](https://uk.mathworks.com/help/matlab/matlab_external/what-you-need-to-build-mex-files.html)).
|
||||
4. Only for the C# interface on Unix you will need [mono](http://www.mono-project.com/) and Microsoft Visual Studio toolchain for C# on Windows.
|
||||
|
||||
### Installation
|
||||
|
||||
There are CMake files for compiling openGJK in the usual
|
||||
way:
|
||||
1. Create a new folder in the folder containing this readme file.
|
||||
2. Move into that folder and type `cmake -G <duild-system> ..`. For example,
|
||||
on Windows you can type `cmake -G "Visual Studio 15 2017 Win64" ..`, on Unix `cmake -G "Unix Makefiles" ..`.
|
||||
3. Use the files generated by Cmake to build the library. Whether you compile
|
||||
with `make` or an IDE, you will build a shared library and an executable
|
||||
for the C example. For Matlab and C# applications, see sections below.
|
||||
|
||||
To install the library you should copy the header file openGJK.h and the binaries in a folder accessible in the search path by all users (on Unix this would normally be /usr/local).
|
||||
|
||||
### Automated documentation
|
||||
The folder `doc` contains a Doxygen file for generating the documentation of the whole
|
||||
library. To build the documentation cd into `doc` and call Doxygen from the command line simply by typing `doxygen`. If correctly installed, Doxygen will create html documentation with graphs illustrating the call stack of the functions of the library.
|
||||
|
||||
## API user reference
|
||||
|
||||
```double gjk( struct bodyA, struct bodyB, struct simplex)```
|
||||
|
||||
### Parameters
|
||||
* **bodyA** The first body.
|
||||
* **bodyB** The second body.
|
||||
* **simplex** The simplex used the GJK algorithm at the first iteration.
|
||||
|
||||
### Returns
|
||||
* **double** the minimum distance between bodyA and bodyB.
|
||||
|
||||
### Description
|
||||
The function `gjk` computes the minimum Euclidean distance between two bodies using the
|
||||
GJK algorithm. Note that the simplex used at the first iteration may be initialised by the user, but this is not necessary.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
openGJK comes in two flavours: *accurate* and *fast* (default). You can
|
||||
change before compiling by editing the main 'lib\CMakeLists.txt' file
|
||||
(in the folder `lib`). Set the option `VERSION_ACCURATE` to `ON` and
|
||||
run CMake. You can verify what version is being compiled from the terminal,
|
||||
if you do not see "Version: Accurate" when calling CMake, you have to clean
|
||||
the CMake cache.
|
||||
|
||||
## Examples
|
||||
|
||||
This section presents three examples on how to use openGJK with C, C# and Matlab.
|
||||
All the examples have been tested both Linux and Windows; the former used `make` and `gcc`,
|
||||
the latter using `Visual studio 2017` and its compiler. Only x64 systems have been tested.
|
||||
|
||||
### C
|
||||
This example illustrates how to include openGJK in an existing C
|
||||
program.
|
||||
|
||||
All files for the example are in the `example1_c` folder. The executable built with
|
||||
CMake reads the coordinates of two polytopes from the input files,
|
||||
respectively userP.dat and userQ.dat, and computes the minimum distance
|
||||
between them.
|
||||
|
||||
Notice that the input files must be in the folder from which the executable
|
||||
is launched, otherwise an error is returned.
|
||||
|
||||
You can edit the coordinates in the input file to test different
|
||||
polytopes; just remember to edit also the first number in the files
|
||||
that corresponds to the numbers of vertices that the program will read.
|
||||
|
||||
### Matlab
|
||||
This example illustrates how to invoke openGJK as a regular built-in
|
||||
Matlab function.
|
||||
|
||||
Open Matlab and cd into the `example2_mex` folder. By running the
|
||||
script `runme.m`, Matlab will first compile a mex file (telling you
|
||||
about the name of the mex file generated) and will call the script
|
||||
`main.m`. This invokes openGJK within Matlab and illustrates the
|
||||
result.
|
||||
|
||||
The mex file may be copied and called from any other Matlab project.
|
||||
|
||||
### C# #
|
||||
This example illustrates how to invoke openGJK in an applications written in C#.
|
||||
The only file required is in the `example3_csharp` folder. This can be compiled in Unix
|
||||
with mono, or in Windows using Visual Studio. Notice that, however, the openGJK library
|
||||
is compiled for a specific architecture (usually x64), and this breaks the portability
|
||||
of the .NET application compiled in this example.
|
||||
|
||||
Below are the steps for compiling the C# application on Windows and Linux. Both
|
||||
procedures assume the dynamic library of openGJK has been already compiled.
|
||||
|
||||
#### Compile on Windows
|
||||
1. Move into the folder `example3_csharp` and create a new folder `example3`.
|
||||
2. Copy into this folder the openGJK library or make it available in any directory.
|
||||
3. Open Visual Studio and create a new project. As project type select **Console App (.NET Framework)**.
|
||||
4. Add to this project the `main.cs` file
|
||||
5. Set x64 as the target platform, compile the application and run it.
|
||||
|
||||
|
||||
#### Compile on Linux
|
||||
1. Move into the folder `example3_csharp` and create a new folder `example3`.
|
||||
2. Copy into this folder the openGJK library or install is so that is available in any directory.
|
||||
3. Move into that new folder and open a terminal.
|
||||
4. Type `mcs -out:example3demo -d:UNIX ../main.cs`
|
||||
5. Run the example by typing `mono example3demo`
|
||||
|
||||
|
||||
|
||||
|
||||
## Repository content
|
||||
This repository contains the following files and folders:
|
||||
|
||||
```
|
||||
│ CMakeLists.txt
|
||||
│ README.md
|
||||
│
|
||||
├───doc
|
||||
│ openGJKcustomfooter.html
|
||||
│ openGJKcustomheader.html
|
||||
│ openGJKcustomstyle.css
|
||||
│ Doxyfile
|
||||
│ oxfordLogo.jpg
|
||||
│
|
||||
├───example1_c
|
||||
│ CMakeLists.txt
|
||||
│ main.c
|
||||
│ userP.dat
|
||||
│ userQ.dat
|
||||
│
|
||||
├───example2_mex
|
||||
│ main.m
|
||||
│ runme.m
|
||||
│
|
||||
├───example3_csharp
|
||||
│ main.cs
|
||||
│
|
||||
└───lib
|
||||
│ CMakeLists.txt
|
||||
│
|
||||
├───ext
|
||||
│ predicates.c
|
||||
│ predicates.h
|
||||
│
|
||||
├───include
|
||||
│ └───openGJK
|
||||
│ openGJK.h
|
||||
│
|
||||
└───src
|
||||
openGJK.c
|
||||
```
|
||||
|
||||
## Where to go next?
|
||||
|
||||
A clear presentation of the GJK algorithm can be found in the
|
||||
book by **Van der Bergen** *Collision Detection in Interactive 3D
|
||||
Environments*, edited by Elsevier.
|
||||
|
||||
More details about the GJK algorithm can be found in the original paper
|
||||
from Gilbert, Johnson and Keerthi [A fast procedure for computing the distance between complex objects in three-dimensional space](http://ieeexplore.ieee.org/document/2083/?arnumber=2083).
|
||||
|
||||
OpenGJK implements the GJK algorithm as described in: [Improving the GJK Algorithm for Faster and More Reliable Distance
|
||||
Queries Between Convex Objects. ACM Trans. on Graph. 2017 ](https://dl.acm.org/citation.cfm?id=3083724). Refer to this papar for further details on the method.
|
||||
|
||||
|
||||
|
||||
## Licence
|
||||
|
||||
This open-source edition of openGJK is released under the terms of
|
||||
[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) License.
|
||||
This means that any software created with this library you must comply
|
||||
with the terms of this licence. If you are seeking another licence please
|
||||
contact the author at the address at the end of this file.
|
||||
|
||||
openGJK may use the geometric predicates from *Routines for Arbitrary
|
||||
Precision Floating-point Arithmetic*, by Jonathan Richard Shewchuk,
|
||||
whose source code is included in the file predicates.c of this
|
||||
repository for convenience.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
openGJK, Copyright (c) 2018
|
||||
|
||||
Impact Engineering Laboratory
|
||||
Department of Engineering Science
|
||||
University of Oxford
|
||||
Parks Road, Oxford, OX1 3PJ
|
||||
|
||||
mattia.montanari@eng.ox.ac.uk
|
||||
------------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,21 @@
|
|||
<!-- HTML footer for doxygen 1.8.14-->
|
||||
<!-- start footer part -->
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
$navpath
|
||||
<li class="footer">$generatedby
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
$generatedby  <a href="http://www.doxygen.org/index.html">
|
||||
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
|
||||
</a> $doxygenversion
|
||||
</small></address>
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen 1.8.14"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>openGJK: Main Page</title>
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="dynsections.js"></script>
|
||||
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="search/searchdata.js"></script>
|
||||
<script type="text/javascript" src="search/search.js"></script>
|
||||
<link href="openGJKcustomstyle.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectlogo"><img alt="Logo" src="oxforduni.jpg" height="100px"/></td>
|
||||
<td id="projectalign" style="padding-left: 2.5em;">
|
||||
<div id="projectname">openGJK
|
||||
 <span id="projectnumber">v 1.0</span>
|
||||
</div>
|
||||
<div id="projectbrief">Fast and reliable distance queries in 3D between convex polytopes.</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- end header part -->
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -0,0 +1,28 @@
|
|||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
# ##### # # # #
|
||||
# #### ##### ###### # # # # # # # #
|
||||
# # # # # # ## # # # # # #
|
||||
# # # # # ##### # # # # #### # ### #
|
||||
# # # ##### # # # # # # # # # # #
|
||||
# # # # # # ## # # # # # # #
|
||||
# #### # ###### # # ##### ##### # # #
|
||||
# #
|
||||
# Mattia Montanari | University of Oxford 2018 #
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
|
||||
|
||||
project(openGJKdemo)
|
||||
|
||||
message( "[${CMAKE_PROJECT_NAME}] Compiling the executable ..")
|
||||
|
||||
# Set source file
|
||||
set(SOURCE_FILES main.c )
|
||||
|
||||
# Create the executable
|
||||
add_executable(demo ${SOURCE_FILES})
|
||||
|
||||
# Link to openGJK
|
||||
target_link_libraries(demo openGJKlib )
|
||||
|
||||
# Report
|
||||
message( ".. executable DONE!")
|
|
@ -0,0 +1,159 @@
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
* ##### # # # *
|
||||
* #### ##### ###### # # # # # # # *
|
||||
* # # # # # ## # # # # # *
|
||||
* # # # # ##### # # # # #### # ### *
|
||||
* # # ##### # # # # # # # # # # *
|
||||
* # # # # # ## # # # # # # *
|
||||
* #### # ###### # # ##### ##### # # *
|
||||
* *
|
||||
* Mattia Montanari | University of Oxford 2018 *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
* *
|
||||
* This file runs an example to illustrate how to invoke the openGJK lib *
|
||||
* within a C program. An executable called 'demo' can be compiled with *
|
||||
* CMake. This reads the coordinates of two polytopes from the input *
|
||||
* files userP.dat and userQ.dat, respectively, and returns the minimum *
|
||||
* distance between them computed using the openGJK library. *
|
||||
* *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/**
|
||||
* @file main.c
|
||||
* @author Mattia Montanari
|
||||
* @date April 2018
|
||||
* @brief File illustrating an application that invokes openGJK.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* For importing openGJK this is Step 1: include header in subfolder. */
|
||||
#include "openGJK/openGJK.h"
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
#define fscanf_s fscanf
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function for reading input file with body's coordinates.
|
||||
*
|
||||
*/
|
||||
int readinput ( const char *inputfile, double ***pts, int * out ) {
|
||||
int npoints = 0;
|
||||
int idx = 0;
|
||||
FILE *fp;
|
||||
|
||||
/* Open file. */
|
||||
#ifdef WIN32
|
||||
errno_t err;
|
||||
if ((err = fopen_s(&fp, inputfile, "r")) != 0) {
|
||||
#else
|
||||
if ((fp = fopen(inputfile, "r")) == NULL) {
|
||||
#endif
|
||||
fprintf(stdout, "ERROR: input file %s not found!\n", inputfile);
|
||||
fprintf(stdout, " -> The file must be in the folder from which this program is launched\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read number of input vertices. */
|
||||
if (fscanf_s(fp, "%1d", &npoints) != 1)
|
||||
return 1;
|
||||
|
||||
/* Allocate memory. */
|
||||
double **arr = (double **)malloc(npoints * sizeof(double *));
|
||||
for (int i=0; i<npoints; i++)
|
||||
arr[i] = (double *)malloc(3 * sizeof(double));
|
||||
|
||||
/* Read and store vertices' coordinates. */
|
||||
for (idx = 0; idx < npoints; idx++)
|
||||
{
|
||||
if (fscanf_s(fp, "%lf %lf %lf\n", &arr[idx][0], &arr[idx][1], &arr[idx][2]) != 3 )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Close file. */
|
||||
fclose(fp);
|
||||
|
||||
/* Pass pointers. */
|
||||
*pts = arr;
|
||||
*out = idx;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main program of example1_c (described in Section 3.1 of the paper).
|
||||
*
|
||||
*/
|
||||
int main() {
|
||||
/* Squared distance computed by openGJK. */
|
||||
double dd;
|
||||
/* Structure of simplex used by openGJK. */
|
||||
struct simplex s;
|
||||
/* Number of vertices defining body 1 and body 2, respectively. */
|
||||
int nvrtx1,
|
||||
nvrtx2;
|
||||
/* Structures of body 1 and body 2, respectively. */
|
||||
struct bd bd1;
|
||||
struct bd bd2;
|
||||
/* Specify name of input files for body 1 and body 2, respectively. */
|
||||
char inputfileA[40] = "userP.dat",
|
||||
inputfileB[40] = "userQ.dat";
|
||||
/* Pointers to vertices' coordinates of body 1 and body 2, respectively. */
|
||||
double (**vrtx1) = NULL,
|
||||
(**vrtx2) = NULL;
|
||||
|
||||
/* For importing openGJK this is Step 2: adapt the data structure for the
|
||||
* two bodies that will be passed to the GJK procedure. */
|
||||
|
||||
/* Import coordinates of object 1. */
|
||||
if (readinput ( inputfileA, &vrtx1, &nvrtx1 ))
|
||||
return (1);
|
||||
bd1.coord = vrtx1;
|
||||
bd1.numpoints = nvrtx1;
|
||||
|
||||
/* Import coordinates of object 2. */
|
||||
if (readinput ( inputfileB, &vrtx2, &nvrtx2 ))
|
||||
return (1);
|
||||
bd2.coord = vrtx2;
|
||||
bd2.numpoints = nvrtx2;
|
||||
|
||||
/* Initialise simplex as empty */
|
||||
s.nvrtx = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Verify input of body A. */
|
||||
for (int i = 0; i < bd1.numpoints; ++i) {
|
||||
printf ( "%.2f ", vrtx1[i][0]);
|
||||
printf ( "%.2f ", vrtx1[i][1]);
|
||||
printf ( "%.2f\n", bd1.coord[i][2]);
|
||||
}
|
||||
|
||||
/* Verify input of body B. */
|
||||
for (int i = 0; i < bd2.numpoints; ++i) {
|
||||
printf ( "%.2f ", bd2.coord[i][0]);
|
||||
printf ( "%.2f ", bd2.coord[i][1]);
|
||||
printf ( "%.2f\n", bd2.coord[i][2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For importing openGJK this is Step 3: invoke the GJK procedure. */
|
||||
/* Compute squared distance using GJK algorithm. */
|
||||
dd = gjk (bd1, bd2, &s);
|
||||
|
||||
/* Print distance between objects. */
|
||||
printf ("Distance between bodies %f\n", dd);
|
||||
|
||||
/* Free memory */
|
||||
for (int i=0; i<bd1.numpoints; i++)
|
||||
free(bd1.coord[i]);
|
||||
free(bd1.coord);
|
||||
for (int i=0; i<bd2.numpoints; i++)
|
||||
free(bd2.coord[i]);
|
||||
free(bd2.coord);
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
9
|
||||
0.0 5.5 0.0
|
||||
2.3 1.0 -2.0
|
||||
8.1 4.0 2.4
|
||||
4.3 5.0 2.2
|
||||
2.5 1.0 2.3
|
||||
7.1 1.0 2.4
|
||||
1.0 1.5 0.3
|
||||
3.3 0.5 0.3
|
||||
6.0 1.4 0.2
|
|
@ -0,0 +1,10 @@
|
|||
9
|
||||
-0.0 -5.5 0.0
|
||||
-2.3 -1.0 2.0
|
||||
-8.1 -4.0 -2.4
|
||||
-4.3 -5.0 -2.2
|
||||
-2.5 -1.0 -2.3
|
||||
-7.1 -1.0 -2.4
|
||||
-1.0 -1.5 -0.3
|
||||
-3.3 -0.5 -0.3
|
||||
-6.0 -1.4 -0.2
|
|
@ -0,0 +1,60 @@
|
|||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
% ##### # # # %
|
||||
% #### ##### ###### # # # # # # # %
|
||||
% # # # # # ## # # # # # %
|
||||
% # # # # ##### # # # # #### # ### %
|
||||
% # # ##### # # # # # # # # # # %
|
||||
% # # # # # ## # # # # # # %
|
||||
% #### # ###### # # ##### ##### # # %
|
||||
% %
|
||||
% Mattia Montanari | University of Oxford 2018 %
|
||||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
% %
|
||||
% This file runs an example to illustrate how to invoke the openGJK lib %
|
||||
% withing Matlab. It that assumes a mex file openGJK is availalbe, see %
|
||||
% the runme.m script for information on how to compile it. %
|
||||
% The example computes the minimum distance between two polytopes in 3D, %
|
||||
% A and B, both defined as a list of points. %
|
||||
% %
|
||||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
|
||||
% DEFINE BODY A AS 3xN MATRIX, WHERE N IS THE NUMBER OF VERTICES OF BODY A
|
||||
A = [ 0.0 2.3 8.1 4.3 2.5 7.1 1.0 3.3 6.0
|
||||
5.5 1.0 4.0 5.0 1.0 1.0 1.5 0.5 1.4
|
||||
0.0 -2.0 2.4 2.2 2.3 2.4 0.3 0.3 0.2];
|
||||
|
||||
% DEFINE BODY B IN THE OPPOSITE QUADRANT OF BODY A
|
||||
B = -A;
|
||||
|
||||
% COMPUTE MINIMUM DISTANCE AND RETURN VALUE
|
||||
dist = openGJK( A, B );
|
||||
fprintf('The minimum distance between A and B is %.2f\n',dist);
|
||||
|
||||
% VISUALISE RESULTS
|
||||
% .. create new figure
|
||||
figure('units','centimeters', 'WindowStyle','normal', 'color','w',...
|
||||
'Position',[0 8.5 9 6],'defaultAxesColorOrder',parula,...
|
||||
'Renderer','opengl')
|
||||
% .. adjust properties
|
||||
axis equal tight off; hold all;
|
||||
% .. display body A
|
||||
DT = delaunayTriangulation(A');
|
||||
[K,~] = convexHull(DT);
|
||||
trisurf(K,DT.Points(:,1),DT.Points(:,2),DT.Points(:,3),...
|
||||
'EdgeColor','none','FaceColor',[.4 1 .9 ],...
|
||||
'FaceLighting','flat' )
|
||||
% .. display body B
|
||||
DT = delaunayTriangulation(B');
|
||||
[K,~] = convexHull(DT);
|
||||
trisurf(K,DT.Points(:,1),DT.Points(:,2),DT.Points(:,3),...
|
||||
'EdgeColor','none','FaceColor',[.4 1 .8 ],...
|
||||
'FaceLighting','flat' )
|
||||
% .. represent the computed distance as a sphere
|
||||
[x,y,z] = sphere(100);
|
||||
surf(x.*dist/2,y.*dist/2,z.*dist/2,'facecolor',[.9 .9 .9],...
|
||||
'EdgeColor','none','FaceLighting','flat','SpecularColorReflectance',0,...
|
||||
'SpecularStrength',1,'SpecularExponent',10,'facealpha',.7)
|
||||
% ... adjust point of view
|
||||
view(42,21)
|
||||
% ... add light
|
||||
light('Position',[5 -10 20],'Style','local');
|
|
@ -0,0 +1,61 @@
|
|||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
% ##### # # # %
|
||||
% #### ##### ###### # # # # # # # %
|
||||
% # # # # # ## # # # # # %
|
||||
% # # # # ##### # # # # #### # ### %
|
||||
% # # ##### # # # # # # # # # # %
|
||||
% # # # # # ## # # # # # # %
|
||||
% #### # ###### # # ##### ##### # # %
|
||||
% %
|
||||
% Mattia Montanari | University of Oxford 2018 %
|
||||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
% %
|
||||
% This file compiles a mex function from the openGJK library and runs an %
|
||||
% example. If the mex function cannot be compiled an error is returned. %
|
||||
% %
|
||||
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %
|
||||
|
||||
% CLEAR ALL VARIABLES
|
||||
clearvars
|
||||
|
||||
% SELECT OPTIMISATION FLAG - FASTER BUT NOT SUITABLE FOR DEBUGGING
|
||||
if 0
|
||||
optflug = '-g'; %#ok<*UNRCH>
|
||||
else
|
||||
optflug = '-O';
|
||||
end
|
||||
% SELECT SILET COMPILATION MODE.
|
||||
if 1
|
||||
silflag = '-silent';
|
||||
else
|
||||
silflag = '-v';
|
||||
end
|
||||
|
||||
% TRY COMPILING MEX FILE
|
||||
fprintf('Compiling mex function... ')
|
||||
try
|
||||
mex('../lib/src/openGJK.c',... % Source of openGJK
|
||||
'-largeArrayDims', ... % Support large arrays
|
||||
optflug, ... % Compiler flag for debug/optimisation
|
||||
'-I../lib/include',... % Folder to header files
|
||||
'-outdir', pwd,... % Ouput directory for writing mex function
|
||||
'-output', 'openGJK',... % Name of ouput mex file
|
||||
'-DMATLABDOESMEXSTUFF',... % Define variable for mex function in source files
|
||||
silflag ) % Silent/verbose flag
|
||||
|
||||
% File compiled without errors. Return path and name of mex file
|
||||
fprintf('completed!\n')
|
||||
fprintf('The following mex file has been generated:')
|
||||
fprintf('\t%s\n',[pwd,filesep,'openGJK.',mexext])
|
||||
catch
|
||||
% Build failed, refer to documentation
|
||||
fprintf('\n\n ERROR DETECTED! Mex file cannot be compiled.\n')
|
||||
fprintf('\tFor more information, see ')
|
||||
fprintf('<a href="http://www.mathworks.com/help/matlab/ref/mex.html">this documentation page</a>.\n\n')
|
||||
return
|
||||
end
|
||||
|
||||
% RUN EXAMPLE
|
||||
fprintf('Running example... ')
|
||||
main
|
||||
fprintf('completed!\n')
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class Tester
|
||||
{
|
||||
|
||||
|
||||
#if UNIX
|
||||
[DllImport("libopenGJKlib.so", EntryPoint="csFunction", CallingConvention = CallingConvention.StdCall)]
|
||||
#else
|
||||
[DllImport("openGJKlib", EntryPoint = "csFunction", CallingConvention = CallingConvention.StdCall)]
|
||||
#endif
|
||||
static extern double gjk(int na, double [,] ia, int nb, double [,] ib);
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
double dist;
|
||||
// Define array A with coordinates
|
||||
int nCoordsA = 9;
|
||||
var inCoordsA = new double[3,9] { {0.0 , 2.3 , 8.1 , 4.3 ,2.5 , 7.1 , 1.0 , 3.3 , 6.0} , { 5.5 , 1.0 , 4.0 , 5.0 ,1.0, 1.0, 1.5, 0.5 , 1.4} ,{ 0.0 , -2.0, 2.4, 2.2, 2.3 , 2.4 , 0.3 , 0.3 , 0.2} };
|
||||
|
||||
// Define array B with coordinates
|
||||
int nCoordsB = 9;
|
||||
var inCoordsB = new double[3,9] { {-0.0 , -2.3 , -8.1 , -4.3 ,-2.5 , -7.1 , -1.0 , -3.3 , -6.0} , { -5.5 , -1.0 ,- 4.0 ,- 5.0 ,-1.0, -1.0, -1.5, -0.5 , -1.4} ,{ -0.0 , 2.0, -2.4, -2.2, -2.3 , -2.4 , -0.3 , -0.3 , -0.2} };
|
||||
|
||||
// Invoke GJK to compute distance
|
||||
dist = gjk( nCoordsA, inCoordsA, nCoordsB, inCoordsB );
|
||||
|
||||
// Output results
|
||||
var s = string.Format("{0:0.##}", dist);
|
||||
var message = string.Format("The distance between {0} is {1}","A and B",s);
|
||||
Console.WriteLine(message);
|
||||
Console.WriteLine("Press any key to exit");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
# ##### # # # #
|
||||
# #### ##### ###### # # # # # # # #
|
||||
# # # # # # ## # # # # # #
|
||||
# # # # # ##### # # # # #### # ### #
|
||||
# # # ##### # # # # # # # # # # #
|
||||
# # # # # # ## # # # # # # #
|
||||
# #### # ###### # # ##### ##### # # #
|
||||
# #
|
||||
# Mattia Montanari | University of Oxford 2018 #
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
|
||||
|
||||
|
||||
project (openGJKlib)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
# SELECT USER OPTIONS
|
||||
option(VERSION_ACCURATE "Reduce speed to maximise accuracy (OFF)"
|
||||
OFF )
|
||||
|
||||
# APPLY USER OPTIONS
|
||||
IF(VERSION_ACCURATE)
|
||||
set(USE_PREDICATES ON)
|
||||
set(openGJK_VERSION "Accurate")
|
||||
ELSE()
|
||||
set(USE_PREDICATES OFF)
|
||||
set(openGJK_VERSION "Fast")
|
||||
ENDIF()
|
||||
|
||||
# COMPILE
|
||||
message( "[${CMAKE_PROJECT_NAME}] Compiling ..")
|
||||
message(STATUS "Version (Accurate,Fast): " ${openGJK_VERSION} )
|
||||
message(STATUS "Build type (Debug,Release): " ${CMAKE_BUILD_TYPE} )
|
||||
|
||||
# Select source files
|
||||
set( SOURCE_FILES src/openGJK.c )
|
||||
set( SOURCE_HEADS include/openGJK/openGJK.h)
|
||||
|
||||
IF(USE_PREDICATES)
|
||||
# for adpative floating-point artim.
|
||||
set( SOURCE_FILES ${SOURCE_FILES} ext/predicates.c)
|
||||
set( SOURCE_HEADS ${SOURCE_HEADS} ext/predicates.h)
|
||||
# Add flag for adpative floating-point artim.
|
||||
add_definitions(-DADAPTIVEFP)
|
||||
ENDIF()
|
||||
|
||||
# Create the (dynamic) library
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${SOURCE_HEADS})
|
||||
add_definitions(-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE)
|
||||
|
||||
# Link include file
|
||||
target_include_directories( ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
IF(USE_PREDICATES)
|
||||
# for adpative floating-point artim.
|
||||
target_include_directories( ${PROJECT_NAME}
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/ext
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
# Report
|
||||
message( ".. DONE!")
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Created by mmontanari on 29/06/16.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef CGJK_PREDICATES_H
|
||||
#define CGJK_PREDICATES_H
|
||||
|
||||
#endif //CGJK_PREDICATES_H
|
||||
|
||||
extern double orient3d(
|
||||
double *pa,
|
||||
double *pb,
|
||||
double *pc,
|
||||
double *pd
|
||||
);
|
||||
|
||||
extern double orient2d(
|
||||
double *pa,
|
||||
double *pb,
|
||||
double *pc
|
||||
);
|
||||
|
||||
extern void exactinit();
|
|
@ -0,0 +1,63 @@
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
* ##### # # # *
|
||||
* #### ##### ###### # # # # # # # *
|
||||
* # # # # # ## # # # # # *
|
||||
* # # # # ##### # # # # #### # ### *
|
||||
* # # ##### # # # # # # # # # # *
|
||||
* # # # # # ## # # # # # # *
|
||||
* #### # ###### # # ##### ##### # # *
|
||||
* *
|
||||
* Mattia Montanari | University of Oxford 2018 *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
* *
|
||||
* This is the header file for the openGJK.c file. It defines the openGJK *
|
||||
* function and it two important structures: bd and simplex. *
|
||||
* *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __OPENGJK_H__
|
||||
#define __OPENGJK_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "math.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Macro that implements the CompareSign function (see paper).
|
||||
*/
|
||||
#define SAMESIGN( a, b ) ( (a>0) == (b>0) )
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure of a body.
|
||||
*/
|
||||
struct bd {
|
||||
int numpoints; /**< Number of points defining the body. */
|
||||
double **coord; /**< Pointer to pointer to the points' coordinates. */
|
||||
double s [3]; /**< Support mapping computed last. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure for a simplex.
|
||||
*/
|
||||
struct simplex {
|
||||
int nvrtx ; /**< Number of simplex's vertices. */
|
||||
double vrtx [4][3]; /**< Coordinates of simplex's vertices. */
|
||||
int wids [4]; /**< Label of the simplex's vertices. */
|
||||
double lambdas [4]; /**< Barycentric coordiantes for each vertex. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief The GJK algorithm which returns the minimum distance between
|
||||
* two bodies.
|
||||
*/
|
||||
extern double gjk( struct bd, struct bd, struct simplex * ) ;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue