2022-07-09 14:10:45 -07:00
|
|
|
// _____ _ _ __ //
|
|
|
|
// / ____| | | |/ / //
|
|
|
|
// ___ _ __ ___ _ __ | | __ | | ' / //
|
|
|
|
// / _ \| '_ \ / _ \ '_ \| | |_ |_ | | < //
|
|
|
|
// | (_) | |_) | __/ | | | |__| | |__| | . \ //
|
|
|
|
// \___/| .__/ \___|_| |_|\_____|\____/|_|\_\ //
|
|
|
|
// | | //
|
|
|
|
// |_| //
|
|
|
|
// //
|
|
|
|
// Copyright 2022 Mattia Montanari, University of Oxford //
|
|
|
|
// //
|
|
|
|
// This program is free software: you can redistribute it and/or modify it under //
|
|
|
|
// the terms of the GNU General Public License as published by the Free Software //
|
|
|
|
// Foundation, either version 3 of the License. You should have received a copy //
|
|
|
|
// of the GNU General Public License along with this program. If not, visit //
|
|
|
|
// //
|
|
|
|
// https://www.gnu.org/licenses/ //
|
|
|
|
// //
|
|
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT //
|
|
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS //
|
|
|
|
// FOR A PARTICULAR PURPOSE. See GNU General Public License for details. //
|
|
|
|
|
|
|
|
/// @author Mattia Montanari
|
|
|
|
/// @date July 2022
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "openGJK/openGJK.h"
|
|
|
|
|
|
|
|
#define fscanf_s fscanf
|
|
|
|
|
|
|
|
/// @brief Function for reading input file with body's coordinates.
|
2023-02-13 05:35:05 -08:00
|
|
|
int
|
2023-04-02 03:06:21 -07:00
|
|
|
readinput(const char* inputfile, gkFloat*** pts, int* out) {
|
2022-07-09 14:10:45 -07:00
|
|
|
int npoints = 0;
|
|
|
|
int idx = 0;
|
2023-02-13 05:35:05 -08:00
|
|
|
FILE* fp;
|
2022-07-09 14:10:45 -07:00
|
|
|
|
|
|
|
/* 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. */
|
2023-02-13 05:35:05 -08:00
|
|
|
if (fscanf_s(fp, "%d", &npoints) != 1) {
|
2022-07-09 14:10:45 -07:00
|
|
|
return 1;
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
|
|
|
|
/* Allocate memory. */
|
2023-04-02 03:06:21 -07:00
|
|
|
gkFloat** arr = (gkFloat**)malloc(npoints * sizeof(gkFloat*));
|
2023-02-13 05:35:05 -08:00
|
|
|
for (int i = 0; i < npoints; i++) {
|
2023-04-02 03:06:21 -07:00
|
|
|
arr[i] = (gkFloat*)malloc(3 * sizeof(gkFloat));
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
|
|
|
|
/* Read and store vertices' coordinates. */
|
|
|
|
for (idx = 0; idx < npoints; idx++) {
|
2023-04-02 03:06:21 -07:00
|
|
|
#ifdef USE_32BITS
|
|
|
|
if (fscanf_s(fp, "%f %f %f\n", &arr[idx][0], &arr[idx][1], &arr[idx][2]) != 3) {
|
2022-07-09 14:10:45 -07:00
|
|
|
return 1;
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2023-04-02 03:06:21 -07:00
|
|
|
#else
|
2023-04-02 03:39:04 -07:00
|
|
|
if (fscanf_s(fp, "%lf %lf %lf\n", &arr[idx][0], &arr[idx][1], &arr[idx][2]) != 3) {
|
|
|
|
return 1;
|
|
|
|
}
|
2023-04-02 03:06:21 -07:00
|
|
|
#endif
|
2022-07-09 14:10:45 -07:00
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
*pts = arr;
|
|
|
|
*out = idx;
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Main program of example1_c (described in Section 3.1 of the paper).
|
|
|
|
*
|
|
|
|
*/
|
2023-02-13 05:35:05 -08:00
|
|
|
int
|
|
|
|
main() {
|
2022-07-09 14:10:45 -07:00
|
|
|
/* Squared distance computed by openGJK. */
|
2023-04-02 03:06:21 -07:00
|
|
|
gkFloat dd;
|
2022-07-09 14:10:45 -07:00
|
|
|
/* Structure of simplex used by openGJK. */
|
|
|
|
gkSimplex s;
|
|
|
|
/* Number of vertices defining body 1 and body 2, respectively. */
|
|
|
|
int nvrtx1, nvrtx2;
|
|
|
|
/* Structures of body 1 and body 2, respectively. */
|
|
|
|
gkPolytope bd1;
|
|
|
|
gkPolytope 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. */
|
2023-04-02 03:06:21 -07:00
|
|
|
gkFloat(**vrtx1) = NULL, (**vrtx2) = NULL;
|
2022-07-09 14:10:45 -07:00
|
|
|
|
|
|
|
/* 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. */
|
2023-02-13 05:35:05 -08:00
|
|
|
if (readinput(inputfileA, &vrtx1, &nvrtx1)) {
|
2022-07-09 14:10:45 -07:00
|
|
|
return (1);
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
bd1.coord = vrtx1;
|
|
|
|
bd1.numpoints = nvrtx1;
|
|
|
|
|
|
|
|
/* Import coordinates of object 2. */
|
2023-02-13 05:35:05 -08:00
|
|
|
if (readinput(inputfileB, &vrtx2, &nvrtx2)) {
|
2022-07-09 14:10:45 -07:00
|
|
|
return (1);
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
bd2.coord = vrtx2;
|
|
|
|
bd2.numpoints = nvrtx2;
|
|
|
|
|
|
|
|
/* Initialise simplex as empty */
|
|
|
|
s.nvrtx = 0;
|
|
|
|
|
|
|
|
/* For importing openGJK this is Step 3: invoke the GJK procedure. */
|
|
|
|
/* Compute squared distance using GJK algorithm. */
|
|
|
|
dd = compute_minimum_distance(bd1, bd2, &s);
|
|
|
|
|
|
|
|
/* Print distance between objects. */
|
|
|
|
printf("Distance between bodies %f\n", dd);
|
|
|
|
|
|
|
|
/* Free memory */
|
2023-02-13 05:35:05 -08:00
|
|
|
for (int i = 0; i < bd1.numpoints; i++) {
|
2022-07-09 14:10:45 -07:00
|
|
|
free(bd1.coord[i]);
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
free(bd1.coord);
|
2023-02-13 05:35:05 -08:00
|
|
|
for (int i = 0; i < bd2.numpoints; i++) {
|
2022-07-09 14:10:45 -07:00
|
|
|
free(bd2.coord[i]);
|
2023-02-13 05:35:05 -08:00
|
|
|
}
|
2022-07-09 14:10:45 -07:00
|
|
|
free(bd2.coord);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|