#region License Information /* HeuristicLab * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab 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, or * (at your option) any later version. * * HeuristicLab 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 the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers { public static class QhullWrapper { [System.Runtime.InteropServices.DllImportAttribute("HeuristicLab.qhull.dll", EntryPoint = "qhull_volume", CallingConvention = CallingConvention.Cdecl)] public static extern double qhull_volume(int dim, int numpoints, [In]double[] data); [System.Runtime.InteropServices.DllImportAttribute("HeuristicLab.qhull.dll", EntryPoint = "qhull_convex_hull", CallingConvention = CallingConvention.Cdecl)] public unsafe static extern IntPtr qhull_convex_hull(int dim, int numpoints, [In]double[] data, [Out] Int32* retCode, [Out] Int32* nrOfFacets); [System.Runtime.InteropServices.DllImportAttribute("HeuristicLab.qhull.dll", EntryPoint = "qhull_free", CallingConvention = CallingConvention.Cdecl)] public static extern void qhull_free(IntPtr data); public static double CalculateVolume(List points) { double result = 0.0; int dimension = points.First().Length; int numPoints = points.Count(); double[] data = new double[dimension * numPoints]; for (int i = 0; i < numPoints; i++) { for (int j = 0; j < dimension; j++) { data[i * dimension + j] = points[i][j]; } } result = qhull_volume(dimension, numPoints, data); return result; } public unsafe static List CalculateConvexHullIndices(List points) { int dimension = points.First().Length; int numPoints = points.Count(); List convexHullIndices = new List(); double[] data = new double[dimension * numPoints]; for (int i = 0; i < numPoints; i++) { for (int j = 0; j < dimension; j++) { data[i * dimension + j] = points[i][j]; } } IntPtr result = IntPtr.Zero; Int32 nrOfFacets = -1; Int32 retCode = 0; result = qhull_convex_hull(dimension, numPoints, data, &retCode, &nrOfFacets); if (result != IntPtr.Zero && retCode == 0) { try { var faces = new int[nrOfFacets * dimension]; Marshal.Copy(result, faces, 0, nrOfFacets * dimension); convexHullIndices.AddRange(faces.Distinct()); } finally { qhull_free(result); } } return convexHullIndices; } public static List Calculate(List points) { var ret = new List(); List indices = CalculateConvexHullIndices(points); foreach (var d in indices) { ret.Add(points[d]); } return ret; } } }