Initial release

This commit is contained in:
Jake
2026-05-11 19:29:55 +01:00
commit d4d1215874
16967 changed files with 4075897 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
qhull/src/libqhull
This directory contains the non-reentrant version of qhull, libqhull.
New code should use the reentrant version of qhull (libqhull_r).
It allows multiple instances of qhull to run at the same time. On
modern architectures, it is nearly as fast as libqhull.
Qhull programs may be built with either library. Each program has a
reentrant version (e.g., qconvex_r.c) and a non-reentrant
version (qconvex.c). The programs, rbox, qconvex, qdelaunay, qhalf,
and qvoronoi, are built with libqhull. The qhull program is built
with libqhull_r.
Qhull's C++ interface requires libqhull_r. If you previously used the
C++ interface, you will need to update your code. See Changes.txt for
suggestions.
The C code in libqhull looks unusual because of the 'qh' macro. The 'qh'
macro controls access to Qhull's global data structure, qhT. If
'qh_QHpointer' is defined, 'qh' is 'qh_qh->' and 'qh_qh' is defined as
'qhT *qh_qh', otherwise 'qh' is 'qh_qh.' and 'qh_qh' is defined as
'qhT qh_qh'.
libqhull will be supported indefinitely. The qh_QHpointer variation
of libqhull will be not be retested each release. It is replaced by
libqhull_r.

View File

@@ -0,0 +1,240 @@
# Simple gcc Makefile for non-reentrant qhull and rbox (default gcc/g++)
#
# make help
# See README.txt and ../../Makefile
#
# Variables
# BINDIR directory where to copy executables
# DESTDIR destination directory for 'make install'
# DOCDIR directory where to copy html documentation
# INCDIR directory where to copy headers
# LIBDIR directory where to copy libraries
# MANDIR directory where to copy manual pages
# PRINTMAN command for printing manual pages
# PRINTC command for printing C files
# CC ANSI C or C++ compiler
# CC_OPTS1 options used to compile .c files
# CC_OPTS2 options used to link .o files
# CC_OPTS3 options to build shared libraries
#
# LIBQHULL_OBJS .o files for linking
# LIBQHULL_HDRS .h files for printing
# CFILES .c files for printing
# DOCFILES documentation files
# FILES miscellaneous files for printing
# TFILES .txt versions of html files
# FILES all other files
# LIBQHULL_OBJS specifies the object files of libqhullstatic_r.a
#
# Results
# rbox Generates points sets for qhull, qconvex, etc.
# qhull Computes convex hulls and related structures
# qconvex, qdelaunay, qhalf, qvoronoi
# Specializations of qhull for each geometric structure
# libqhullstatic_r.a Static library for non-reentrant qhull
# testqset_r Standalone test of non-reentrant qset_r.c with mem_r.c
# user_eg An example of using qhull (non-reentrant)
# user_eg2 An example of using qhull (non-reentrant)
#
# Make targets
# make Build results using gcc or another compiler
# make clean Remove object files
# make cleanall Remove generated files
# make doc Print documentation
# make help
# make install Copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
# make new Rebuild qhull and rbox from source
# make printall Print all files
# make qtest Quick test of qset, rbox, and qhull
# make test Quck test of qhull, qconvex, etc.
#
# Do not replace tabs with spaces. Needed for build rules
# Unix line endings (\n)
# $Id: //main/2015/qhull/src/libqhull/Makefile#8 $
DESTDIR = /usr/local
BINDIR = $(DESTDIR)/bin
INCDIR = $(DESTDIR)/include
LIBDIR = $(DESTDIR)/lib
DOCDIR = $(DESTDIR)/share/doc/qhull
MANDIR = $(DESTDIR)/share/man/man1
# if you do not have enscript, try a2ps or just use lpr. The files are text.
PRINTMAN = enscript -2rl
PRINTC = enscript -2r
# PRINTMAN = lpr
# PRINTC = lpr
#for Gnu's gcc compiler, -O3 for optimization, -g for debugging, -pg for profiling
# -fpic needed for gcc x86_64-linux-gnu. Not needed for mingw
CC = gcc
CC_OPTS1 = -O3 -ansi -I../../src -fpic $(CC_WARNINGS)
# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
#CC = cc
#CC_OPTS1 = -Xc -v -fast -I../../src
# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
#CC = cc
#CC_OPTS1 = -ansi -O2 -I../../src
# for Next cc compiler with fat executable
#CC = cc
#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
# For loader, ld,
CC_OPTS2 = $(CC_OPTS1)
# Default targets for make
all: qhull_links qhull_all qtest
help:
head -n 50 Makefile
clean:
rm -f *.o
# Delete linked files from other directories [qhull_links]
rm -f qconvex.c unix.c qdelaun.c qhalf.c qvoronoi.c rbox.c
rm -f user_eg.c user_eg2.c testqset.c
cleanall: clean
rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
rm -f core user_eg user_eg2 testqset libqhullstatic.a
doc:
$(PRINTMAN) $(TXTFILES) $(DOCFILES)
install:
mkdir -p $(BINDIR)
mkdir -p $(DOCDIR)
mkdir -p $(INCDIR)/libqhull
mkdir -p $(MANDIR)
cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(BINDIR)
cp -p libqhullstatic.a $(LIBDIR)
cp -p ../../html/qhull.man $(MANDIR)/qhull.1
cp -p ../../html/rbox.man $(MANDIR)/rbox.1
cp -p ../../html/* $(DOCDIR)
cp *.h $(INCDIR)/libqhull
new: cleanall all
printall: doc printh printc printf
printh:
$(PRINTC) $(LIBQHULL_HDRS)
printc:
$(PRINTC) $(CFILES)
# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end. Better locality.
# Same definitions as ../../Makefile
LIBQHULLS_OBJS_1= global.o stat.o geom2.o poly2.o merge.o \
libqhull.o geom.o poly.o qset.o mem.o random.o
LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem.o userprintf.o io.o user.o
LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib.o userprintf_rbox.o
LIBQHULL_HDRS= user.h libqhull.h qhull_a.h geom.h \
io.h mem.h merge.h poly.h random.h \
qset.h stat.h
# CFILES ordered alphabetically after libqhull.c
CFILES= ../qhull/unix.c libqhull.c geom.c geom2.c global.c io.c \
mem.c merge.c poly.c poly2.c random.c rboxlib.c \
qset.c stat.c user.c usermem.c userprintf.c \
../qconvex/qconvex.c ../qdelaunay/qdelaun.c ../qhalf/qhalf.c ../qvoronoi/qvoronoi.c
TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
.c.o:
$(CC) -c $(CC_OPTS1) -o $@ $<
# Work around problems with ../ in Red Hat Linux
qhull_links:
# On MINSYS, 'ln -s' may create a copy instead of a symbolic link
[ -f qconvex.c ] || ln -s ../qconvex/qconvex.c
[ -f qdelaun.c ] || ln -s ../qdelaunay/qdelaun.c
[ -f qhalf.c ] || ln -s ../qhalf/qhalf.c
[ -f qvoronoi.c ] || ln -s ../qvoronoi/qvoronoi.c
[ -f rbox.c ] || ln -s ../rbox/rbox.c
[ -f testqset.c ] || ln -s ../testqset/testqset.c
[ -f unix.c ] || ln -s ../qhull/unix.c
[ -f user_eg.c ] || ln -s ../user_eg/user_eg.c
[ -f user_eg2.c ] || ln -s ../user_eg2/user_eg2.c
# compile qhull without using bin/libqhullstatic.a
qhull_all: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o user_eg.o user_eg2.o rbox.o testqset.o $(LIBQHULLS_OBJS)
$(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex.o
$(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun.o
$(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf.o
$(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi.o
$(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix.o
$(CC) -o rbox $(CC_OPTS2) -lm $(LIBQHULLS_OBJS) rbox.o
$(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg.o
$(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2.o usermem.o userprintf.o io.o
$(CC) -o testqset $(CC_OPTS2) -lm mem.o qset.o usermem.o testqset.o
-ar -rs libqhullstatic.a $(LIBQHULLS_OBJS)
#libqhullstatic.a is not needed for qhull
#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
#ranlib libqhullstatic.a
qtest:
@echo ============================================
@echo == make qtest ==============================
@echo ============================================
@echo -n "== "
@date
@echo
@echo Testing qset.c and mem.c with testqset
./testqset 10000
@echo Run the qhull smoketest
./rbox D4 | ./qhull
@echo ============================================
@echo == To smoketest qhull programs
@echo '== make test'
@echo ============================================
@echo
@echo ============================================
@echo == For all make targets
@echo '== make help'
@echo ============================================
@echo
test: qtest
@echo ==============================
@echo ========= qconvex ============
@echo ==============================
-./rbox 10 | ./qconvex Tv
@echo
@echo ==============================
@echo ========= qdelaunay ==========
@echo ==============================
-./rbox 10 | ./qdelaunay Tv
@echo
@echo ==============================
@echo ========= qhalf ==============
@echo ==============================
-./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
@echo
@echo ==============================
@echo ========= qvoronoi ===========
@echo ==============================
-./rbox 10 | ./qvoronoi Tv
@echo
@echo ==============================
@echo ========= user_eg ============
@echo == w/o shared library ========
@echo ==============================
-./user_eg
@echo
@echo ==============================
@echo ========= user_eg2 ===========
@echo ==============================
-./user_eg2
@echo
# end of Makefile

View File

@@ -0,0 +1,206 @@
#########################################################################
# Borland C++ 4.02 for Win32 and DOS Power Pack #
# Makefile for qhull and rbox #
# #
# make -fMborland all to produce qconvex, qhull, and rbox #
# make -fMborland user_eg to produce user_eg #
# make -fMborland user_eg2 to produce user_eg2 #
# make -fMborland new to rebuild qhull and rbox from source #
# make -fMborland clean to remove object files #
# make -fMborland cleanall to remove all generated files #
# make -fMborland test to test rbox and qhull #
# #
# Author: D. Zwick of Germany, C.B. Barber #
#########################################################################
CC = bcc32 # 32 bit compiler for DOS
# bcc32i - Intel's compiler
LINKER = $(CC) # bcc calls tlink32 with needed options
CFLAGS = -w- -A -O2
# -w- no warnings, bcc doesn't handle assigns in conditions
# -A Ansi standard
# -X no auto-dependency outputs
# -v debugging, use CCOPTS for both
# -O2 optimization
!if $d(_DPMI)
LFLAGS = -WX -w- # -WX loads DPMI library
!else
LFLAGS = -lap -lx -lc
# -lap 32-bit console application
# -lx no map file
# -lc case is significant
!endif
EXERB = rbox
EXEQH = qhull
EXEQC = qconvex
EXEQD = qdelaunay
EXEQV = qvoronoi
EXEQF = qhalf
EXEEG = user_eg
EXEEG2 = user_eg2
TMPFILE = BCC32tmp.cfg
OBJS1 = global.obj stat.obj geom2.obj poly2.obj merge.obj
OBJS2 = libqhull.obj geom.obj poly.obj qset.obj mem.obj
OBJS3 = random.obj usermem.obj userprintf.obj io.obj user.obj
OBJS4 = rboxlib.obj random.obj usermem.obj userprintf_rbox.obj
HFILES1 = libqhull.h stat.h qhull_a.h user.h
# General rules
.c.obj:
$(CC) -c $(CFLAGS) $<
# Default
all: $(EXERB) $(EXEQH) $(EXEQC) $(EXEQD) $(EXEQV) $(EXEQF) test
help:
@echo USAGE:
@echo "make all to produce qhull, rbox, qconvex, qdelaun, qvoronoi, qhalf"
@echo "make user_eg to produce user_eg"
@echo "make user_eg2 to produce user_eg2"
@echo "make new to rebuild qhull and rbox from source"
@echo "make clean to remove object files"
@echo "make cleanall to remove all generated file"
@echo "make test to test rbox and qhull"
@echo OPTIONS (default is 32-bit console app):
@echo "-D_DPMI for C++ 4.01 and DOS Power Pack"
# Executables
$(EXEQH): ..\..\bin\$(EXEQH).exe
@echo Made ..\..\bin\$(EXEQH).exe
unix.obj: ..\qhull\unix.c
..\..\bin\$(EXEQH).exe: unix.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo unix.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEQC): ..\..\bin\$(EXEQC).exe
@echo Made ..\..\bin\$(EXEQC).exe
qconvex.obj: ..\qconvex\qconvex.c
..\..\bin\$(EXEQC).exe: qconvex.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo qconvex.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEQD): ..\..\bin\$(EXEQD).exe
@echo Made ..\..\bin\$(EXEQD).exe
qdelaun.obj: ..\qdelaunay\qdelaun.c
..\..\bin\$(EXEQD).exe: qdelaun.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo qdelaun.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEQV): ..\..\bin\$(EXEQV).exe
@echo Made ..\..\bin\$(EXEQV).exe
qvoronoi.obj: ..\qvoronoi\qvoronoi.c
..\..\bin\$(EXEQV).exe: qvoronoi.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo qvoronoi.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEQF): ..\..\bin\$(EXEQF).exe
@echo Made ..\..\bin\$(EXEQF).exe
qhalf.obj: ..\qhalf\qhalf.c
..\..\bin\$(EXEQF).exe: qhalf.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo qhalf.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEEG): ..\..\bin\$(EXEEG).exe
@echo Made ..\..\bin\$(EXEEG).exe
user_eg.obj: ..\user_eg\user_eg.c
..\..\bin\$(EXEEG).exe: user_eg.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo user_eg.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXEEG2): ..\..\bin\$(EXEEG2).exe
@echo Made ..\..\bin\$(EXEEG2).exe
user_eg2.obj: ..\user_eg2\user_eg2.c
..\..\bin\$(EXEEG2).exe: user_eg2.obj $(OBJS1) $(OBJS2) $(OBJS3)
@echo user_eg2.obj > $(TMPFILE)
@echo $(OBJS1) >> $(TMPFILE)
@echo $(OBJS2) >> $(TMPFILE)
@echo $(OBJS3) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
$(EXERB): ..\..\bin\$(EXERB).exe
@echo Made ..\..\bin\$(EXERB).exe
rbox.obj: ..\rbox\rbox.c
..\..\bin\$(EXERB).exe: rbox.obj $(OBJS4)
@echo rbox.obj > $(TMPFILE)
@echo $(OBJS4) >> $(TMPFILE)
$(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
# Test rbox and qhull
test:
@..\..\bin\rbox D4 > test.x
@..\..\bin\qhull <test.x
@del test.x
# Clean up
clean:
@del *.obj
@del $(TMPFILE)
cleanall: clean
@del ..\..\bin\$(EXERB).exe
@del ..\..\bin\$(EXEQC).exe
@del ..\..\bin\$(EXEQD).exe
@del ..\..\bin\$(EXEQF).exe
@del ..\..\bin\$(EXEQH).exe
@del ..\..\bin\$(EXEQV).exe
@del ..\..\bin\$(EXEEG).exe
@del ..\..\bin\$(EXEEG2).exe
@del ..\q_test.x
@del ..\q_test.log.1
# Clean up and rebuild all
new: cleanall all
# Header file dependencies
libqhull.obj stat.obj user.obj global.obj usermem.obj userprintf.obj: $(HFILES1)
random.obj: libqhull.h random.h
geom.obj geom2.obj: $(HFILES1) geom.h
poly.obj poly2.obj: $(HFILES1) poly.h
io.obj: $(HFILES1) io.h
merge.obj: $(HFILES1) merge.h
mem.obj: mem.h
qset.obj: qset.h mem.h
unix.obj: libqhull.h user.h
qconvex.obj: libqhull.h user.h
qdelaun.obj: libqhull.h user.h
qhalf.obj: libqhull.h user.h
qvoronoi.obj: libqhull.h user.h
rbox.obj: user.h

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
geom.h
header file for geometric routines
see qh-geom.htm and geom.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/geom.h#1 $$Change: 1981 $
$DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
*/
#ifndef qhDEFgeom
#define qhDEFgeom 1
#include "libqhull.h"
/* ============ -macros- ======================== */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fabs_">-</a>
fabs_(a)
returns the absolute value of a
*/
#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fmax_">-</a>
fmax_(a,b)
returns the maximum value of a and b
*/
#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="fmin_">-</a>
fmin_(a,b)
returns the minimum value of a and b
*/
#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="maximize_">-</a>
maximize_(maxval, val)
set maxval to val if val is greater than maxval
*/
#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="minimize_">-</a>
minimize_(minval, val)
set minval to val if val is less than minval
*/
#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="det2_">-</a>
det2_(a1, a2,
b1, b2)
compute a 2-d determinate
*/
#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="det3_">-</a>
det3_(a1, a2, a3,
b1, b2, b3,
c1, c2, c3)
compute a 3-d determinate
*/
#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
- ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="dX">-</a>
dX( p1, p2 )
dY( p1, p2 )
dZ( p1, p2 )
given two indices into rows[],
compute the difference between X, Y, or Z coordinates
*/
#define dX( p1,p2 ) ( *( rows[p1] ) - *( rows[p2] ))
#define dY( p1,p2 ) ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
#define dZ( p1,p2 ) ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
#define dW( p1,p2 ) ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
/*============= prototypes in alphabetical order, infrequent at end ======= */
void qh_backnormal(realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
void qh_distplane(pointT *point, facetT *facet, realT *dist);
facetT *qh_findbest(pointT *point, facetT *startfacet,
boolT bestoutside, boolT isnewfacets, boolT noupper,
realT *dist, boolT *isoutside, int *numpart);
facetT *qh_findbesthorizon(boolT ischeckmax, pointT *point,
facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
facetT *qh_findbestnew(pointT *point, facetT *startfacet, realT *dist,
boolT bestoutside, boolT *isoutside, int *numpart);
void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
realT qh_getangle(pointT *vect1, pointT *vect2);
pointT *qh_getcenter(setT *vertices);
pointT *qh_getcentrum(facetT *facet);
realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
void qh_normalize(coordT *normal, int dim, boolT toporient);
void qh_normalize2(coordT *normal, int dim, boolT toporient,
realT *minnorm, boolT *ismin);
pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
void qh_setfacetplane(facetT *newfacets);
void qh_sethyperplane_det(int dim, coordT **rows, coordT *point0,
boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
void qh_sethyperplane_gauss(int dim, coordT **rows, pointT *point0,
boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
boolT qh_sharpnewfacets(void);
/*========= infrequently used code in geom2.c =============*/
coordT *qh_copypoints(coordT *points, int numpoints, int dimension);
void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
realT qh_determinant(realT **rows, int dim, boolT *nearzero);
realT qh_detjoggle(pointT *points, int numpoints, int dimension);
void qh_detroundoff(void);
realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
realT qh_distround(int dimension, realT maxabs, realT maxsumabs);
realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
realT qh_facetarea(facetT *facet);
realT qh_facetarea_simplex(int dim, coordT *apex, setT *vertices,
vertexT *notvertex, boolT toporient, coordT *normal, realT *offset);
pointT *qh_facetcenter(setT *vertices);
facetT *qh_findgooddist(pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
void qh_getarea(facetT *facetlist);
boolT qh_gram_schmidt(int dim, realT **rows);
boolT qh_inthresholds(coordT *normal, realT *angle);
void qh_joggleinput(void);
realT *qh_maxabsval(realT *normal, int dim);
setT *qh_maxmin(pointT *points, int numpoints, int dimension);
realT qh_maxouter(void);
void qh_maxsimplex(int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
realT qh_minabsval(realT *normal, int dim);
int qh_mindiff(realT *vecA, realT *vecB, int dim);
boolT qh_orientoutside(facetT *facet);
void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane);
coordT qh_pointdist(pointT *point1, pointT *point2, int dim);
void qh_printmatrix(FILE *fp, const char *string, realT **rows, int numrow, int numcol);
void qh_printpoints(FILE *fp, const char *string, setT *points);
void qh_projectinput(void);
void qh_projectpoints(signed char *project, int n, realT *points,
int numpoints, int dim, realT *newpoints, int newdim);
void qh_rotateinput(realT **rows);
void qh_rotatepoints(realT *points, int numpoints, int dim, realT **rows);
void qh_scaleinput(void);
void qh_scalelast(coordT *points, int numpoints, int dim, coordT low,
coordT high, coordT newhigh);
void qh_scalepoints(pointT *points, int numpoints, int dim,
realT *newlows, realT *newhighs);
boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp,
coordT *normal, coordT *offset, coordT *feasible);
coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible);
pointT *qh_voronoi_center(int dim, setT *points);
#endif /* qhDEFgeom */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,264 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Qhull functions, macros, and data structures</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
<hr>
<!-- Main text of document. -->
<h1>Qhull functions, macros, and data structures</h1>
<blockquote>
<p>The following sections provide an overview and index to
Qhull's functions, macros, and data structures.
Each section starts with an introduction.
See also <a href=../../html/qh-code.htm#library>Calling
Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
<p>Qhull uses the following conventions:</p>
<blockquote>
<ul>
<li>in code, global variables start with &quot;qh &quot;
<li>in documentation, global variables start with 'qh.'
<li>constants start with an upper case word
<li>important globals include an '_'
<li>functions, macros, and constants start with &quot;qh_&quot;</li>
<li>data types end in &quot;T&quot;</li>
<li>macros with arguments end in &quot;_&quot;</li>
<li>iterators are macros that use local variables</li>
<li>iterators for sets start with &quot;FOREACH&quot;</li>
<li>iterators for lists start with &quot;FORALL&quot;</li>
<li>qhull options are in single quotes (e.g., 'Pdn')</li>
<li>lists are sorted alphabetically</li>
<li>preprocessor directives on left margin for older compilers</li>
</ul>
</blockquote>
<p>
When reading the code, please note that the
global data structure, 'qh', is a macro. It
either expands to &quot;qh_qh.&quot; or to
&quot;qh_qh-&gt;&quot;. The later is used for
applications which run concurrent calls to qh_qhull().
<p>
When reading code with an editor, a search for
'<i>&quot;function</i>'
will locate the header of <i>qh_function</i>. A search for '<i>* function</i>'
will locate the tail of <i>qh_function</i>.
<p>A useful starting point is <a href="libqhull.h">libqhull.h</a>. It defines most
of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
determine the corresponding <a href="libqhull.h#qh_PRINT">qh_PRINT...</a> constant.
Search <a href="io.c">io.c</a> to learn how the print function is implemented.</p>
<p>If your web browser is configured for .c and .h files, the function, macro, and data type links
go to the corresponding source location. To configure your web browser for .c and .h files.
<ul>
<li>In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'.
<li>Opera 12.10
<ol>
<li>In Tools > Preferences > Advanced > Downloads
<li>Uncheck 'Hide file types opened with Opera'
<li>Quick find 'html'
<li>Select 'text/html' > Edit
<li>Add File extensions 'c,h,'
<li>Click 'OK'
</ol>
<li>Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings?
<li>Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type?
<li>Chrome -- Can Chrome be configured?
</ul>
<p>
Please report documentation and link errors
to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
</blockquote>
<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
<hr>
<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
<blockquote>
<p>This sections lists the .c and .h files for Qhull. Please
refer to these files for detailed information.</p>
<blockquote>
<dl>
<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
platforms with <a href=http://www.cmake.org/>CMake</a>.
Qhull includes project files for Visual Studio and Qt.
</dd>
<dt>&nbsp;</dt>
<dt><a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
Data structures are documented under <a href="qh-poly.htm">Poly</a>.
Global variables are documented under <a href="qh-globa.htm">Global</a>.
Other data structures and variables are documented under
<a href="qh-qhull.htm#TOC">Qhull</a> or <a href="qh-geom.htm"><b>Geom</b></a><b>.</b></dd>
<dt>&nbsp;</dt>
<dt><a href="qh-geom.htm"><b>Geom</b></a><b>, </b>
<a href="geom.h"><b>geom.h</b></a><b>, </b>
<a href="geom.c"><b>geom.c</b></a><b>, </b>
<a href="geom2.c"><b>geom2.c</b></a><b>, </b>
<a href="random.c"><b>random.c</b></a><b>, </b>
<a href="random.h"><b>random.h</b></a></dt>
<dd>Geometric routines. These routines implement mathematical
functions such as Gaussian elimination and geometric
routines needed for Qhull. Frequently used routines are
in <tt>geom.c</tt> while infrequent ones are in <tt>geom2.c</tt>.
</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-globa.htm"><b>Global</b></a><b>, </b>
<a href="global.c"><b>global.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
to store globally defined constants, lists, sets, and
variables.
<tt>global.c</tt> initializes and frees these
structures. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-io.htm"><b>Io</b></a><b>, </b><a href="io.h"><b>io.h</b></a><b>,
</b><a href="io.c"><b>io.c</b></a> </dt>
<dd>Input and output routines. Qhull provides a wide range of
input and output options.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-mem.htm"><b>Mem</b></a><b>, </b>
<a href="mem.h"><b>mem.h</b></a><b>, </b>
<a href="mem.c"><b>mem.c</b></a> </dt>
<dd>Memory routines. Qhull provides memory allocation and
deallocation. It uses quick-fit allocation.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-merge.htm"><b>Merge</b></a><b>, </b>
<a href="merge.h"><b>merge.h</b></a><b>, </b>
<a href="merge.c"><b>merge.c</b></a> </dt>
<dd>Merge routines. Qhull handles precision problems by
merged facets or joggled input. These routines merge simplicial facets,
merge non-simplicial facets, merge cycles of facets, and
rename redundant vertices.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-poly.htm"><b>Poly</b></a><b>, </b>
<a href="poly.h"><b>poly.h</b></a><b>, </b>
<a href="poly.c"><b>poly.c</b></a><b>, </b>
<a href="poly2.c"><b>poly2.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
<dd>Polyhedral routines. Qhull produces a polyhedron as a
list of facets with vertices, neighbors, ridges, and
geometric information. <tt>libqhull.h</tt> defines the main
data structures. Frequently used routines are in <tt>poly.c</tt>
while infrequent ones are in <tt>poly2.c</tt>.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-qhull.htm#TOC"><b>Qhull</b></a><b>, </b>
<a href="libqhull.c"><b>libqhull.c</b></a><b>, </b>
<a href="libqhull.h"><b>libqhull.h</b></a><b>, </b>
<a href="qhull_a.h"><b>qhull_a.h</b></a><b>, </b>
<a href="../qhullo/unix.c"><b>unix.c</b></a> <b>, </b>
<a href="../qconvex/qconvex.c"><b>qconvex.c</b></a> <b>, </b>
<a href="../qdelaunay/qdelaun.c"><b>qdelaun.c</b></a> <b>, </b>
<a href="../qhalf/qhalf.c"><b>qhalf.c</b></a> <b>, </b>
<a href="../qvoronoi/qvoronoi.c"><b>qvoronoi.c</b></a> </dt>
<dd>Top-level routines. The Quickhull algorithm is
implemented by <tt>libqhull.c</tt>. <tt>qhull_a.h</tt>
includes all header files. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-set.htm"><b>Set</b></a><b>, </b>
<a href="qset.h"><b>qset.h</b></a><b>, </b>
<a href="qset.c"><b>qset.c</b></a> </dt>
<dd>Set routines. Qhull implements its data structures as
sets. A set is an array of pointers that is expanded as
needed. This is a separate package that may be used in
other applications. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-stat.htm"><b>Stat</b></a><b>, </b>
<a href="stat.h"><b>stat.h</b></a><b>, </b>
<a href="stat.c"><b>stat.c</b></a> </dt>
<dd>Statistical routines. Qhull maintains statistics about
its implementation. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-user.htm"><b>User</b></a><b>, </b>
<a href="user.h"><b>user.h</b></a><b>, </b>
<a href="user.c"><b>user.c</b></a><b>, </b>
<a href="../user_eg/user_eg.c"><b>user_eg.c</b></a><b>, </b>
<a href="../user_eg2/user_eg2.c"><b>user_eg2.c</b></a><b>, </b>
</dt>
<dd>User-defined routines. Qhull allows the user to configure
the code with defined constants and specialized routines.
</dd>
</dl>
</blockquote>
</blockquote>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
/*<html><pre> -<a href="qh-io.htm"
>-------------------------------</a><a name="TOP">-</a>
io.h
declarations of Input/Output functions
see README, libqhull.h and io.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/io.h#1 $$Change: 1981 $
$DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
*/
#ifndef qhDEFio
#define qhDEFio 1
#include "libqhull.h"
/*============ constants and flags ==================*/
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_MAXfirst">-</a>
qh_MAXfirst
maximum length of first two lines of stdin
*/
#define qh_MAXfirst 200
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_MINradius">-</a>
qh_MINradius
min radius for Gp and Gv, fraction of maxcoord
*/
#define qh_MINradius 0.02
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_GEOMepsilon">-</a>
qh_GEOMepsilon
adjust outer planes for 'lines closer' and geomview roundoff.
This prevents bleed through.
*/
#define qh_GEOMepsilon 2e-3
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="qh_WHITESPACE">-</a>
qh_WHITESPACE
possible values of white space
*/
#define qh_WHITESPACE " \n\t\v\r\f"
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="RIDGE">-</a>
qh_RIDGE
to select which ridges to print in qh_eachvoronoi
*/
typedef enum
{
qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
}
qh_RIDGE;
/*-<a href="qh-io.htm#TOC"
>--------------------------------</a><a name="printvridgeT">-</a>
printvridgeT
prints results of qh_printvdiagram
see:
<a href="io.c#printvridge">qh_printvridge</a> for an example
*/
typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
/*============== -prototypes in alphabetical order =========*/
void qh_dfacet(unsigned id);
void qh_dvertex(unsigned id);
int qh_compare_facetarea(const void *p1, const void *p2);
int qh_compare_facetmerge(const void *p1, const void *p2);
int qh_compare_facetvisit(const void *p1, const void *p2);
int qh_compare_vertexpoint(const void *p1, const void *p2); /* not used, not in libqhull_r.h */
void qh_copyfilename(char *filename, int size, const char* source, int length);
void qh_countfacets(facetT *facetlist, setT *facets, boolT printall,
int *numfacetsp, int *numsimplicialp, int *totneighborsp,
int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
pointT *qh_detvnorm(vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
setT *qh_detvridge(vertexT *vertex);
setT *qh_detvridge3(vertexT *atvertex, vertexT *vertex);
int qh_eachvoronoi(FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
int qh_eachvoronoi_all(FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets);
void qh_geomplanes(facetT *facet, realT *outerplane, realT *innerplane);
void qh_markkeep(facetT *facetlist);
setT *qh_markvoronoi(facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
void qh_order_vertexneighbors(vertexT *vertex);
void qh_prepare_output(void);
void qh_printafacet(FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
void qh_printbegin(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printcenter(FILE *fp, qh_PRINT format, const char *string, facetT *facet);
void qh_printcentrum(FILE *fp, facetT *facet, realT radius);
void qh_printend(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printend4geom(FILE *fp, facetT *facet, int *num, boolT printall);
void qh_printextremes(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printfacet(FILE *fp, facetT *facet);
void qh_printfacet2math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
facetT *facet, realT offset, realT color[3]);
void qh_printfacet3math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet3vertex(FILE *fp, facetT *facet, qh_PRINT format);
void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, qh_PRINT format);
void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, qh_PRINT format);
void qh_printfacetheader(FILE *fp, facetT *facet);
void qh_printfacetridges(FILE *fp, facetT *facet);
void qh_printfacets(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
setT *vertices, realT color[3]);
void qh_printneighborhood(FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
void qh_printline3geom(FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
void qh_printpoint(FILE *fp, const char *string, pointT *point);
void qh_printpointid(FILE *fp, const char *string, int dim, pointT *point, int id);
void qh_printpoint3(FILE *fp, pointT *point);
void qh_printpoints_out(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printpointvect(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
void qh_printpointvect2(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
void qh_printridge(FILE *fp, ridgeT *ridge);
void qh_printspheres(FILE *fp, setT *vertices, realT radius);
void qh_printvdiagram(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
int qh_printvdiagram2(FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
void qh_printvertex(FILE *fp, vertexT *vertex);
void qh_printvertexlist(FILE *fp, const char* string, facetT *facetlist,
setT *facets, boolT printall);
void qh_printvertices(FILE *fp, const char* string, setT *vertices);
void qh_printvneighbors(FILE *fp, facetT* facetlist, setT *facets, boolT printall);
void qh_printvoronoi(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
void qh_produce_output(void);
void qh_produce_output2(void);
void qh_projectdim3(pointT *source, pointT *destination);
int qh_readfeasible(int dim, const char *curline);
coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
void qh_setfeasible(int dim);
boolT qh_skipfacet(facetT *facet);
char *qh_skipfilename(char *filename);
#endif /* qhDEFio */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
# -------------------------------------------------
# libqhull.pro -- Qt project for Qhull shared library
# -------------------------------------------------
include(../qhull-warn.pri)
DESTDIR = ../../lib
DLLDESTDIR = ../../bin
TEMPLATE = lib
CONFIG += shared warn_on
CONFIG -= qt
build_pass:CONFIG(debug, debug|release):{
TARGET = qhull_d
OBJECTS_DIR = Debug
}else:build_pass:CONFIG(release, debug|release):{
TARGET = qhull
OBJECTS_DIR = Release
}
win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
win32-msvc* : DEF_FILE += ../../src/libqhull/qhull-exports.def
# Order object files by frequency of execution. Small files at end.
# libqhull/libqhull.pro and ../qhull-libqhull-src.pri have the same SOURCES and HEADERS
SOURCES += ../libqhull/global.c
SOURCES += ../libqhull/stat.c
SOURCES += ../libqhull/geom2.c
SOURCES += ../libqhull/poly2.c
SOURCES += ../libqhull/merge.c
SOURCES += ../libqhull/libqhull.c
SOURCES += ../libqhull/geom.c
SOURCES += ../libqhull/poly.c
SOURCES += ../libqhull/qset.c
SOURCES += ../libqhull/mem.c
SOURCES += ../libqhull/random.c
SOURCES += ../libqhull/usermem.c
SOURCES += ../libqhull/userprintf.c
SOURCES += ../libqhull/io.c
SOURCES += ../libqhull/user.c
SOURCES += ../libqhull/rboxlib.c
SOURCES += ../libqhull/userprintf_rbox.c
HEADERS += ../libqhull/geom.h
HEADERS += ../libqhull/io.h
HEADERS += ../libqhull/libqhull.h
HEADERS += ../libqhull/mem.h
HEADERS += ../libqhull/merge.h
HEADERS += ../libqhull/poly.h
HEADERS += ../libqhull/random.h
HEADERS += ../libqhull/qhull_a.h
HEADERS += ../libqhull/qset.h
HEADERS += ../libqhull/stat.h
HEADERS += ../libqhull/user.h
OTHER_FILES += Mborland
OTHER_FILES += qh-geom.htm
OTHER_FILES += qh-globa.htm
OTHER_FILES += qh-io.htm
OTHER_FILES += qh-mem.htm
OTHER_FILES += qh-merge.htm
OTHER_FILES += qh-poly.htm
OTHER_FILES += qh-qhull.htm
OTHER_FILES += qh-set.htm
OTHER_FILES += qh-stat.htm
OTHER_FILES += qh-user.htm

View File

@@ -0,0 +1,576 @@
/*<html><pre> -<a href="qh-mem.htm"
>-------------------------------</a><a name="TOP">-</a>
mem.c
memory management routines for qhull
This is a standalone program.
To initialize memory:
qh_meminit(stderr);
qh_meminitbuffers(qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
qh_memsize((int)sizeof(facetT));
qh_memsize((int)sizeof(facetT));
...
qh_memsetup();
To free up all memory buffers:
qh_memfreeshort(&curlong, &totlong);
if qh_NOmem,
malloc/free is used instead of mem.c
notes:
uses Quickfit algorithm (freelists for commonly allocated sizes)
assumes small sizes for freelists (it discards the tail of memory buffers)
see:
qh-mem.htm and mem.h
global.c (qh_initbuffers) for an example of using mem.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/mem.c#7 $$Change: 2065 $
$DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
*/
#include "user.h" /* for QHULL_CRTDBG */
#include "mem.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef qhDEFlibqhull
typedef struct ridgeT ridgeT;
typedef struct facetT facetT;
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4127) /* conditional expression is constant */
#pragma warning( disable : 4706) /* assignment within conditional function */
#endif
void qh_errexit(int exitcode, facetT *, ridgeT *);
void qh_exit(int exitcode);
void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
void qh_free(void *mem);
void *qh_malloc(size_t size);
#endif
/*============ -global data structure ==============
see mem.h for definition
*/
qhmemT qhmem= {0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0}; /* remove "= {0}" if this causes a compiler error */
#ifndef qh_NOmem
/*============= internal functions ==============*/
static int qh_intcompare(const void *i, const void *j);
/*========== functions in alphabetical order ======== */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="intcompare">-</a>
qh_intcompare( i, j )
used by qsort and bsearch to compare two integers
*/
static int qh_intcompare(const void *i, const void *j) {
return(*((const int *)i) - *((const int *)j));
} /* intcompare */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memalloc">-</a>
qh_memalloc( insize )
returns object of insize bytes
qhmem is the global memory structure
returns:
pointer to allocated memory
errors if insufficient memory
notes:
use explicit type conversion to avoid type warnings on some compilers
actual object may be larger than insize
use qh_memalloc_() for inline code for quick allocations
logs allocations if 'T5'
caller is responsible for freeing the memory.
short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
design:
if size < qhmem.LASTsize
if qhmem.freelists[size] non-empty
return first object on freelist
else
round up request to size of qhmem.freelists[size]
allocate new allocation buffer if necessary
allocate object from allocation buffer
else
allocate object with qh_malloc() in user.c
*/
void *qh_memalloc(int insize) {
void **freelistp, *newbuffer;
int idx, size, n;
int outsize, bufsize;
void *object;
if (insize<0) {
qh_fprintf(qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
if (insize>=0 && insize <= qhmem.LASTsize) {
idx= qhmem.indextable[insize];
outsize= qhmem.sizetable[idx];
qhmem.totshort += outsize;
freelistp= qhmem.freelists+idx;
if ((object= *freelistp)) {
qhmem.cntquick++;
qhmem.totfree -= outsize;
*freelistp= *((void **)*freelistp); /* replace freelist with next object */
#ifdef qh_TRACEshort
n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
#endif
return(object);
}else {
qhmem.cntshort++;
if (outsize > qhmem.freesize) {
qhmem.totdropped += qhmem.freesize;
if (!qhmem.curbuffer)
bufsize= qhmem.BUFinit;
else
bufsize= qhmem.BUFsize;
if (!(newbuffer= qh_malloc((size_t)bufsize))) {
qh_fprintf(qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
*((void **)newbuffer)= qhmem.curbuffer; /* prepend newbuffer to curbuffer
list. newbuffer!=0 by QH6080 */
qhmem.curbuffer= newbuffer;
size= (sizeof(void **) + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
qhmem.freemem= (void *)((char *)newbuffer+size);
qhmem.freesize= bufsize - size;
qhmem.totbuffer += bufsize - size; /* easier to check */
/* Periodically test totbuffer. It matches at beginning and exit of every call */
n = qhmem.totshort + qhmem.totfree + qhmem.totdropped + qhmem.freesize - outsize;
if (qhmem.totbuffer != n) {
qh_fprintf(qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qhmem.totbuffer, n);
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
}
object= qhmem.freemem;
qhmem.freemem= (void *)((char *)qhmem.freemem + outsize);
qhmem.freesize -= outsize;
qhmem.totunused += outsize - insize;
#ifdef qh_TRACEshort
n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
#endif
return object;
}
}else { /* long allocation */
if (!qhmem.indextable) {
qh_fprintf(qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
outsize= insize;
qhmem.cntlong++;
qhmem.totlong += outsize;
if (qhmem.maxlong < qhmem.totlong)
qhmem.maxlong= qhmem.totlong;
if (!(object= qh_malloc((size_t)outsize))) {
qh_fprintf(qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, outsize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
}
return(object);
} /* memalloc */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memcheck">-</a>
qh_memcheck( )
*/
void qh_memcheck(void) {
int i, count, totfree= 0;
void *object;
if (qhmem.ferr == 0 || qhmem.IStracing < 0 || qhmem.IStracing > 10 || (((qhmem.ALIGNmask+1) & qhmem.ALIGNmask) != 0)) {
qh_fprintf_stderr(6244, "qh_memcheck error: either qhmem is overwritten or qhmem is not initialized. Call qh_meminit() or qh_new_qhull() before calling qh_mem routines. ferr 0x%x IsTracing %d ALIGNmask 0x%x", qhmem.ferr, qhmem.IStracing, qhmem.ALIGNmask);
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
if (qhmem.IStracing != 0)
qh_fprintf(qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qhmem\n");
for (i=0; i < qhmem.TABLEsize; i++) {
count=0;
for (object= qhmem.freelists[i]; object; object= *((void **)object))
count++;
totfree += qhmem.sizetable[i] * count;
}
if (totfree != qhmem.totfree) {
qh_fprintf(qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qhmem.totfree, totfree);
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
if (qhmem.IStracing != 0)
qh_fprintf(qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qhmem.totfree\n", totfree);
} /* memcheck */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memfree">-</a>
qh_memfree( object, insize )
free up an object of size bytes
size is insize from qh_memalloc
notes:
object may be NULL
type checking warns if using (void **)object
use qh_memfree_() for quick free's of small objects
design:
if size <= qhmem.LASTsize
append object to corresponding freelist
else
call qh_free(object)
*/
void qh_memfree(void *object, int insize) {
void **freelistp;
int idx, outsize;
if (!object)
return;
if (insize <= qhmem.LASTsize) {
qhmem.freeshort++;
idx= qhmem.indextable[insize];
outsize= qhmem.sizetable[idx];
qhmem.totfree += outsize;
qhmem.totshort -= outsize;
freelistp= qhmem.freelists + idx;
*((void **)object)= *freelistp;
*freelistp= object;
#ifdef qh_TRACEshort
idx= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
#endif
}else {
qhmem.freelong++;
qhmem.totlong -= insize;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
qh_free(object);
}
} /* memfree */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memfreeshort">-</a>
qh_memfreeshort( curlong, totlong )
frees up all short and qhmem memory allocations
returns:
number and size of current long allocations
see:
qh_freeqhull(allMem)
qh_memtotal(curlong, totlong, curshort, totshort, maxlong, totbuffer);
*/
void qh_memfreeshort(int *curlong, int *totlong) {
void *buffer, *nextbuffer;
FILE *ferr;
*curlong= qhmem.cntlong - qhmem.freelong;
*totlong= qhmem.totlong;
for (buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) {
nextbuffer= *((void **) buffer);
qh_free(buffer);
}
qhmem.curbuffer= NULL;
if (qhmem.LASTsize) {
qh_free(qhmem.indextable);
qh_free(qhmem.freelists);
qh_free(qhmem.sizetable);
}
ferr= qhmem.ferr;
memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
qhmem.ferr= ferr;
} /* memfreeshort */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="meminit">-</a>
qh_meminit( ferr )
initialize qhmem and test sizeof( void*)
Does not throw errors. qh_exit on failure
*/
void qh_meminit(FILE *ferr) {
memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
if (ferr)
qhmem.ferr= ferr;
else
qhmem.ferr= stderr;
if (sizeof(void*) < sizeof(int)) {
qh_fprintf(qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
if (sizeof(void*) > sizeof(ptr_intT)) {
qh_fprintf(qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
qh_memcheck();
} /* meminit */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="meminitbuffers">-</a>
qh_meminitbuffers( tracelevel, alignment, numsizes, bufsize, bufinit )
initialize qhmem
if tracelevel >= 5, trace memory allocations
alignment= desired address alignment for memory allocations
numsizes= number of freelists
bufsize= size of additional memory buffers for short allocations
bufinit= size of initial memory buffer for short allocations
*/
void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
qhmem.IStracing= tracelevel;
qhmem.NUMsizes= numsizes;
qhmem.BUFsize= bufsize;
qhmem.BUFinit= bufinit;
qhmem.ALIGNmask= alignment-1;
if (qhmem.ALIGNmask & ~qhmem.ALIGNmask) {
qh_fprintf(qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
if (!qhmem.sizetable || !qhmem.freelists) {
qh_fprintf(qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
if (qhmem.IStracing >= 1)
qh_fprintf(qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
} /* meminitbuffers */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memsetup">-</a>
qh_memsetup()
set up memory after running memsize()
*/
void qh_memsetup(void) {
int k,i;
qsort(qhmem.sizetable, (size_t)qhmem.TABLEsize, sizeof(int), qh_intcompare);
qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1];
if (qhmem.LASTsize >= qhmem.BUFsize || qhmem.LASTsize >= qhmem.BUFinit) {
qh_fprintf(qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
qhmem.LASTsize, qhmem.BUFsize, qhmem.BUFinit);
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
if (!(qhmem.indextable= (int *)qh_malloc((qhmem.LASTsize+1) * sizeof(int)))) {
qh_fprintf(qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
for (k=qhmem.LASTsize+1; k--; )
qhmem.indextable[k]= k;
i= 0;
for (k=0; k <= qhmem.LASTsize; k++) {
if (qhmem.indextable[k] <= qhmem.sizetable[i])
qhmem.indextable[k]= i;
else
qhmem.indextable[k]= ++i;
}
} /* memsetup */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memsize">-</a>
qh_memsize( size )
define a free list for this size
*/
void qh_memsize(int size) {
int k;
if (qhmem.LASTsize) {
qh_fprintf(qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
size= (size + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
for (k=qhmem.TABLEsize; k--; ) {
if (qhmem.sizetable[k] == size)
return;
}
if (qhmem.TABLEsize < qhmem.NUMsizes)
qhmem.sizetable[qhmem.TABLEsize++]= size;
else
qh_fprintf(qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes);
} /* memsize */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memstatistics">-</a>
qh_memstatistics( fp )
print out memory statistics
Verifies that qhmem.totfree == sum of freelists
*/
void qh_memstatistics(FILE *fp) {
int i;
int count;
void *object;
qh_memcheck();
qh_fprintf(fp, 9278, "\nmemory statistics:\n\
%7d quick allocations\n\
%7d short allocations\n\
%7d long allocations\n\
%7d short frees\n\
%7d long frees\n\
%7d bytes of short memory in use\n\
%7d bytes of short memory in freelists\n\
%7d bytes of dropped short memory\n\
%7d bytes of unused short memory (estimated)\n\
%7d bytes of long memory allocated (max, except for input)\n\
%7d bytes of long memory in use (in %d pieces)\n\
%7d bytes of short memory buffers (minus links)\n\
%7d bytes per short memory buffer (initially %d bytes)\n",
qhmem.cntquick, qhmem.cntshort, qhmem.cntlong,
qhmem.freeshort, qhmem.freelong,
qhmem.totshort, qhmem.totfree,
qhmem.totdropped + qhmem.freesize, qhmem.totunused,
qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong,
qhmem.totbuffer, qhmem.BUFsize, qhmem.BUFinit);
if (qhmem.cntlarger) {
qh_fprintf(fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
qhmem.cntlarger, ((float)qhmem.totlarger)/(float)qhmem.cntlarger);
qh_fprintf(fp, 9280, " freelists(bytes->count):");
}
for (i=0; i < qhmem.TABLEsize; i++) {
count=0;
for (object= qhmem.freelists[i]; object; object= *((void **)object))
count++;
qh_fprintf(fp, 9281, " %d->%d", qhmem.sizetable[i], count);
}
qh_fprintf(fp, 9282, "\n\n");
} /* memstatistics */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
qh_NOmem
turn off quick-fit memory allocation
notes:
uses qh_malloc() and qh_free() instead
*/
#else /* qh_NOmem */
void *qh_memalloc(int insize) {
void *object;
if (!(object= qh_malloc((size_t)insize))) {
qh_fprintf(qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
qh_errexit(qhmem_ERRmem, NULL, NULL);
}
qhmem.cntlong++;
qhmem.totlong += insize;
if (qhmem.maxlong < qhmem.totlong)
qhmem.maxlong= qhmem.totlong;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
return object;
}
void qh_memfree(void *object, int insize) {
if (!object)
return;
qh_free(object);
qhmem.freelong++;
qhmem.totlong -= insize;
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
}
void qh_memfreeshort(int *curlong, int *totlong) {
*totlong= qhmem.totlong;
*curlong= qhmem.cntlong - qhmem.freelong;
memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
}
void qh_meminit(FILE *ferr) {
memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
if (ferr)
qhmem.ferr= ferr;
else
qhmem.ferr= stderr;
if (sizeof(void*) < sizeof(int)) {
qh_fprintf(qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
}
void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
qhmem.IStracing= tracelevel;
}
void qh_memsetup(void) {
}
void qh_memsize(int size) {
}
void qh_memstatistics(FILE *fp) {
qh_fprintf(fp, 9409, "\nmemory statistics:\n\
%7d long allocations\n\
%7d long frees\n\
%7d bytes of long memory allocated (max, except for input)\n\
%7d bytes of long memory in use (in %d pieces)\n",
qhmem.cntlong,
qhmem.freelong,
qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong);
}
#endif /* qh_NOmem */
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="memtotlong">-</a>
qh_memtotal( totlong, curlong, totshort, curshort, maxlong, totbuffer )
Return the total, allocated long and short memory
returns:
Returns the total current bytes of long and short allocations
Returns the current count of long and short allocations
Returns the maximum long memory and total short buffer (minus one link per buffer)
Does not error (UsingLibQhull.cpp)
*/
void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
*totlong= qhmem.totlong;
*curlong= qhmem.cntlong - qhmem.freelong;
*totshort= qhmem.totshort;
*curshort= qhmem.cntshort + qhmem.cntquick - qhmem.freeshort;
*maxlong= qhmem.maxlong;
*totbuffer= qhmem.totbuffer;
} /* memtotlong */

View File

@@ -0,0 +1,222 @@
/*<html><pre> -<a href="qh-mem.htm"
>-------------------------------</a><a name="TOP">-</a>
mem.h
prototypes for memory management functions
see qh-mem.htm, mem.c and qset.h
for error handling, writes message and calls
qh_errexit(qhmem_ERRmem, NULL, NULL) if insufficient memory
and
qh_errexit(qhmem_ERRqhull, NULL, NULL) otherwise
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/mem.h#2 $$Change: 2062 $
$DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
*/
#ifndef qhDEFmem
#define qhDEFmem 1
#include <stdio.h>
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
qh_NOmem
turn off quick-fit memory allocation
notes:
mem.c implements Quickfit memory allocation for about 20% time
savings. If it fails on your machine, try to locate the
problem, and send the answer to qhull@qhull.org. If this can
not be done, define qh_NOmem to use malloc/free instead.
#define qh_NOmem
*/
/*-<a href="qh-mem.htm#TOC"
>-------------------------------</a><a name="TRACEshort">-</a>
qh_TRACEshort
Trace short and quick memory allocations at T5
*/
#define qh_TRACEshort
/*-------------------------------------------
to avoid bus errors, memory allocation must consider alignment requirements.
malloc() automatically takes care of alignment. Since mem.c manages
its own memory, we need to explicitly specify alignment in
qh_meminitbuffers().
A safe choice is sizeof(double). sizeof(float) may be used if doubles
do not occur in data structures and pointers are the same size. Be careful
of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
*/
#define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull.h */
#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull.h */
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="ptr_intT">-</a>
ptr_intT
for casting a void * to an integer-type that holds a pointer
Used for integer expressions (e.g., computing qh_gethash() in poly.c)
notes:
WARN64 -- these notes indicate 64-bit issues
On 64-bit machines, a pointer may be larger than an 'int'.
qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*'
ptr_intT is typically a signed value, but not necessarily so
size_t is typically unsigned, but should match the parameter type
Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
This matches Qt convention and is easier to work with.
*/
#if (defined(__MINGW64__)) && defined(_WIN64)
typedef long long ptr_intT;
#elif (_MSC_VER) && defined(_WIN64)
typedef long long ptr_intT;
#else
typedef long ptr_intT;
#endif
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="qhmemT">-</a>
qhmemT
global memory structure for mem.c
notes:
users should ignore qhmem except for writing extensions
qhmem is allocated in mem.c
qhmem could be swapable like qh and qhstat, but then
multiple qh's and qhmem's would need to keep in synch.
A swapable qhmem would also waste memory buffers. As long
as memory operations are atomic, there is no problem with
multiple qh structures being active at the same time.
If you need separate address spaces, you can swap the
contents of qhmem.
*/
typedef struct qhmemT qhmemT;
extern qhmemT qhmem;
#ifndef DEFsetT
#define DEFsetT 1
typedef struct setT setT; /* defined in qset.h */
#endif
/* Update qhmem in mem.c if add or remove fields */
struct qhmemT { /* global memory management variables */
int BUFsize; /* size of memory allocation buffer */
int BUFinit; /* initial size of memory allocation buffer */
int TABLEsize; /* actual number of sizes in free list table */
int NUMsizes; /* maximum number of sizes in free list table */
int LASTsize; /* last size in free list table */
int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
void **freelists; /* free list table, linked by offset 0 */
int *sizetable; /* size of each freelist */
int *indextable; /* size->index table */
void *curbuffer; /* current buffer, linked by offset 0 */
void *freemem; /* free memory in curbuffer */
int freesize; /* size of freemem in bytes */
setT *tempstack; /* stack of temporary memory, managed by users */
FILE *ferr; /* file for reporting errors when 'qh' may be undefined */
int IStracing; /* =5 if tracing memory allocations */
int cntquick; /* count of quick allocations */
/* Note: removing statistics doesn't effect speed */
int cntshort; /* count of short allocations */
int cntlong; /* count of long allocations */
int freeshort; /* count of short memfrees */
int freelong; /* count of long memfrees */
int totbuffer; /* total short memory buffers minus buffer links */
int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */
int totfree; /* total size of free, short memory on freelists */
int totlong; /* total size of long memory in use */
int maxlong; /* maximum totlong */
int totshort; /* total size of short memory in use */
int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */
int cntlarger; /* count of setlarger's */
int totlarger; /* total copied by setlarger */
};
/*==================== -macros ====================*/
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memalloc_">-</a>
qh_memalloc_(insize, freelistp, object, type)
returns object of size bytes
assumes size<=qhmem.LASTsize and void **freelistp is a temp
*/
#if defined qh_NOmem
#define qh_memalloc_(insize, freelistp, object, type) {\
object= (type*)qh_memalloc(insize); }
#elif defined qh_TRACEshort
#define qh_memalloc_(insize, freelistp, object, type) {\
freelistp= NULL; /* Avoid warnings */ \
object= (type*)qh_memalloc(insize); }
#else /* !qh_NOmem */
#define qh_memalloc_(insize, freelistp, object, type) {\
freelistp= qhmem.freelists + qhmem.indextable[insize];\
if ((object= (type*)*freelistp)) {\
qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \
qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \
qhmem.cntquick++; \
*freelistp= *((void **)*freelistp);\
}else object= (type*)qh_memalloc(insize);}
#endif
/*-<a href="qh-mem.htm#TOC"
>--------------------------------</a><a name="memfree_">-</a>
qh_memfree_(object, insize, freelistp)
free up an object
notes:
object may be NULL
assumes size<=qhmem.LASTsize and void **freelistp is a temp
*/
#if defined qh_NOmem
#define qh_memfree_(object, insize, freelistp) {\
qh_memfree(object, insize); }
#elif defined qh_TRACEshort
#define qh_memfree_(object, insize, freelistp) {\
freelistp= NULL; /* Avoid warnings */ \
qh_memfree(object, insize); }
#else /* !qh_NOmem */
#define qh_memfree_(object, insize, freelistp) {\
if (object) { \
qhmem.freeshort++;\
freelistp= qhmem.freelists + qhmem.indextable[insize];\
qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \
qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \
*((void **)object)= *freelistp;\
*freelistp= object;}}
#endif
/*=============== prototypes in alphabetical order ============*/
void *qh_memalloc(int insize);
void qh_memcheck(void);
void qh_memfree(void *object, int insize);
void qh_memfreeshort(int *curlong, int *totlong);
void qh_meminit(FILE *ferr);
void qh_meminitbuffers(int tracelevel, int alignment, int numsizes,
int bufsize, int bufinit);
void qh_memsetup(void);
void qh_memsize(int size);
void qh_memstatistics(FILE *fp);
void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
#endif /* qhDEFmem */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,178 @@
/*<html><pre> -<a href="qh-merge.htm"
>-------------------------------</a><a name="TOP">-</a>
merge.h
header file for merge.c
see qh-merge.htm and merge.c
Copyright (c) 1993-2015 C.B. Barber.
$Id: //main/2015/qhull/src/libqhull/merge.h#1 $$Change: 1981 $
$DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
*/
#ifndef qhDEFmerge
#define qhDEFmerge 1
#include "libqhull.h"
/*============ -constants- ==============*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEredundant">-</a>
qh_ANGLEredundant
indicates redundant merge in mergeT->angle
*/
#define qh_ANGLEredundant 6.0
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEdegen">-</a>
qh_ANGLEdegen
indicates degenerate facet in mergeT->angle
*/
#define qh_ANGLEdegen 5.0
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEconcave">-</a>
qh_ANGLEconcave
offset to indicate concave facets in mergeT->angle
notes:
concave facets are assigned the range of [2,4] in mergeT->angle
roundoff error may make the angle less than 2
*/
#define qh_ANGLEconcave 1.5
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="MRG">-</a>
MRG... (mergeType)
indicates the type of a merge (mergeT->type)
*/
typedef enum { /* in sort order for facet_mergeset */
MRGnone= 0,
MRGcoplanar, /* centrum coplanar */
MRGanglecoplanar, /* angle coplanar */
/* could detect half concave ridges */
MRGconcave, /* concave ridge */
MRGflip, /* flipped facet. facet1 == facet2 */
MRGridge, /* duplicate ridge (qh_MERGEridge) */
/* degen and redundant go onto degen_mergeset */
MRGdegen, /* degenerate facet (!enough neighbors) facet1 == facet2 */
MRGredundant, /* redundant facet (vertex subset) */
/* merge_degenredundant assumes degen < redundant */
MRGmirror, /* mirror facet from qh_triangulate */
ENDmrg
} mergeType;
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="qh_MERGEapex">-</a>
qh_MERGEapex
flag for qh_mergefacet() to indicate an apex merge
*/
#define qh_MERGEapex True
/*============ -structures- ====================*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="mergeT">-</a>
mergeT
structure used to merge facets
*/
typedef struct mergeT mergeT;
struct mergeT { /* initialize in qh_appendmergeset */
realT angle; /* angle between normals of facet1 and facet2 */
facetT *facet1; /* will merge facet1 into facet2 */
facetT *facet2;
mergeType type;
};
/*=========== -macros- =========================*/
/*-<a href="qh-merge.htm#TOC"
>--------------------------------</a><a name="FOREACHmerge_">-</a>
FOREACHmerge_( merges ) {...}
assign 'merge' to each merge in merges
notes:
uses 'mergeT *merge, **mergep;'
if qh_mergefacet(),
restart since qh.facet_mergeset may change
see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
/*============ prototypes in alphabetical order after pre/postmerge =======*/
void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle);
void qh_postmerge(const char *reason, realT maxcentrum, realT maxangle,
boolT vneighbors);
void qh_all_merges(boolT othermerge, boolT vneighbors);
void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
setT *qh_basevertices( facetT *samecycle);
void qh_checkconnect(void /* qh.new_facets */);
boolT qh_checkzero(boolT testall);
int qh_compareangle(const void *p1, const void *p2);
int qh_comparemerge(const void *p1, const void *p2);
int qh_comparevisit(const void *p1, const void *p2);
void qh_copynonconvex(ridgeT *atridge);
void qh_degen_redundant_facet(facetT *facet);
void qh_degen_redundant_neighbors(facetT *facet, facetT *delfacet);
vertexT *qh_find_newvertex(vertexT *oldvertex, setT *vertices, setT *ridges);
void qh_findbest_test(boolT testcentrum, facetT *facet, facetT *neighbor,
facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
void qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
void qh_forcedmerges( boolT *wasmerge);
void qh_getmergeset(facetT *facetlist);
void qh_getmergeset_initial(facetT *facetlist);
void qh_hashridge(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
ridgeT *qh_hashridge_find(setT *hashtable, int hashsize, ridgeT *ridge,
vertexT *vertex, vertexT *oldvertex, int *hashslot);
void qh_makeridges(facetT *facet);
void qh_mark_dupridges(facetT *facetlist);
void qh_maydropneighbor(facetT *facet);
int qh_merge_degenredundant(void);
void qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
void qh_mergecycle(facetT *samecycle, facetT *newfacet);
void qh_mergecycle_all(facetT *facetlist, boolT *wasmerge);
void qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
void qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
void qh_mergefacet2d(facetT *facet1, facetT *facet2);
void qh_mergeneighbors(facetT *facet1, facetT *facet2);
void qh_mergeridges(facetT *facet1, facetT *facet2);
void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
void qh_mergevertex_del(vertexT *vertex, facetT *facet1, facetT *facet2);
void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
void qh_mergevertices(setT *vertices1, setT **vertices);
setT *qh_neighbor_intersections(vertexT *vertex);
void qh_newvertices(setT *vertices);
boolT qh_reducevertices(void);
vertexT *qh_redundant_vertex(vertexT *vertex);
boolT qh_remove_extravertices(facetT *facet);
vertexT *qh_rename_sharedvertex(vertexT *vertex, facetT *facet);
void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
facetT *oldfacet, facetT *neighborA);
boolT qh_test_appendmerge(facetT *facet, facetT *neighbor);
boolT qh_test_vneighbors(void /* qh.newfacet_list */);
void qh_tracemerge(facetT *facet1, facetT *facet2);
void qh_tracemerging(void);
void qh_updatetested( facetT *facet1, facetT *facet2);
setT *qh_vertexridges(vertexT *vertex);
void qh_vertexridges_facet(vertexT *vertex, facetT *facet, setT **ridges);
void qh_willdelete(facetT *facet, facetT *replace);
#endif /* qhDEFmerge */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
/*<html><pre> -<a href="qh-poly.htm"
>-------------------------------</a><a name="TOP">-</a>
poly.h
header file for poly.c and poly2.c
see qh-poly.htm, libqhull.h and poly.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/poly.h#3 $$Change: 2047 $
$DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
*/
#ifndef qhDEFpoly
#define qhDEFpoly 1
#include "libqhull.h"
/*=============== constants ========================== */
/*-<a href="qh-geom.htm#TOC"
>--------------------------------</a><a name="ALGORITHMfault">-</a>
ALGORITHMfault
use as argument to checkconvex() to report errors during buildhull
*/
#define qh_ALGORITHMfault 0
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="DATAfault">-</a>
DATAfault
use as argument to checkconvex() to report errors during initialhull
*/
#define qh_DATAfault 1
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="DUPLICATEridge">-</a>
DUPLICATEridge
special value for facet->neighbor to indicate a duplicate ridge
notes:
set by matchneighbor, used by matchmatch and mark_dupridge
*/
#define qh_DUPLICATEridge (facetT *)1L
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="MERGEridge">-</a>
MERGEridge flag in facet
special value for facet->neighbor to indicate a merged ridge
notes:
set by matchneighbor, used by matchmatch and mark_dupridge
*/
#define qh_MERGEridge (facetT *)2L
/*============ -structures- ====================*/
/*=========== -macros- =========================*/
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLfacet_">-</a>
FORALLfacet_( facetlist ) { ... }
assign 'facet' to each facet in facetlist
notes:
uses 'facetT *facet;'
assumes last facet is a sentinel
see:
FORALLfacets
*/
#define FORALLfacet_( facetlist ) if (facetlist ) for ( facet=( facetlist ); facet && facet->next; facet= facet->next )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLnew_facets">-</a>
FORALLnew_facets { ... }
assign 'newfacet' to each facet in qh.newfacet_list
notes:
uses 'facetT *newfacet;'
at exit, newfacet==NULL
*/
#define FORALLnew_facets for ( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvertex_">-</a>
FORALLvertex_( vertexlist ) { ... }
assign 'vertex' to each vertex in vertexlist
notes:
uses 'vertexT *vertex;'
at exit, vertex==NULL
*/
#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLvisible_facets">-</a>
FORALLvisible_facets { ... }
assign 'visible' to each visible facet in qh.visible_list
notes:
uses 'vacetT *visible;'
at exit, visible==NULL
*/
#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLsame_">-</a>
FORALLsame_( newfacet ) { ... }
assign 'same' to each facet in newfacet->f.samecycle
notes:
uses 'facetT *same;'
stops when it returns to newfacet
*/
#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FORALLsame_cycle_">-</a>
FORALLsame_cycle_( newfacet ) { ... }
assign 'same' to each facet in newfacet->f.samecycle
notes:
uses 'facetT *same;'
at exit, same == NULL
*/
#define FORALLsame_cycle_(newfacet) \
for (same= newfacet->f.samecycle; \
same; same= (same == newfacet ? NULL : same->f.samecycle))
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHneighborA_">-</a>
FOREACHneighborA_( facet ) { ... }
assign 'neighborA' to each neighbor in facet->neighbors
FOREACHneighborA_( vertex ) { ... }
assign 'neighborA' to each neighbor in vertex->neighbors
declare:
facetT *neighborA, **neighborAp;
see:
<a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvisible_">-</a>
FOREACHvisible_( facets ) { ... }
assign 'visible' to each facet in facets
notes:
uses 'facetT *facet, *facetp;'
see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHnewfacet_">-</a>
FOREACHnewfacet_( facets ) { ... }
assign 'newfacet' to each facet in facets
notes:
uses 'facetT *newfacet, *newfacetp;'
see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexA_">-</a>
FOREACHvertexA_( vertices ) { ... }
assign 'vertexA' to each vertex in vertices
notes:
uses 'vertexT *vertexA, *vertexAp;'
see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
/*-<a href="qh-poly.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
FOREACHvertexreverse12_( vertices ) { ... }
assign 'vertex' to each vertex in vertices
reverse order of first two vertices
notes:
uses 'vertexT *vertex, *vertexp;'
see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
/*=============== prototypes poly.c in alphabetical order ================*/
void qh_appendfacet(facetT *facet);
void qh_appendvertex(vertexT *vertex);
void qh_attachnewfacets(void /* qh.visible_list, qh.newfacet_list */);
boolT qh_checkflipped(facetT *facet, realT *dist, boolT allerror);
void qh_delfacet(facetT *facet);
void qh_deletevisible(void /*qh.visible_list, qh.horizon_list*/);
setT *qh_facetintersect(facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
int qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem);
facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
void qh_makenewplanes(void /* newfacet_list */);
facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew);
facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew);
void qh_matchneighbor(facetT *newfacet, int newskip, int hashsize,
int *hashcount);
void qh_matchnewfacets(void);
boolT qh_matchvertices(int firstindex, setT *verticesA, int skipA,
setT *verticesB, int *skipB, boolT *same);
facetT *qh_newfacet(void);
ridgeT *qh_newridge(void);
int qh_pointid(pointT *point);
void qh_removefacet(facetT *facet);
void qh_removevertex(vertexT *vertex);
void qh_updatevertices(void);
/*========== -prototypes poly2.c in alphabetical order ===========*/
void qh_addhash(void* newelem, setT *hashtable, int hashsize, int hash);
void qh_check_bestdist(void);
void qh_check_dupridge(facetT *facet1, realT dist1, facetT *facet2, realT dist2);
void qh_check_maxout(void);
void qh_check_output(void);
void qh_check_point(pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
void qh_check_points(void);
void qh_checkconvex(facetT *facetlist, int fault);
void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
void qh_checkflipped_all(facetT *facetlist);
void qh_checkpolygon(facetT *facetlist);
void qh_checkvertex(vertexT *vertex);
void qh_clearcenters(qh_CENTER type);
void qh_createsimplex(setT *vertices);
void qh_delridge(ridgeT *ridge);
void qh_delvertex(vertexT *vertex);
setT *qh_facet3vertex(facetT *facet);
facetT *qh_findbestfacet(pointT *point, boolT bestoutside,
realT *bestdist, boolT *isoutside);
facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside,
int *numpart);
int qh_findgood(facetT *facetlist, int goodhorizon);
void qh_findgood_all(facetT *facetlist);
void qh_furthestnext(void /* qh.facet_list */);
void qh_furthestout(facetT *facet);
void qh_infiniteloop(facetT *facet);
void qh_initbuild(void);
void qh_initialhull(setT *vertices);
setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
vertexT *qh_isvertex(pointT *point, setT *vertices);
vertexT *qh_makenewfacets(pointT *point /*horizon_list, visible_list*/);
void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount);
void qh_nearcoplanar(void /* qh.facet_list */);
vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp);
int qh_newhashtable(int newsize);
vertexT *qh_newvertex(pointT *point);
ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
void qh_outcoplanar(void /* facet_list */);
pointT *qh_point(int id);
void qh_point_add(setT *set, pointT *point, void *elem);
setT *qh_pointfacet(void /*qh.facet_list*/);
setT *qh_pointvertex(void /*qh.facet_list*/);
void qh_prependfacet(facetT *facet, facetT **facetlist);
void qh_printhashtable(FILE *fp);
void qh_printlists(void);
void qh_resetlists(boolT stats, boolT resetVisible /*qh.newvertex_list qh.newfacet_list qh.visible_list*/);
void qh_setvoronoi_all(void);
void qh_triangulate(void /*qh.facet_list*/);
void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex);
void qh_triangulate_link(facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
void qh_triangulate_mirror(facetT *facetA, facetT *facetB);
void qh_triangulate_null(facetT *facetA);
void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
setT *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
void qh_vertexneighbors(void /*qh.facet_list*/);
boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
#endif /* qhDEFpoly */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,295 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>geom.c, geom2.c -- geometric and floating point routines</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm#TOC">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
<h2>geom.c, geom2.c, random.c -- geometric and floating point routines</h2>
<blockquote>
<p>Geometrically, a vertex is a point with <em>d</em> coordinates
and a facet is a halfspace. A <em>halfspace</em> is defined by an
oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
is defined by <em>d</em> normalized coefficients and an offset. A
point is <em>above</em> a facet if its distance to the facet is
positive.</p>
<p>Qhull uses floating point coordinates for input points,
vertices, halfspace equations, centrums, and an interior point.</p>
<p>Qhull may be configured for single precision or double
precision floating point arithmetic (see <a href="user.h#realT">realT</a>
). </p>
<p>Each floating point operation may incur round-off error (see
<a href="qh-merge.htm#TOC">Merge</a>). The maximum error for distance
computations is determined at initialization. The roundoff error
in halfspace computation is accounted for by computing the
distance from vertices to the halfspace. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <b>Geom</b>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
<h3>Index to <a href="geom.c">geom.c</a>,
<a href="geom2.c">geom2.c</a>, <a href="geom.h">geom.h</a>,
<a href="random.c">random.c</a>, <a href="random.h">random.h</a>
</h3>
<ul>
<li><a href="#gtype">geometric data types and constants</a> </li>
<li><a href="#gmacro">mathematical macros</a>
</li>
<li><a href="#gmath">mathematical functions</a> </li>
<li><a href="#gcomp">computational geometry functions</a> </li>
<li><a href="#gpoint">point array functions</a> </li>
<li><a href="#gfacet">geometric facet functions</a> </li>
<li><a href="#ground">geometric roundoff functions</a></li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gtype">geometric data types
and constants</a></h3>
<ul>
<li><a href="libqhull.h#coordT">coordT</a> coordinates and
coefficients are stored as realT</li>
<li><a href="libqhull.h#pointT">pointT</a> a point is an array
of <tt>DIM3</tt> coordinates </li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
<ul>
<li><a href="geom.h#fabs_">fabs_</a> returns the absolute
value of a </li>
<li><a href="geom.h#fmax_">fmax_</a> returns the maximum
value of a and b </li>
<li><a href="geom.h#fmin_">fmin_</a> returns the minimum
value of a and b </li>
<li><a href="geom.h#maximize_">maximize_</a> maximize a value
</li>
<li><a href="geom.h#minimize_">minimize_</a> minimize a value
</li>
<li><a href="geom.h#det2_">det2_</a> compute a 2-d
determinate </li>
<li><a href="geom.h#det3_">det3_</a> compute a 3-d
determinate </li>
<li><a href="geom.h#dX">dX, dY, dZ</a> compute the difference
between two coordinates </li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
<ul>
<li><a href="geom.c#backnormal">qh_backnormal</a> solve for
normal using back substitution </li>
<li><a href="geom2.c#crossproduct">qh_crossproduct</a>
compute the cross product of two 3-d vectors </li>
<li><a href="geom2.c#determinant">qh_determinant</a> compute
the determinant of a square matrix </li>
<li><a href="geom.c#gausselim">qh_gausselim</a> Gaussian
elimination with partial pivoting </li>
<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
implements Gram-Schmidt orthogonalization by rows </li>
<li><a href="geom2.c#maxabsval">qh_maxabsval</a> return max
absolute value of a vector </li>
<li><a href="geom2.c#minabsval">qh_minabsval</a> return min
absolute value of a dim vector </li>
<li><a href="geom2.c#mindiff">qh_mindiff</a> return index of
min absolute difference of two vectors </li>
<li><a href="geom.c#normalize">qh_normalize</a> normalize a
vector </li>
<li><a href="geom.c#normalize2">qh_normalize2</a> normalize a
vector and report if too small </li>
<li><a href="geom2.c#printmatrix">qh_printmatrix</a> print
matrix given by row vectors </li>
<li><a href="random.c#rand">qh_rand/srand</a> generate random
numbers </li>
<li><a href="random.c#randomfactor">qh_randomfactor</a> return
a random factor near 1.0 </li>
<li><a href="random.c#randommatrix">qh_randommatrix</a>
generate a random dimXdim matrix in range (-1,1) </li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
<ul>
<li><a href="geom2.c#detsimplex">qh_detsimplex</a> compute
determinate of a simplex of points </li>
<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
<li><a href="geom2.c#distnorm">qh_distnorm</a> compute
distance from point to hyperplane as defined by normal and offset</li>
<li><a href="geom2.c#facetarea_simplex">qh_facetarea_simplex</a>
return area of a simplex</li>
<li><a href="geom.c#getangle">qh_getangle</a> return cosine
of angle (i.e., dot product) </li>
<li><a href="geom.c#getcenter">qh_getcenter</a> return
arithmetic center for a set of vertices </li>
<li><a href="geom2.c#pointdist">qh_pointdist</a> return
distance between two points </li>
<li><a href="geom2.c#rotatepoints">qh_rotatepoints</a> rotate
numpoints points by a row matrix </li>
<li><a href="geom2.c#sethalfspace">qh_sethalfspace</a> set
coords to dual of halfspace relative to an interior point </li>
<li><a href="geom.c#sethyperplane_det">qh_sethyperplane_det</a>
return hyperplane for oriented simplex using determinates
</li>
<li><a href="geom.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
return hyperplane for oriented simplex using Gaussian
elimination </li>
<li><a href="geom2.c#voronoi_center">qh_voronoi_center</a>
return Voronoi center for a set of points </li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
<ul>
<li><a href="geom2.c#copypoints">qh_copypoints</a> return
malloc'd copy of points</li>
<li><a href="geom2.c#joggleinput">qh_joggleinput</a> joggle
input points by qh.JOGGLEmax </li>
<li><a href="geom2.c#maxmin">qh_maxmin</a> return max/min
points for each dimension</li>
<li><a href="geom2.c#maxsimplex">qh_maxsimplex</a> determines
maximum simplex for a set of points </li>
<li><a href="geom2.c#printpoints">qh_printpoints</a> print ids for a
set of points </li>
<li><a href="geom2.c#projectinput">qh_projectinput</a> project
input using qh DELAUNAY and qh low_bound/high_bound </li>
<li><a href="geom2.c#projectpoints">qh_projectpoints</a>
project points along one or more dimensions </li>
<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
input points using row matrix </li>
<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
input points using qh low_bound/high_bound </li>
<li><a href="geom2.c#scalelast">qh_scalelast</a> scale last
coordinate to [0,m] for Delaunay triangulations </li>
<li><a href="geom2.c#scalepoints">qh_scalepoints</a> scale
points to new lowbound and highbound </li>
<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
points to paraboloid for Delaunay triangulation </li>
<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
generate dual for halfspace intersection with interior
point </li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
<ul>
<li><a href="geom.c#distplane">qh_distplane</a> return
distance from point to facet </li>
<li><a href="geom2.c#facetarea">qh_facetarea</a> return area
of a facet </li>
<li><a href="geom2.c#facetcenter">qh_facetcenter</a> return
Voronoi center for a facet's vertices </li>
<li><a href="geom.c#findbest">qh_findbest</a> find visible
facet or best facet for a point </li>
<li><a href="geom.c#findbesthorizon">qh_findbesthorizon</a>
update best new facet with horizon facets</li>
<li><a href="geom.c#findbestnew">qh_findbestnew</a> find best
new facet for point </li>
<li><a href="geom2.c#getarea">qh_getarea</a> get area of all
facets in facetlist, collect statistics </li>
<li><a href="geom.c#getcentrum">qh_getcentrum</a> return
centrum for a facet </li>
<li><a href="geom.c#getdistance">qh_getdistance</a> returns
the max and min distance of a facet's vertices to a
neighboring facet</li>
<li><a href="geom2.c#findgooddist">qh_findgooddist</a> find
best good facet visible for point from facet </li>
<li><a href="geom2.c#inthresholds">qh_inthresholds</a> return
True if facet normal within 'Pdn' and 'PDn'</li>
<li><a href="geom2.c#orientoutside">qh_orientoutside</a>
orient facet so that <tt>qh.interior_point</tt> is inside</li>
<li><a href="geom.c#projectpoint">qh_projectpoint</a> project
point onto a facet </li>
<li><a href="geom.c#setfacetplane">qh_setfacetplane</a> sets
the hyperplane for a facet </li>
<li><a href="geom2.c#sharpnewfacets">qh_sharpnewfacets</a> true
if new facets contains a sharp corner</li>
</ul>
<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
<ul>
<li><a href="geom2.c#detjoggle">qh_detjoggle</a> determine
default joggle for points and distance roundoff error</li>
<li><a href="geom2.c#detroundoff">qh_detroundoff</a>
determine maximum roundoff error and other precision constants</li>
<li><a href="geom2.c#distround">qh_distround</a> compute
maximum roundoff error due to a distance computation to a
normalized hyperplane</li>
<li><a href="geom2.c#divzero">qh_divzero</a> divide by a
number that is nearly zero </li>
<li><a href="geom2.c#maxouter">qh_maxouter</a> return maximum outer
plane</li>
<li><a href="geom2.c#outerinner">qh_outerinner</a> return actual
outer and inner planes
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,165 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>global.c -- global variables and their functions</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
<h2>global.c -- global variables and their functions</h2>
<blockquote>
<p>Qhull uses a global data structure, <tt>qh</tt>, to store
globally defined constants, lists, sets, and variables. This
allows multiple instances of Qhull to execute at the same time.
The structure may be statically allocated or
dynamically allocated with malloc(). See
<a href="user.h#QHpointer">QHpointer</a>.
</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <b>Global</b> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
<h3>Index to <a href="global.c">global.c</a> and
<a href="libqhull.h">libqhull.h</a></h3>
<ul>
<li><a href="#ovar">Qhull's global variables</a> </li>
<li><a href="#ofunc">Global variable and initialization
routines</a> </li>
</ul>
<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ovar">Qhull's global
variables</a></h3>
<ul>
<li><a href=global.c#qh_version>qh_version</a> version string
<li><a href="libqhull.h#qh">qh</a> all global variables for
qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
<li><a href="libqhull_r.h#qh">QHULL_LIB_CHECK</a> Check for compatible library</li>
<li><a href="libqhull.h#qh-const">qh constants</a> configuration
flags and constants for Qhull </li>
<li><a href="libqhull.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
<li><a href="libqhull.h#qh-codetern">qh internal constants</a>
internal constants for Qhull </li>
<li><a href="libqhull.h#qh-lists">qh facet and vertex lists</a>
lists of facets and vertices </li>
<li><a href="libqhull.h#qh-var">qh global variables</a> minimum
and maximum distances, next visit ids, several flags, and
other global variables. </li>
<li><a href="libqhull.h#qh-set">qh global sets</a> global sets
for merging, hashing, input, etc. </li>
<li><a href="libqhull.h#qh-buf">qh global buffers</a> buffers
for matrix operations and input </li>
<li><a href="libqhull.h#qh-static">qh static variables</a>
static variables for individual functions </li>
</ul>
<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ofunc">Global variable and
initialization routines</a></h3>
<ul>
<li><a href="global.c#appendprint">qh_appendprint</a> append
output format to <tt>qh.PRINTout</tt> </li>
<li><a href="global.c#freebuffers">qh_freebuffers</a> free
global memory buffers </li>
<li><a href="global.c#freeqhull">qh_freeqhull</a> free memory
used by qhull </li>
<li><a href="global.c#init_A">qh_init_A</a> called before
error handling initialized </li>
<li><a href="global.c#init_B">qh_init_B</a> called after
points are defined </li>
<li><a href="global.c#init_qhull_command">qh_init_qhull_command</a>
build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
<li><a href="global.c#initflags">qh_initflags</a> set flags
and constants from command line </li>
<li><a href="global.c#initqhull_buffers">qh_initqhull_buffers</a>
initialize global memory buffers </li>
<li><a href="global.c#initqhull_globals">qh_initqhull_globals</a>
initialize global variables </li>
<li><a href="global.c#initqhull_mem">qh_initqhull_mem</a>
initialize Qhull memory management </li>
<li><a href="global.c#initqhull_start">qh_initqhull_start</a>
allocate qh_qh and call qh_initqhull_start2()
<li><a href="global.c#initqhull_start2">qh_initqhull_start2</a>
initialize default values at Qhull startup </li>
<li><a href="global.c#initthresholds">qh_initthresholds</a>
initialize 'Pdn' and 'PDn' thresholds </li>
<li><a href="global.c#lib_check">qh_lib_check</a> check for compatible Qhull library. Invoked by QHULL_LIB_CHECK at start of each program.</li>
<li><a href="global.c#option">qh_option</a> append option
description to <tt>qh.global_options</tt> </li>
<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
restores a previously saved qhull </li>
<li><a href="global.c#save_qhull">qh_save_qhull</a> saves
qhull for a later qh_restore_qhull() </li>
<li><a href="global.c#strtol">qh_strtol</a> duplicates
strtod() and strtol() </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,305 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>io.c -- input and output operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>io.c -- input and output operations</h2>
<blockquote>
<p>Qhull provides a wide range of input
and output options. To organize the code, most output formats use
the same driver: </p>
<pre>
qh_printbegin( fp, format, facetlist, facets, printall );
FORALLfacet_( facetlist )
qh_printafacet( fp, format, facet, printall );
FOREACHfacet_( facets )
qh_printafacet( fp, format, facet, printall );
qh_printend( fp, format );
</pre>
<p>Note the 'printall' flag. It selects whether or not
qh_skipfacet() is tested. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
<a href="qh-globa.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
<a href="qh-mem.htm#TOC">Mem</a> &#149; <a href="qh-merge.htm#TOC">Merge</a> &#149;
<a href="qh-poly.htm#TOC">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149;
<a href="qh-set.htm#TOC">Set</a> &#149; <a href="qh-stat.htm#TOC">Stat</a> &#149;
<a href="qh-user.htm#TOC">User</a> </p>
<h3>Index to <a href="io.c">io.c</a> and <a href="io.h">io.h</a></h3>
<ul>
<li><a href="#iconst">io.h constants and types</a> </li>
<li><a href="#ilevel">User level functions</a> </li>
<li><a href="#iprint">Print functions for all output formats</a></li>
<li><a href="#itext">Text output functions</a> </li>
<li><a href="#iutil">Text utility functions</a></li>
<li><a href="#igeom">Geomview output functions</a> </li>
<li><a href="#iview">Geomview utility functions</a></li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iconst">io.h constants and types</a></h3>
<ul>
<li><a href="io.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
of first two lines of stdin </li>
<li><a href="io.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
values of white space </li>
<li><a href="io.h#printvridgeT">printvridgeT</a> function to
print results of qh_printvdiagram or qh_eachvoronoi</li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
<ul>
<li><a href="io.c#copyfilename">qh_copyfilename</a>
copy filename identified by qh_skipfilename
<li><a href="io.c#eachvoronoi_all">qh_eachvoronoi_all</a>
visit each Voronoi ridge of the Voronoi diagram
<li><a href="io.c#prepare_output">qh_prepare_output</a>
prepare Qhull for output (called by qh_produce_output())
<li><a href="io.c#printhelp_degenerate">qh_printhelp_degenerate</a>
prints descriptive message for precision error </li>
<li><a href="io.c#printhelp_singular">qh_printhelp_singular</a>
print help message for singular data </li>
<li><a href="libqhull.c#printsummary">qh_printsummary</a> print
summary ('s')</li>
<li><a href="io.c#produce_output">qh_produce_output</a>
prints out the result of qhull()</li>
<li><a href="io.c#produce_output">qh_produce_output2</a>
prints out the result of qhull() without calling qh_prepare_output()</li>
<li><a href="io.c#readfeasible">qh_readfeasible</a> read
interior point from remainder and qh fin ('H')</li>
<li><a href="io.c#readpoints">qh_readpoints</a> read input
points </li>
<li><a href="io.c#setfeasible">qh_setfeasible</a> set
interior point from qh feasible_string ('Hn,n,n')</li>
<li><a href="io.c#skipfilename">qh_skipfilename</a>
skip filename in string
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iprint">Print functions for all
output formats</a></h3>
<ul>
<li><a href="io.c#countfacets">qh_countfacets</a> count good
facets for printing and set visitid </li>
<li><a href="io.c#markkeep">qh_markkeep</a> mark good facets
that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
<li><a href="io.c#order_vertexneighbors">qh_order_vertexneighbors</a>
order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
<li><a href="io.c#printafacet">qh_printafacet</a> print facet
in an output format </li>
<li><a href="io.c#printbegin">qh_printbegin</a> print header
for an output format </li>
<li><a href="io.c#printend">qh_printend</a> print trailer for
an output format </li>
<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
print facets in a facetlist</li>
<li><a href="io.c#printfacets">qh_printfacets</a> print
facetlist and/or facet set in an output format </li>
<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
print neighborhood of one or two facets ('Po')</li>
<li><a href="io.c#produce_output">qh_produce_output</a>
print the results of qh_qhull() </li>
<li><a href="io.c#skipfacet">qh_skipfacet</a> True if not
printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
<li><a href="io.c#facetvertices">qh_facetvertices</a> return
vertices in a set of facets ('p')</li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
<ul>
<li><a href="io.c#eachvoronoi">qh_eachvoronoi</a>
print or visit each Voronoi ridge for an input site of the Voronoi diagram
<li><a href="io.c#printextremes">qh_printextremes</a> print
extreme points by point ID (vertices of convex hull) ('Fx')</li>
<li><a href="io.c#printextremes_2d">qh_printextremes_2d</a> print
2-d extreme points by point ID ('Fx')</li>
<li><a href="io.c#printextremes_d">qh_printextremes_d</a> print
extreme points of input sites for Delaunay triangulations ('Fx')</li>
<li><a href="io.c#printfacet">qh_printfacet</a> print all
fields of a facet ('f')</li>
<li><a href="io.c#printfacet2math">qh_printfacet2math</a> print
2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
<li><a href="io.c#printfacet3math">qh_printfacet3math</a>
print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
<li><a href="io.c#printfacet3vertex">qh_printfacet3vertex</a>
print vertices for a 3-d facet ('i', 'o')</li>
<li><a href="io.c#printfacetheader">qh_printfacetheader</a>
prints header fields of a facet ('f')</li>
<li><a href="io.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
<li><a href="io.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
<li><a href="io.c#printfacetridges">qh_printfacetridges</a>
prints ridges of a facet ('f')</li>
<li><a href="io.c#printpoints_out">qh_printpoints_out</a> prints
vertices for facets by their point coordinates ('p')</li>
<li><a href="io.c#printridge">qh_printridge</a> print all
fields for a ridge ('f')</li>
<li><a href="io.c#printvdiagram">qh_printvdiagram</a> print
voronoi diagram as Voronoi vertices for each input pair</li>
<li><a href="io.c#printvertex">qh_printvertex</a> print all
fields for a vertex ('f')</li>
<li><a href="io.c#printvertexlist">qh_printvertexlist</a>
print vertices used by a list or set of facets ('f')</li>
<li><a href="io.c#printvertices">qh_printvertices</a> print a
set of vertices ('f')</li>
<li><a href="io.c#printvneighbors">qh_printvneighbors</a>
print vertex neighbors of vertices ('FN')</li>
<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
voronoi diagram in 'o' or 'G' format</li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
<ul>
<li><a href="io.c#dfacet">dfacet</a> print facet by ID </li>
<li><a href="io.c#dvertex">dvertex</a> print vertex by ID </li>
<li><a href="io.c#compare_facetarea">qh_compare_facetarea</a>
used by qsort() to order facets by area </li>
<li><a href="io.c#compare_facetmerge">qh_compare_facetmerge</a>
used by qsort() to order facets by number of merges </li>
<li><a href="io.c#compare_facetvisit">qh_compare_facetvisit</a>
used by qsort() to order facets by visit ID or ID </li>
<li><a href="io.c#compare_vertexpoint">qh_compare_vertexpoint</a>
used by qsort() to order vertices by point ID </li>
<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
ridge for an input site
<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
ridge for an input site
<li><a href="io.c#facet2point">qh_facet2point</a> return two
projected temporary vertices for a 2-d facet ('m', 'G')</li>
<li><a href="io.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
vertices for printing
<li><a href="io.c#printcenter">qh_printcenter</a> print
facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
<li><a href="io.c#printpoint">qh_printpoint</a>, qh_printpointid, print
coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
<li><a href="io.c#printpoint3">qh_printpoint3</a> prints 2-d,
3-d, or 4-d point as 3-d coordinates ('G')</li>
<li><a href="io.c#printvdiagram2">qh_printvdiagram2</a> print
voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
<li><a href="io.c#printvnorm">qh_printvnorm</a> print
separating plane of the Voronoi diagram for a pair of input sites</li>
<li><a href="io.c#printvridge">qh_printvridge</a> print
ridge of the Voronoi diagram for a pair of input sites</li>
<li><a href="io.c#projectdim3">qh_projectdim3</a> project 2-d
3-d or 4-d point to a 3-d point ('G')</li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
<ul>
<li><a href="io.c#printfacet2geom">qh_printfacet2geom</a>
print facet as a 2-d VECT object </li>
<li><a href="io.c#printfacet2geom_points">qh_printfacet2geom_points</a>
print points as a 2-d VECT object with offset </li>
<li><a href="io.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
print Geomview OFF for a 3-d nonsimplicial facet. </li>
<li><a href="io.c#printfacet3geom_points">qh_printfacet3geom_points</a>
prints a 3-d facet as OFF Geomview object. </li>
<li><a href="io.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
print Geomview OFF for a 3-d simplicial facet. </li>
<li><a href="io.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
print Geomview 4OFF file for a 4d nonsimplicial facet </li>
<li><a href="io.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
print Geomview 4OFF file for a 4d simplicial facet </li>
<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
print hyperplane intersection as OFF or 4OFF </li>
<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
voronoi diagram in 'o' or 'G' format</li>
</ul>
<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
<ul>
<li><a href="io.c#geomplanes">qh_geomplanes</a>
return outer and inner planes for Geomview</li>
<li><a href="io.c#printcentrum">qh_printcentrum</a> print
centrum for a facet in OOGL format </li>
<li><a href="io.c#printend4geom">qh_printend4geom</a> helper
function for qh_printbegin/printend </li>
<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
print Geomview OFF or 4OFF for the intersection of two
hyperplanes in 3-d or 4-d </li>
<li><a href="io.c#printline3geom">qh_printline3geom</a> prints a
line as a VECT </li>
<li><a href="io.c#printpointvect">qh_printpointvect</a>
prints a 2-d or 3-d point as 3-d VECT's </li>
<li><a href="io.c#printpointvect2">qh_printpointvect2</a>
prints a 2-d or 3-d point as 2 3-d VECT's </li>
<li><a href="io.c#printspheres">qh_printspheres</a> prints 3-d
vertices as OFF spheres </li>
</ul>
<p>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,145 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>mem.c -- memory operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>mem.c -- memory operations</h2>
<blockquote>
<p>Qhull uses quick-fit memory allocation. It maintains a
set of free lists for a variety of small allocations. A
small request returns a block from the best fitting free
list. If the free list is empty, Qhull allocates a block
from a reserved buffer. </p>
<p>Use 'T5' to trace memory allocations.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <b>Mem</b>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="mem.c">mem.c</a> and
<a href="mem.h">mem.h</a></h3>
<ul>
<li><a href="#etype">mem.h data types</a> </li>
<li><a href="#emacro">mem.h macros</a> </li>
<li><a href="#efunc">User level functions</a> </li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="etype">mem.h data types and constants</a></h3>
<ul>
<li><a href="mem.h#ptr_intT">ptr_intT</a> for casting
a void* to an integer-type </li>
<li><a href="mem.h#qhmemT">qhmemT</a> global memory
structure for mem.c </li>
<li><a href="mem.h#NOmem">qh_NOmem</a> disable memory allocation</li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="emacro">mem.h macros</a></h3>
<ul>
<li><a href="mem.h#memalloc_">qh_memalloc_</a>
allocate memory</li>
<li><a href="mem.h#memfree_">qh_memfree_</a> free
memory</li>
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="efunc">User level
functions</a></h3>
<ul>
<li><a href="mem.c#memalloc">qh_memalloc</a> allocate
memory </li>
<li><a href="mem.c#memcheck">qh_memcheck</a>
quick check of memory for internal consistency</li>
<li><a href="mem.c#memfree">qh_memfree</a> free
memory </li>
<li><a href="mem.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem.c#memstatistics">qh_memstatistics</a>
print memory statistics </li>
<li><a href="mem.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
<li><a href="mem.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
</ul>
<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="m">Initialization and
termination functions</a></h3>
<ul>
<li><a href="mem.c#intcompare">qh_intcompare</a> used by
qsort and bsearch to compare two integers </li>
<li><a href="mem.c#memfreeshort">qh_memfreeshort</a>
frees up all short and qhmem memory allocations </li>
<li><a href="mem.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem.c#meminitbuffers">qh_meminitbuffers</a>
initialize qhmem </li>
<li><a href="mem.c#memsetup">qh_memsetup</a> set up
memory after running memsize() </li>
<li><a href="mem.c#memsize">qh_memsize</a> define a free
list for this size </li>
<li><a href="mem.c#memstatistics">qh_memstatistics</a>
print out memory statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,366 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>merge.c -- facet merge operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>merge.c -- facet merge operations</h2>
<blockquote>
<p>Qhull handles precision problems by merged facets or joggled input.
Except for redundant vertices, it corrects a problem by
merging two facets. When done, all facets are clearly
convex. See <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
for further information. </p>
<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
instead of merging facets. </p>
<p>Qhull detects and corrects the following problems: </p>
<ul>
<li><b>More than two facets meeting at a ridge. </b>When
Qhull creates facets, it creates an even number
of facets for each ridge. A convex hull always
has two facets for each ridge. More than two
facets may be created if non-adjacent facets
share a vertex. This is called a <em>duplicate
ridge</em>. In 2-d, a duplicate ridge would
create a loop of facets. </li>
</ul>
<ul>
<li><b>A facet contained in another facet. </b>Facet
merging may leave all vertices of one facet as a
subset of the vertices of another facet. This is
called a <em>redundant facet</em>. </li>
</ul>
<ul>
<li><b>A facet with fewer than three neighbors. </b>Facet
merging may leave a facet with one or two
neighbors. This is called a <em>degenerate facet</em>.
</li>
</ul>
<ul>
<li><b>A facet with flipped orientation. </b>A
facet's hyperplane may define a halfspace that
does not include the interior point.This is
called a <em>flipped facet</em>. </li>
</ul>
<ul>
<li><strong>A coplanar horizon facet.</strong> A
newly processed point may be coplanar with an
horizon facet. Qhull creates a new facet without
a hyperplane. It links new facets for the same
horizon facet together. This is called a <em>samecycle</em>.
The new facet or samecycle is merged into the
horizon facet. </li>
</ul>
<ul>
<li><b>Concave facets. </b>A facet's centrum may be
above a neighboring facet. If so, the facets meet
at a concave angle. </li>
</ul>
<ul>
<li><b>Coplanar facets. </b>A facet's centrum may be
coplanar with a neighboring facet (i.e., it is
neither clearly below nor clearly above the
facet's hyperplane). Qhull removes coplanar
facets in independent sets sorted by angle.</li>
</ul>
<ul>
<li><b>Redundant vertex. </b>A vertex may have fewer
than three neighboring facets. If so, it is
redundant and may be renamed to an adjacent
vertex without changing the topological
structure.This is called a <em>redundant vertex</em>.
</li>
</ul>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <b>Merge</b> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="merge.c">merge.c</a> and
<a href="merge.h">merge.h</a></h3>
<ul>
<li><a href="#mtype">merge.h data types, macros, and
global sets</a> </li>
<li><a href="#mconst">merge.h constants</a> </li>
</ul>
<ul>
<li><a href="#mtop">top-level merge functions</a> </li>
<li><a href="#mset">functions for identifying merges</a></li>
<li><a href="#mbest">functions for determining the
best merge</a> </li>
<li><a href="#mmerge">functions for merging facets</a>
</li>
<li><a href="#mcycle">functions for merging a cycle
of facets</a> </li>
<li><a href="#mrename">functions for renaming a
vertex</a> </li>
<li><a href="#mvertex">functions for identifying
vertices for renaming</a> </li>
<li><a href="#mcheck">functions for check and trace</a> </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtype">merge.h data
types, macros, and global sets</a></h3>
<ul>
<li><a href="merge.h#mergeT">mergeT</a> structure to
identify a merge of two facets</li>
<li><a href="merge.h#FOREACHmerge_">FOREACHmerge_</a>
assign 'merge' to each merge in merges </li>
<li><a href="libqhull.h#qh-set">qh global sets</a>
qh.facet_mergeset contains non-convex merges
while qh.degen_mergeset contains degenerate and
redundant facets</li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mconst">merge.h
constants</a></h3>
<ul>
<li><a href="libqhull.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
<li><a href="merge.h#MRG">MRG...</a> indicates the
type of a merge (mergeT-&gt;type)</li>
<li><a href="merge.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
indicates redundant merge in mergeT-&gt;angle </li>
<li><a href="merge.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
indicates degenerate facet in mergeT-&gt;angle </li>
<li><a href="merge.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
offset to indicate concave facets in
mergeT-&gt;angle </li>
<li><a href="merge.h#qh_MERGEapex">qh_MERGEapex</a>
flag for qh_mergefacet() to indicate an apex
merge </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtop">top-level merge
functions</a></h3>
<ul>
<li><a href="merge.c#all_merges">qh_all_merges</a>
merge all non-convex facets </li>
<li><a href="merge.c#checkzero">qh_checkzero</a>
check that facets are clearly convex </li>
<li><a href="merge.c#flippedmerges">qh_flippedmerges</a>
merge flipped facets into best neighbor </li>
<li><a href="merge.c#forcedmerges">qh_forcedmerges</a>
merge all duplicate ridges </li>
<li><a href="merge.c#merge_degenredundant">qh_merge_degenredundant</a>
merge degenerate and redundant facets </li>
<li><a href="merge.c#merge_nonconvex">qh_merge_nonconvex</a>
merge a non-convex ridge </li>
<li><a href="merge.c#premerge">qh_premerge</a>
pre-merge non-convex facets </li>
<li><a href="merge.c#postmerge">qh_postmerge</a>
post-merge nonconvex facets as defined by
maxcentrum/maxangle </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mset">functions for
identifying merges</a></h3>
<ul>
<li><a href="merge.c#appendmergeset">qh_appendmergeset</a>
appends an entry to qh.facet_mergeset</li>
<li><a href="merge.c#compareangle">qh_compareangle</a>
used by qsort() to order merges </li>
<li><a href="merge.c#comparemerge">qh_comparemerge</a>
used by qsort() to order merges </li>
<li><a href="merge.c#degen_redundant_facet">qh_degen_redundant_facet</a>
check for a degenerate and redundant facet</li>
<li><a href="merge.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
append degenerate and redundant neighbors to
qh.degen_mergeset </li>
<li><a href="merge.c#getmergeset_initial">qh_getmergeset_initial</a>
build initial qh.facet_mergeset </li>
<li><a href="merge.c#getmergeset">qh_getmergeset</a>
update qh.facet_mergeset </li>
<li><a href="merge.c#mark_dupridges">qh_mark_dupridges</a>
add duplicated ridges to qh.facet_mergeset</li>
<li><a href="merge.c#maydropneighbor">qh_maydropneighbor</a>
drop neighbor relationship if no ridge between
facet and neighbor </li>
<li><a href="merge.c#test_appendmerge">qh_test_appendmerge</a>
test a pair of facets for convexity and append to
qh.facet_mergeset if non-convex </li>
<li><a href="merge.c#test_vneighbors">qh_test_vneighbors</a>
test vertex neighbors for convexity </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mbest">functions for
determining the best merge</a></h3>
<ul>
<li><a href="merge.c#findbest_test">qh_findbest_test</a>
test neighbor for best merge </li>
<li><a href="merge.c#findbestneighbor">qh_findbestneighbor</a>
finds best neighbor of a facet for merging (i.e.,
closest hyperplane) </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mmerge">functions for
merging facets</a></h3>
<ul>
<li><a href="merge.c#copynonconvex">qh_copynonconvex</a>
copy non-convex flag to another ridge for the
same neighbor </li>
<li><a href="merge.c#makeridges">qh_makeridges</a>
creates explicit ridges between simplicial facets
</li>
<li><a href="merge.c#mergefacet">qh_mergefacet</a>
merges one facet into another facet</li>
<li><a href="merge.c#mergeneighbors">qh_mergeneighbors</a>
merges the neighbors of two facets </li>
<li><a href="merge.c#mergeridges">qh_mergeridges</a>
merges the ridge sets of two facets </li>
<li><a href="merge.c#mergesimplex">qh_mergesimplex</a>
merge a simplicial facet into another simplicial
facet </li>
<li><a href="merge.c#mergevertex_del">qh_mergevertex_del</a>
delete a vertex due to merging one facet into
another facet </li>
<li><a href="merge.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
merge the vertex neighbors of two facets </li>
<li><a href="merge.c#mergevertices">qh_mergevertices</a>
merge the vertex sets of two facets </li>
<li><a href="merge.c#newvertices">qh_newvertices</a>
register all vertices as new vertices </li>
<li><a href="merge.c#updatetested">qh_updatetested</a>
clear tested flags and centrums involved in a
merge </li>
<li><a href="merge.c#willdelete">qh_willdelete</a>
moves facet to qh.visible_list; sets replacement
or NULL </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcycle">functions for
merging a cycle of facets</a></h3>
<p>If a point is coplanar with an horizon facet, the
corresponding new facets are linked together (a <em>samecycle</em>)
for merging.</p>
<ul>
<li><a href="merge.c#basevertices">qh_basevertices</a>
return temporary set of base vertices for a
samecycle </li>
<li><a href="merge.c#mergecycle">qh_mergecycle</a>
merge a samecycle into a horizon facet </li>
<li><a href="merge.c#mergecycle_all">qh_mergecycle_all</a>
merge all samecycles into horizon facets</li>
<li><a href="merge.c#mergecycle_facets">qh_mergecycle_facets</a>
finish merge of samecycle </li>
<li><a href="merge.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
merge neighbor sets for samecycle </li>
<li><a href="merge.c#mergecycle_ridges">qh_mergecycle_ridges</a>
merge ridge sets for samecycle </li>
<li><a href="merge.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
merge vertex neighbor sets for samecycle </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mrename">functions
for renaming a vertex</a></h3>
<ul>
<li><a href="merge.c#comparevisit">qh_comparevisit</a>
used by qsort() to order vertices by visitid</li>
<li><a href="merge.c#reducevertices">qh_reducevertices</a>
reduce vertex sets </li>
<li><a href="merge.c#redundant_vertex">qh_redundant_vertex</a>
returns true if detect and rename redundant
vertex </li>
<li><a href="merge.c#rename_sharedvertex">qh_rename_sharedvertex</a>
detect and rename a shared vertex </li>
<li><a href="merge.c#renameridgevertex">qh_renameridgevertex</a>
rename oldvertex to newvertex in a ridge </li>
<li><a href="merge.c#renamevertex">qh_renamevertex</a>
rename oldvertex to newvertex in ridges </li>
<li><a href="merge.c#remove_extravertices">qh_remove_extravertices</a>
remove extra vertices in non-simplicial facets </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mvertex">functions
for identifying vertices for renaming</a></h3>
<ul>
<li><a href="merge.c#find_newvertex">qh_find_newvertex</a>
locate new vertex for renaming old vertex </li>
<li><a href="merge.c#hashridge">qh_hashridge</a> add
ridge to hashtable </li>
<li><a href="merge.c#hashridge_find">qh_hashridge_find</a>
returns matching ridge in hashtable</li>
<li><a href="merge.c#neighbor_intersections">qh_neighbor_intersections</a>
return intersection of vertex sets for
neighboring facets </li>
<li><a href="merge.c#vertexridges">qh_vertexridges</a>
return temporary set of ridges adjacent to a
vertex </li>
<li><a href="merge.c#vertexridges_facet">qh_vertexridges_facet</a>
add adjacent ridges for a vertex in facet </li>
</ul>
<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcheck">functions for check and
trace</a></h3>
<ul>
<li><a href="merge.c#checkconnect">qh_checkconnect</a>
check that new facets are connected </li>
<li><a href="merge.c#tracemerge">qh_tracemerge</a>
print trace message after merge </li>
<li><a href="merge.c#tracemerging">qh_tracemerging</a>
print trace message during post-merging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,485 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>poly.c, poly2.c -- polyhedron operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>poly.c, poly2.c -- polyhedron operations</h2>
<blockquote>
<p>Qhull uses dimension-free terminology. Qhull builds a
polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
simplicial complex of faces with geometric information for the
top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
is a <em>vertex</em>. For example in 3-d, a facet is a polygon
and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
and a vertex (the <em>apex</em>). See
<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
<p>Qhull's primary data structure is a polyhedron. A
polyhedron is a list of facets. Each facet has a set of
neighboring facets and a set of vertices. Each facet has a
hyperplane. For example, a tetrahedron has four facets.
If its vertices are <em>a, b, c, d</em>, and its facets
are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
<blockquote>
<ul>
<li>facet 1 <ul>
<li>vertices: b c d </li>
<li>neighbors: 2 3 4 </li>
</ul>
</li>
<li>facet 2 <ul>
<li>vertices: a c d </li>
<li>neighbors: 1 3 4 </li>
</ul>
</li>
<li>facet 3 <ul>
<li>vertices: a b d </li>
<li>neighbors: 1 2 4 </li>
</ul>
</li>
<li>facet 4 <ul>
<li>vertices: a b c </li>
<li>neighbors: 1 2 3 </li>
</ul>
</li>
</ul>
</blockquote>
<p>A facet may be simplicial or non-simplicial. In 3-d, a
<i>simplicial facet</i> has three vertices and three
neighbors. A <i>nonsimplicial facet</i> has more than
three vertices and more than three neighbors. A
nonsimplicial facet has a set of ridges and a centrum. </p>
<p>
A simplicial facet has an orientation. An <i>orientation</i>
is either <i>top</i> or <i>bottom</i>.
The flag, <tt>facet-&gt;toporient,</tt>
defines the orientation of the facet's vertices. For example in 3-d,
'top' is left-handed orientation (i.e., the vertex order follows the direction
of the left-hand fingers when the thumb is pointing away from the center).
Except for axis-parallel facets in 5-d and higher, topological orientation
determines the geometric orientation of the facet's hyperplane.
<p>A nonsimplicial facet is due to merging two or more
facets. The facet's ridge set determine a simplicial
decomposition of the facet. Each ridge is a 1-face (i.e.,
it has two vertices and two neighboring facets). The
orientation of a ridge is determined by the order of the
neighboring facets. The flag, <tt>facet-&gt;toporient,</tt>is
ignored. </p>
<p>A nonsimplicial facet has a centrum for testing
convexity. A <i>centrum</i> is a point on the facet's
hyperplane that is near the center of the facet. Except
for large facets, it is the arithmetic average of the
facet's vertices. </p>
<p>A nonsimplicial facet is an approximation that is
defined by offsets from the facet's hyperplane. When
Qhull finishes, the <i>outer plane</i> is above all
points while the <i>inner plane</i> is below the facet's
vertices. This guarantees that any exact convex hull
passes between the inner and outer planes. The outer
plane is defined by <tt>facet-&gt;maxoutside</tt> while
the inner plane is computed from the facet's vertices.</p>
<p>Qhull 3.1 includes triangulation of non-simplicial facets
('<a href="../../html/qh-optq.htm#Qt">Qt</a>').
These facets,
called <i>tricoplanar</i>, share the same normal. centrum, and Voronoi center.
One facet (keepcentrum) owns these data structures.
While tricoplanar facets are more accurate than the simplicial facets from
joggled input, they
may have zero area or flipped orientation.
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <b>Poly</b>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="poly.c">poly.c</a>,
<a href="poly2.c">poly2.c</a>, <a href="poly.h">poly.h</a>,
and <a href="libqhull.h">libqhull.h</a></h3>
<ul>
<li><a href="#ptype">Data types and global
lists for polyhedrons</a> </li>
<li><a href="#pconst">poly.h constants</a> </li>
<li><a href="#pgall">Global FORALL macros</a> </li>
<li><a href="#pall">FORALL macros</a> </li>
<li><a href="#peach">FOREACH macros</a> </li>
<li><a href="#pieach">Indexed FOREACH macros</a> </li>
<li><a href="#pmacro">Other macros for polyhedrons</a><p>&nbsp;</li>
<li><a href="#plist">Facetlist functions</a> </li>
<li><a href="#pfacet">Facet functions</a> </li>
<li><a href="#pvertex">Vertex, ridge, and point
functions</a> </li>
<li><a href="#phash">Hashtable functions</a> </li>
<li><a href="#pnew">Allocation and deallocation
functions</a> </li>
<li><a href="#pcheck">Check functions</a> </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="ptype">Data
types and global lists for polyhedrons</a></h3>
<ul>
<li><a href="libqhull.h#facetT">facetT</a> defines a
facet </li>
<li><a href="libqhull.h#ridgeT">ridgeT</a> defines a
ridge </li>
<li><a href="libqhull.h#vertexT">vertexT</a> defines a
vertex </li>
<li><a href="libqhull.h#qh-lists">qh facet and vertex
lists</a> lists of facets and vertices </li>
<li><a href="libqhull.h#qh-set">qh global sets</a>
global sets for merging, hashing, input, etc. </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pconst">poly.h constants</a></h3>
<ul>
<li><a href="poly.h#ALGORITHMfault">ALGORITHMfault</a>
flag to not report errors in qh_checkconvex() </li>
<li><a href="poly.h#DATAfault">DATAfault</a> flag to
report errors in qh_checkconvex() </li>
<li><a href="poly.h#DUPLICATEridge">DUPLICATEridge</a>
special value for facet-&gt;neighbor to indicate
a duplicate ridge </li>
<li><a href="poly.h#MERGEridge">MERGEridge</a>
special value for facet-&gt;neighbor to indicate
a merged ridge </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pgall">Global FORALL
macros</a></h3>
<ul>
<li><a href="libqhull.h#FORALLfacets">FORALLfacets</a>
assign 'facet' to each facet in qh.facet_list </li>
<li><a href="poly.h#FORALLnew_facets">FORALLnew_facets</a>
assign 'facet' to each facet in qh.newfacet_list </li>
<li><a href="poly.h#FORALLvisible_facets">FORALLvisible_facets</a>
assign 'visible' to each visible facet in
qh.visible_list </li>
<li><a href="libqhull.h#FORALLpoints">FORALLpoints</a>
assign 'point' to each point in qh.first_point,
qh.num_points </li>
<li><a href="libqhull.h#FORALLvertices">FORALLvertices</a>
assign 'vertex' to each vertex in qh.vertex_list </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
<ul>
<li><a href="poly.h#FORALLfacet_">FORALLfacet_</a>
assign 'facet' to each facet in facetlist </li>
<li><a href="libqhull.h#FORALLpoint_">FORALLpoint_</a>
assign 'point' to each point in points array</li>
<li><a href="poly.h#FORALLsame_">FORALLsame_</a>
assign 'same' to each facet in samecycle</li>
<li><a href="poly.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
assign 'same' to each facet in samecycle</li>
<li><a href="poly.h#FORALLvertex_">FORALLvertex_</a>
assign 'vertex' to each vertex in vertexlist </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
<ul>
<li><a href="libqhull.h#FOREACHfacet_">FOREACHfacet_</a>
assign 'facet' to each facet in facets </li>
<li><a href="libqhull.h#FOREACHneighbor_">FOREACHneighbor_</a>
assign 'neighbor' to each facet in
facet-&gt;neighbors or vertex-&gt;neighbors</li>
<li><a href="poly.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
assign 'newfacet' to each facet in facet set </li>
<li><a href="libqhull.h#FOREACHpoint_">FOREACHpoint_</a>
assign 'point' to each point in points set </li>
<li><a href="libqhull.h#FOREACHridge_">FOREACHridge_</a>
assign 'ridge' to each ridge in ridge set </li>
<li><a href="libqhull.h#FOREACHvertex_">FOREACHvertex_</a>
assign 'vertex' to each vertex in vertex set </li>
<li><a href="poly.h#FOREACHvertexA_">FOREACHvertexA_</a>
assign 'vertexA' to each vertex in vertex set</li>
<li><a href="poly.h#FOREACHvisible_">FOREACHvisible_</a>
assign 'visible' to each facet in facet set </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pieach">Indexed
FOREACH macros</a></h3>
<ul>
<li><a href="libqhull.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
assign 'facet' and 'facet_i' to each facet in
facet set </li>
<li><a href="libqhull.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
assign 'neighbor' and 'neighbor_i' to each facet
in facet-&gt;neighbors or vertex-&gt;neighbors</li>
<li><a href="libqhull.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
assign 'point' and 'point_i' to each point in
points set </li>
<li><a href="libqhull.h#FOREACHridge_i_">FOREACHridge_i_</a>
assign 'ridge' and 'ridge_i' to each ridge in
ridges set </li>
<li><a href="libqhull.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
assign 'vertex' and 'vertex_i' to each vertex in
vertices set </li>
<li><a href="poly.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
assign 'vertex' to each vertex in vertex set;
reverse the order of first two vertices </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
<ul>
<li><a href="libqhull.h#getid_">getid_</a> return ID for
a facet, ridge, or vertex </li>
<li><a href="libqhull.h#otherfacet_">otherfacet_</a>
return neighboring facet for a ridge in a facet </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="plist">Facetlist
functions</a></h3>
<ul>
<li><a href="poly.c#appendfacet">qh_appendfacet</a>
appends facet to end of qh.facet_list</li>
<li><a href="poly.c#attachnewfacets">qh_attachnewfacets</a>
attach new facets in qh.newfacet_list to the
horizon </li>
<li><a href="poly2.c#findgood">qh_findgood</a>
identify good facets for qh.PRINTgood </li>
<li><a href="poly2.c#findgood_all">qh_findgood_all</a>
identify more good facets for qh.PRINTgood </li>
<li><a href="poly2.c#furthestnext">qh_furthestnext</a>
move facet with furthest of furthest points to
facet_next </li>
<li><a href="poly2.c#initialhull">qh_initialhull</a>
construct the initial hull as a simplex of
vertices </li>
<li><a href="poly2.c#nearcoplanar">qh_nearcoplanar</a>
remove near-inside points from coplanar sets</li>
<li><a href="poly2.c#prependfacet">qh_prependfacet</a>
prepends facet to start of facetlist </li>
<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
print facets in a facetlist</li>
<li><a href="poly2.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
<li><a href="poly.c#removefacet">qh_removefacet</a>
unlinks facet from qh.facet_list</li>
<li><a href="poly2.c#resetlists">qh_resetlists</a>
reset qh.newvertex_list, qh.newfacet_list, and
qh.visible_list </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pfacet">Facet
functions</a></h3>
<ul>
<li><a href="poly2.c#createsimplex">qh_createsimplex</a>
create a simplex of facets from a set of vertices
</li>
<li><a href="poly2.c#findbestlower">qh_findbestlower</a> find best
non-upper, non-flipped facet for point at upperfacet</li>
<li><a href="poly2.c#furthestout">qh_furthestout</a>
make furthest outside point the last point of a
facet's outside set </li>
<li><a href="poly.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
make new facets from ridges of visible facets </li>
<li><a href="poly.c#makenew_simplicial">qh_makenew_simplicial</a>
make new facets for horizon neighbors </li>
<li><a href="poly.c#makenewfacet">qh_makenewfacet</a>
create a facet from vertices and apex </li>
<li><a href="poly2.c#makenewfacets">qh_makenewfacets</a>
make new facets from vertex, horizon facets, and
visible facets </li>
<li><a href="poly.c#makenewplanes">qh_makenewplanes</a>
make new hyperplanes for facets </li>
<li><a href="poly2.c#outcoplanar">qh_outcoplanar</a>
move points from outside set to coplanar set </li>
<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
compute Voronoi centers for all facets </li>
<li><a href="poly2.c#triangulate">qh_triangulate</a>
triangulate non-simplicial facets</li>
<li><a href="poly2.c#triangulate_facet">qh_triangulate_facet</a>
triangulate a non-simplicial facet</li>
<li><a href="poly2.c#triangulate_link">qh_triangulate_link</a>
link facets together from qh_triangulate</li>
<li><a href="poly2.c#triangulate_mirror">qh_triangulate_mirror</a>
delete mirrored facets from qh_triangulate</li>
<li><a href="poly2.c#triangulate_null">qh_triangulate_null</a>
delete null facet from qh_triangulate</li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pvertex">Vertex,
ridge, and point functions</a></h3>
<ul>
<li><a href="poly.c#appendvertex">qh_appendvertex</a>
append vertex to end of qh.vertex_list, </li>
<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
ridge for an input site
<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
ridge for an input site
<li><a href="poly2.c#facet3vertex">qh_facet3vertex</a>
return an oriented vertex set for a 3-d facet </li>
<li><a href="poly.c#facetintersect">qh_facetintersect</a>
return intersection of simplicial facets </li>
<li><a href="poly2.c#initialvertices">qh_initialvertices</a>
return non-singular set of initial vertices </li>
<li><a href="poly2.c#isvertex">qh_isvertex</a> true
if point is in a vertex set </li>
<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
return nearest vertex to point </li>
<li><a href="poly2.c#nextridge3d">qh_nextridge3d</a>
iterate over each ridge and vertex for a 3-d
facet </li>
<li><a href="poly2.c#point">qh_point</a> return point
for a point ID </li>
<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
return temporary set of facets indexed by point
ID </li>
<li><a href="poly.c#pointid">qh_pointid</a> return ID
for a point</li>
<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
return temporary set of vertices indexed by point
ID </li>
<li><a href="poly.c#removevertex">qh_removevertex</a>
unlink vertex from qh.vertex_list, </li>
<li><a href="poly.c#updatevertices">qh_updatevertices</a>
update vertex neighbors and delete interior
vertices </li>
<li><a href="poly2.c#vertexintersect">qh_vertexintersect</a>
intersect two vertex sets </li>
<li><a href="poly2.c#vertexintersect_new">qh_vertexintersect_new</a>
return intersection of two vertex sets </li>
<li><a href="poly2.c#vertexneighbors">qh_vertexneighbors</a>
for each vertex in hull, determine facet
neighbors </li>
<li><a href="poly2.c#vertexsubset">qh_vertexsubset</a>
returns True if vertexsetA is a subset of
vertexsetB </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
<ul>
<li><a href="poly2.c#addhash">qh_addhash</a> add hash
element to linear hash table</li>
<li><a href="poly.c#gethash">qh_gethash</a> return
hash value for a set</li>
<li><a href="poly2.c#matchduplicates">qh_matchduplicates</a>
match duplicate ridges in hash table </li>
<li><a href="poly.c#matchneighbor">qh_matchneighbor</a>
try to match subridge of new facet with a
neighbor </li>
<li><a href="poly.c#matchnewfacets">qh_matchnewfacets</a>
match new facets with their new facet neighbors </li>
<li><a href="poly.c#matchvertices">qh_matchvertices</a>
tests whether a facet and hash entry match at a
ridge </li>
<li><a href="poly2.c#newhashtable">qh_newhashtable</a>
allocate a new qh.hash_table </li>
<li><a href="poly2.c#printhashtable">qh_printhashtable</a>
print hash table </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pnew">Allocation and
deallocation functions</a></h3>
<ul>
<li><a href="poly2.c#clearcenters">qh_clearcenters</a>
clear old data from facet-&gt;center </li>
<li><a href="poly.c#deletevisible">qh_deletevisible</a>
delete visible facets and vertices </li>
<li><a href="poly.c#delfacet">qh_delfacet</a> free up
the memory occupied by a facet </li>
<li><a href="poly2.c#delridge">qh_delridge</a> delete
ridge</li>
<li><a href="poly2.c#delvertex">qh_delvertex</a>
delete vertex </li>
<li><a href="poly.c#newfacet">qh_newfacet</a> create
and allocate space for a facet </li>
<li><a href="poly.c#newridge">qh_newridge</a> create
and allocate space for a ridge </li>
<li><a href="poly2.c#newvertex">qh_newvertex</a>
create and allocate space for a vertex </li>
</ul>
<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pcheck">Check
functions</a></h3>
<ul>
<li><a href="poly2.c#check_bestdist">qh_check_bestdist</a>
check that points are not outside of facets </li>
<li><a href="poly2.c#check_dupridge">qh_check_dupridge</a>
check duplicate ridge between facet1 and facet2 for wide merge </li>
<li><a href="poly2.c#check_maxout">qh_check_maxout</a>
updates qh.max_outside and checks all points
against bestfacet </li>
<li><a href="poly2.c#check_output">qh_check_output</a>
check topological and geometric output</li>
<li><a href="poly2.c#check_point">qh_check_point</a>
check that point is not outside of facet </li>
<li><a href="poly2.c#check_points">qh_check_points</a>
check that all points are inside all facets </li>
<li><a href="poly2.c#checkconvex">qh_checkconvex</a>
check that each ridge in facetlist is convex </li>
<li><a href="poly2.c#checkfacet">qh_checkfacet</a>
check for consistency errors in facet </li>
<li><a href="poly.c#checkflipped">qh_checkflipped</a>
check facet orientation to the interior point </li>
<li><a href="poly2.c#checkflipped_all">qh_checkflipped_all</a>
check facet orientation for a facet list </li>
<li><a href="poly2.c#checkpolygon">qh_checkpolygon</a>
check topological structure </li>
<li><a href="poly2.c#checkvertex">qh_checkvertex</a>
check vertex for consistency </li>
<li><a href="poly2.c#infiniteloop">qh_infiniteloop</a>
report error for a loop of facets </li>
<li><a href="poly2.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,279 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>libqhull.c -- top-level functions and basic data types</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>libqhull.c -- top-level functions and basic data types</h2>
<blockquote>
<p>Qhull implements the Quickhull algorithm for computing
the convex hull. The Quickhull algorithm combines two
well-known algorithms: the 2-d quickhull algorithm and
the n-d beneath-beyond algorithm. See
<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
<p>This section provides an index to the top-level
functions and base data types. The top-level header file, <tt>libqhull.h</tt>,
contains prototypes for these functions.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <b>Qhull</b> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="libqhull.c">libqhull.c</a>,
<a href="libqhull.h">libqhull.h</a>, and
<a href="../qhull/unix.c">unix.c</a></h3>
<ul>
<li><a href="#qtype">libqhull.h and unix.c data types and
constants</a> </li>
<li><a href="#qmacro">libqhull.h other macros</a> </li>
<li><a href="#qfunc">Quickhull routines in call order</a> </li>
<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
<li><a href="#qout">Top-level routines for returning results</a></li>
<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtype">libqhull.h and unix.c
data types and constants</a></h3>
<ul>
<li><a href="libqhull.h#flagT">flagT</a> Boolean flag as
a bit </li>
<li><a href="libqhull.h#boolT">boolT</a> boolean value,
either True or False </li>
<li><a href="libqhull.h#CENTERtype">CENTERtype</a> to
distinguish facet-&gt;center </li>
<li><a href="libqhull.h#qh_PRINT">qh_PRINT</a> output
formats for printing (qh.PRINTout) </li>
<li><a href="libqhull.h#qh_ALL">qh_ALL</a> argument flag
for selecting everything </li>
<li><a href="libqhull.h#qh_ERR">qh_ERR</a> Qhull exit
codes for indicating errors </li>
<li><a href="libqhull.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
to distinguish error output from normal output [C++ only]</li>
<li><a href="../qhull/unix.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
<li><a href="../qhull/unix.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
<li><a href="../qhull/unix.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
<li><a href="global.c#qh_version">qh_version</a> version stamp</li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qmacro">libqhull.h other
macros</a></h3>
<ul>
<li><a href="qhull_a.h#traceN">traceN</a> print trace
message if <em>qh.IStracing &gt;= N</em>. </li>
<li><a href="qhull_a.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
unused variable to avoid warnings. </li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qfunc">Quickhull
routines in call order</a></h3>
<ul>
<li><a href="../qhull/unix.c#main">main</a> processes the
command line, calls qhull() to do the work, and
exits </li>
<li><a href="libqhull.c#qhull">qh_qhull</a> construct
the convex hull of a set of points </li>
<li><a href="libqhull.c#build_withrestart">qh_build_withrestart</a>
allow restarts while calling qh_buildhull</li>
<li><a href="poly2.c#initbuild">qh_initbuild</a>
initialize hull and outside sets with point array</li>
<li><a href="libqhull.c#partitionall">qh_partitionall</a>
partition all points into outside sets </li>
<li><a href="libqhull.c#buildhull">qh_buildhull</a>
construct a convex hull by adding points one at a
time </li>
<li><a href="libqhull.c#nextfurthest">qh_nextfurthest</a>
return next furthest point for processing </li>
<li><a href="libqhull.c#buildtracing">qh_buildtracing</a>
trace an iteration of buildhull </li>
<li><a href="libqhull.c#addpoint">qh_addpoint</a> add a
point to the convex hull </li>
<li><a href="libqhull.c#findhorizon">qh_findhorizon</a>
find the horizon and visible facets for a point </li>
<li><a href="libqhull.c#partitionvisible">qh_partitionvisible</a>
partition points from facets in qh.visible_list
to facets in qh.newfacet_list </li>
<li><a href="libqhull.c#partitionpoint">qh_partitionpoint</a>
partition a point as inside, coplanar with, or
outside a facet </li>
<li><a href="libqhull.c#partitioncoplanar">qh_partitioncoplanar</a>
partition coplanar point into a facet </li>
<li><a href="libqhull.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
<ul>
<li><a href="global.c#freebuild">qh_freebuild</a>
free memory used by qh_initbuild and qh_buildhull
</li>
<li><a href="global.c#checkflags">qh_checkflags</a>
check flags for multiple frontends to qhull
<li><a href="global.c#freeqhull">qh_freeqhull</a>
free memory used by qhull </li>
<li><a href="global.c#init_A">qh_init_A</a> called
before error handling initialized </li>
<li><a href="global.c#init_B">qh_init_B</a> called
after points are defined </li>
<li><a href="global.c#initflags">qh_initflags</a> set
flags and constants from command line </li>
<li><a href="rboxlib.c#rboxpoints">qh_rboxpoints</a>
generate points for qhull </li>
<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
restores a saved qhull </li>
<li><a href="global.c#save_qhull">qh_save_qhull</a>
saves qhull for later restoring </li>
<li><a href="user.c#user_memsizes">qh_user_memsizes</a>
define additional quick allocation sizes
</li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
<ul>
<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
implements Gram-Schmidt orthogonalization by rows </li>
<li><a href="geom2.c#projectinput">qh_projectinput</a>
project input along one or more dimensions +
Delaunay projection </li>
<li><a href="geom2.c#randommatrix">qh_randommatrix</a>
generate a random dimXdim matrix in range (-1,1) </li>
<li><a href="io.c#readpoints">qh_readpoints</a> read
points from input </li>
<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
input points using row matrix </li>
<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
input points using qh low_bound/high_bound </li>
<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
points to paraboloid for Delaunay triangulation </li>
<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
generate dual for halfspace intersection with interior
point </li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
<ul>
<li><a href="libqhull.c#addpoint">qh_addpoint</a> add
point to convex hull </li>
<li><a href="poly2.c#findbestfacet">qh_findbestfacet</a>
find facet that is furthest below a point </li>
<li><a href="poly2.c#findfacet_all">qh_findfacet_all</a>
exhaustive search for facet below a point </li>
<li><a href="libqhull.c#qhull">qh_qhull</a> construct
the convex hull of a set of points </li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
<ul>
<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
collect statistics for qh.facet_list </li>
<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
return nearest vertex to point </li>
<li><a href="poly2.c#point">qh_point</a> return point
for a point ID </li>
<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
return temporary set of facets indexed by point
ID </li>
<li><a href="poly.c#pointid">qh_pointid</a> return ID
for a point</li>
<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
return vertices (if any) for all points</li>
<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
print all statistics </li>
<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
print neighborhood of one or two facets </li>
<li><a href="libqhull.c#printsummary">qh_printsummary</a>
print summary </li>
<li><a href="io.c#produce_output">qh_produce_output</a>
print the results of qh_qhull() </li>
<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
compute Voronoi centers for all facets </li>
</ul>
<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
<ul>
<li><a href="io.c#dfacet">dfacet</a> print facet by
ID from debugger </li>
<li><a href="io.c#dvertex">dvertex</a> print vertex
by ID from debugger </li>
<li><a href="poly2.c#check_output">qh_check_output</a>
check output </li>
<li><a href="poly2.c#check_points">qh_check_points</a>
verify that all points are inside the convex hull
</li>
<li><a href="user.c#errexit">qh_errexit</a> report
error with a facet and a ridge</li>
<li><a href="libqhull.c#errexit2">qh_errexit2</a> report
error with two facets </li>
<li><a href="user.c#errprint">qh_errprint</a> print
erroneous facets, ridge, and vertex </li>
<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
print all fields for a list of facets </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,308 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>qset.c -- set data type and operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>qset.c -- set data type and operations</h2>
<blockquote>
<p>Qhull's data structures are constructed from sets. The
functions and macros in qset.c construct, iterate, and
modify these sets. They are the most frequently called
functions in Qhull. For this reason, efficiency is the
primary concern. </p>
<p>In Qhull, a <i>set</i> is represented by an unordered
array of pointers with a maximum size and a NULL
terminator (<a href="qset.h#setT">setT</a>).
Most sets correspond to mathematical sets
(i.e., the pointers are unique). Some sets are sorted to
enforce uniqueness. Some sets are ordered. For example,
the order of vertices in a ridge determine the ridge's
orientation. If you reverse the order of adjacent
vertices, the orientation reverses. Some sets are not
mathematical sets. They may be indexed as an array and
they may include NULL pointers. </p>
<p>The most common operation on a set is to iterate its
members. This is done with a 'FOREACH...' macro. Each set
has a custom macro. For example, 'FOREACHvertex_'
iterates over a set of vertices. Each vertex is assigned
to the variable 'vertex' from the pointer 'vertexp'. </p>
<p>Most sets are constructed by appending elements to the
set. The last element of a set is either NULL or the
index of the terminating NULL for a partially full set.
If a set is full, appending an element copies the set to
a larger array. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <b>Set</b>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="qset.c">qset.c</a> and
<a href="qset.h">qset.h</a></h3>
<ul>
<li><a href="#stype">Data types and constants</a> </li>
<li><a href="#seach">FOREACH macros</a> </li>
<li><a href="#saccess">access and size macros</a> </li>
<li><a href="#sint">internal macros</a> </li>
<li><a href="#saddr">address macros</a><p>&nbsp;</li>
<li><a href="#snew">Allocation and deallocation functions</a> </li>
<li><a href="#spred">Access and predicate functions</a>
</li>
<li><a href="#sadd">Add functions</a> </li>
<li><a href="#scheck">Check and print functions</a></li>
<li><a href="#scopy">Copy, compact, and zero functions</a></li>
<li><a href="#sdel">Delete functions</a> </li>
<li><a href="#stemp">Temporary set functions</a> </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stype">Data types and
constants</a></h3>
<ul>
<li><a href="qset.h#SETelemsize">SETelemsize</a> size
of a set element in bytes </li>
<li><a href="qset.h#setT">setT</a> a set with a
maximum size and a current size</li>
<li><a href="libqhull.h#qh-set">qh global sets</a>
global sets for temporary sets, etc. </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
<ul>
<li><a href="qset.h#FOREACHelem_">FOREACHelem_</a>
assign 'elem' to each element in a set </li>
<li><a href="qset.h#FOREACHset_">FOREACHset_</a>
assign 'set' to each set in a set of sets </li>
<li><a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
define a FOREACH iterator </li>
<li><a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
define an indexed FOREACH iterator </li>
<li><a href="qset.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
define a reversed FOREACH iterator </li>
<li><a href="qset.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
define a FOREACH iterator with e[1] and e[0]
reversed </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saccess">Access and
size macros</a></h3>
<ul>
<li><a href="qset.h#SETelem_">SETelem_</a> return the
n'th element of set </li>
<li><a href="qset.h#SETelemt_">SETelemt_</a> return
the n'th element of set as a type</li>
<li><a href="qset.h#SETempty_">SETempty_</a> return
true (1) if set is empty </li>
<li><a href="qset.h#SETfirst_">SETfirst_</a> return
first element of set </li>
<li><a href="qset.h#SETfirstt_">SETfirstt_</a> return
first element of set as a type</li>
<li><a href="qset.h#SETindex_">SETindex_</a> return
index of elem in set </li>
<li><a href="qset.h#SETreturnsize_">SETreturnsize_</a>
return size of a set (normally use <a href="qset.c#setsize">qh_setsize</a>) </li>
<li><a href="qset.h#SETsecond_">SETsecond_</a> return
second element of set </li>
<li><a href="qset.h#SETsecondt_">SETsecondt_</a>
return second element of set as a type</li>
<li><a href="qset.h#SETtruncate_">SETtruncate_</a>
truncate set to size, i.e., qh_settruncate()</li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
<ul>
<li><a href="qset.c#SETsizeaddr_">SETsizeaddr_</a>
return pointer to end element of a set (indicates
current size) </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
<ul>
<li><a href="qset.h#SETaddr_">SETaddr_</a> return
address of a set's elements </li>
<li><a href="qset.h#SETelemaddr_">SETelemaddr_</a>
return address of the n'th element of a set </li>
<li><a href="qset.h#SETref_">SETref_</a> l.h.s. for
modifying the current element in a FOREACH
iteration </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="snew">Allocation and
deallocation functions</a></h3>
<ul>
<li><a href="qset.c#setfree">qh_setfree</a> free the
space occupied by a set </li>
<li><a href="qset.c#setfree2">qh_setfree2</a> free a
set and its elements </li>
<li><a href="qset.c#setfreelong">qh_setfreelong</a>
free a set only if it is in long memory </li>
<li><a href="qset.c#setnew">qh_setnew</a> create a new
set </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="spred">Access and
predicate functions </a></h3>
<ul>
<li><a href="qset.c#setendpointer">qh_setendpointer</a> return
pointer to NULL terminator of a set</li>
<li><a href="qset.c#setequal">qh_setequal</a> return 1
if two sorted sets are equal </li>
<li><a href="qset.c#setequal_except">qh_setequal_except</a>
return 1 if two sorted sets are equal except for
an element </li>
<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
<li><a href="qset.c#setin">qh_setin</a> return 1 if an
element is in a set </li>
<li><a href="qset.c#setindex">qh_setindex</a> return
the index of an element in a set </li>
<li><a href="qset.c#setlast">qh_setlast</a> return
last element of a set</li>
<li><a href="qset.c#setsize">qh_setsize</a> returns
the size of a set </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
<ul>
<li><a href="qset.c#setaddnth">qh_setaddnth</a> add a
element as n'th element of sorted or unsorted set
</li>
<li><a href="qset.c#setaddsorted">qh_setaddsorted</a>
add an element to a sorted set </li>
<li><a href="qset.c#setappend">qh_setappend</a> append
an element to a set </li>
<li><a href="qset.c#setappend_set">qh_setappend_set</a>
append a set of elements to a set </li>
<li><a href="qset.c#setappend2ndlast">qh_setappend2ndlast</a>
add an element as the next to the last element in
a set </li>
<li><a href="qset.c#setlarger">qh_setlarger</a> return
a larger set with the same elements</li>
<li><a href="qset.c#setreplace">qh_setreplace</a>
replace one element with another in a set</li>
<li><a href="qset.c#setunique">qh_setunique</a> add an
element if it is not already in a set </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
<ul>
<li><a href="qset.c#setcheck">qh_setcheck</a> check a
set for validity </li>
<li><a href="qset.c#setprint">qh_setprint</a> print a
set's elements to fp </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
<ul>
<li><a href="qset.c#setcompact">qh_setcompact</a>
compact NULLs from an unsorted set </li>
<li><a href="qset.c#setcopy">qh_setcopy</a> make a
copy of a sorted or unsorted set </li>
<li><a href="qset.c#setduplicate">qh_setduplicate</a>
duplicate a set and its elements </li>
<li><a href="qset.c#settruncate">qh_settruncate</a>
truncate a set to size elements </li>
<li><a href="qset.c#setzero">qh_setzero</a> zero the
remainder of a set </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
<ul>
<li><a href="qset.c#setdel">qh_setdel</a> delete an
element from an unsorted set. </li>
<li><a href="qset.c#setdellast">qh_setdellast</a>
delete and return last element from a set</li>
<li><a href="qset.c#setdelnth">qh_setdelnth</a> delete
and return nth element from an unsorted set </li>
<li><a href="qset.c#setdelnthsorted">qh_setdelnthsorted</a>
delete and return nth element from a sorted set </li>
<li><a href="qset.c#setdelsorted">qh_setdelsorted</a>
delete an element from a sorted set </li>
<li><a href="qset.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
create a sorted set not containing the nth
element </li>
</ul>
<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
<ul>
<li><a href="qset.c#settemp">qh_settemp</a> return a
temporary set and append it qhmem.tempstack</li>
<li><a href="qset.c#settempfree">qh_settempfree</a>
free and pop a set from qhmem.tempstack</li>
<li><a href="qset.c#settempfree_all">qh_settempfree_all</a>
free all sets in qhmem.tempstack </li>
<li><a href="qset.c#settemppop">qh_settemppop</a> pop
a set from qhmem.tempstack (makes it permanent) </li>
<li><a href="qset.c#settemppush">qh_settemppush</a>
push a set unto qhmem.tempstack (makes it
temporary) </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,163 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>stat.c -- statistical operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm">User</a>
</p>
<hr>
<h2>stat.c -- statistical operations</h2>
<blockquote>
<p>Qhull records many statistics. These functions and
macros make it inexpensive to add a statistic.
<p>As with Qhull's global variables, the statistics data structure is
accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro
is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'.
Statistics
may be turned off in user.h. If so, all but the 'zz'
statistics are ignored.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <b>Stat</b> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<h3>Index to <a href="stat.c">stat.c</a> and
<a href="stat.h">stat.h</a></h3>
<ul>
<li><a href="#ttype">stat.h types</a> </li>
<li><a href="#tconst">stat.h constants</a> </li>
<li><a href="#tmacro">stat.h macros</a> </li>
<li><a href="#tfunc">stat.c functions</a> </li>
</ul>
<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="ttype">stat.h types</a></h3>
<ul>
<li><a href="stat.h#intrealT">intrealT</a> union of
integer and real</li>
<li><a href="stat.h#qhstat">qhstat</a> global data
structure for statistics </li>
</ul>
<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tconst">stat.h
constants</a></h3>
<ul>
<li><a href="stat.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
<li><a href="stat.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
</li>
<li><a href="stat.h#ZZstat">ZZstat</a> Z.../W... statistics that
remain defined if qh_KEEPstatistics=0
</li>
<li><a href="stat.h#ztype">ztype</a> zdoc, zinc, etc.
for definining statistics </li>
</ul>
<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tmacro">stat.h macros</a></h3>
<ul>
<li><a href="stat.h#MAYdebugx">MAYdebugx</a> called
frequently for error trapping </li>
<li><a href="stat.h#zadd_">zadd_/wadd_</a> add value
to an integer or real statistic </li>
<li><a href="stat.h#zdef_">zdef_</a> define a
statistic </li>
<li><a href="stat.h#zinc_">zinc_</a> increment an
integer statistic </li>
<li><a href="stat.h#zmax_">zmax_/wmax_</a> update
integer or real maximum statistic </li>
<li><a href="stat.h#zmin_">zmin_/wmin_</a> update
integer or real minimum statistic </li>
<li><a href="stat.h#zval_">zval_/wval_</a> set or
return value of a statistic </li>
</ul>
<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tfunc">stat.c
functions</a></h3>
<ul>
<li><a href="stat.c#allstatA">qh_allstatA</a> define
statistics in groups of 20 </li>
<li><a href="stat.c#allstatistics">qh_allstatistics</a>
reset printed flag for all statistics </li>
<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
collect statistics for qh.facet_list </li>
<li><a href="stat.c#freestatistics">qh_freestatistics</a>
free memory used for statistics </li>
<li><a href="stat.c#initstatistics">qh_initstatistics</a>
allocate and initialize statistics </li>
<li><a href="stat.c#newstats">qh_newstats</a> returns
True if statistics for zdoc </li>
<li><a href="stat.c#nostatistic">qh_nostatistic</a>
true if no statistic to print </li>
<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
print all statistics </li>
<li><a href="stat.c#printstatistics">qh_printstatistics</a>
print statistics to a file </li>
<li><a href="stat.c#printstatlevel">qh_printstatlevel</a>
print level information for a statistic </li>
<li><a href="stat.c#printstats">qh_printstats</a>
print statistics for a zdoc group </li>
<li><a href="stat.c#stddev">qh_stddev</a> compute the
standard deviation and average from statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,271 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>user.c -- user-definable operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
</p>
<hr>
<h2>user.c -- user-definable operations</h2>
<blockquote>
<p>This section contains functions and constants that the
user may want to change. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <b>User</b>
</p>
<h3>Index to <a href="user.c">user.c</a>, <a href="usermem.c">usermem.c</a>, <a href="userprintf.c">userprintf.c</a>, <a href="userprintf_rbox.c">userprintf_rbox.c</a> and
<a href="user.h">user.h</a></h3>
<ul>
<li><a href="#qulllib">qhull library constants</a></li>
<li><a href="#utype">user.h data types and
configuration macros</a> </li>
<li><a href="#ujoggle">joggle constants</a></li>
<li><a href="#uperform">performance related constants</a></li>
<li><a href="#umemory">memory constants</a></li>
<li><a href="#ucond">conditional compilation</a></li>
<li><a href="#umerge">merge constants</a> </li>
<li><a href="#ufunc">user.c functions</a> </li>
<li><a href="#u2func">usermem.c functions</a> </li>
<li><a href="#u3func">userprintf.c functions</a> </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
<ul>
<li><a href="user.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
<li><a href="user.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
<li><a href="user.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="utype">user.h data
types and configuration macros</a></h3>
<ul>
<li><a href="user.h#realT">realT, qh_REAL...</a> size
of floating point numbers </li>
<li><a href="user.h#countT">countT, COUNTmax</a> size
of counts and identifiers, typically 'int' or 'long long' </li>
<li><a href="user.h#CPUclock">qh_CPUclock</a> clock()
function for reporting the total time spent by
Qhull </li>
<li><a href="user.h#RANDOM">qh_RANDOM...</a> random
number generator </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
<ul>
<li><a href="user.h#DEFAULTbox">qh_DEFAULTbox</a>
define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
<li><a href="user.h#INFINITE">qh_INFINITE</a> on
output, indicates Voronoi center at infinity </li>
<li><a href="user.h#ORIENTclock">qh_ORIENTclock</a>
define convention for orienting facets</li>
<li><a href="user.h#ZEROdelaunay">qh_ZEROdelaunay</a>
define facets that are ignored in Delaunay triangulations</li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
<ul>
<li><a href="user.h#JOGGLEagain">qh_JOGGLEagain</a>
how often to retry before using qh_JOGGLEmaxincrease
again </li>
<li><a href="user.h#JOGGLEdefault">qh_JOGGLEdefault</a>
default value for qh.JOGGLEmax for 'QP' </li>
<li><a href="user.h#JOGGLEincrease">qh_JOGGLEincrease</a>
factor to increase qh.JOGGLEmax on retrys for
'QPn' </li>
<li><a href="user.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
for increasing qh.JOGGLEmax relative to
qh.MAXwidth </li>
<li><a href="user.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
report error if this many retries </li>
<li><a href="user.h#JOGGLEretry">qh_JOGGLEretry</a>
how often to retry before using qh_JOGGLEmax </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="uperform">performance
related constants</a></h3>
<ul>
<li><a href="user.h#HASHfactor">qh_HASHfactor</a>
total/used hash slots </li>
<li><a href="user.h#INITIALmax">qh_INITIALmax</a> if
dim &gt;= qh_INITIALmax, use min/max coordinate
points for initial simplex </li>
<li><a href="user.h#INITIALsearch">qh_INITIALsearch</a>
if qh.INITIALmax, search points up to this
dimension </li>
<li><a href="user.h#NOtrace">qh_NOtrace</a> disallow
tracing </li>
<li><a href="user.h#VERIFYdirect">qh_VERIFYdirect</a>
'Tv' verifies all <em>points X facets</em> if op
count is smaller </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
<ul>
<li><a href="user.h#MEMalign">qh_MEMalign</a> memory
alignment for qh_meminitbuffers() in global.c </li>
<li><a href="user.h#MEMbufsize">qh_MEMbufsize</a>
size of additional memory buffers </li>
<li><a href="user.h#MEMinitbuf">qh_MEMinitbuf</a>
size of initial memory buffer </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
<ul>
<li><a href="user.h#compiler">compiler</a> defined symbols,
e.g., _STDC_ and _cplusplus
<li><a href="user.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
compute furthest distance to an outside point instead of storing it with the facet
<li><a href="user.h#KEEPstatistics">qh_KEEPstatistics</a>
enable statistic gathering and reporting with option 'Ts'
<li><a href="user.h#MAXoutside">qh_MAXoutside</a>
record outer plane for each facet
<li><a href="user.h#NOmerge">qh_NOmerge</a>
disable facet merging
<li><a href="user.h#NOtrace">qh_NOtrace</a>
disable tracing with option 'T4'
<li><a href="user.h#QHpointer">qh_QHpointer</a>
access global data with pointer or static structure
<li><a href="user.h#QUICKhelp">qh_QUICKhelp</a>
use abbreviated help messages, e.g., for degenerate inputs
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umerge">merge
constants</a></h3>
<ul>
<li><a href="user.h#BESTcentrum">qh_BESTcentrum</a>
when does qh_findbestneighbor() test centrums? </li>
<li><a href="user.h#BESTnonconvex">qh_BESTnonconvex</a>
when does qh_findbestneighbor() test nonconvex
ridges only? </li>
<li><a href="user.h#COPLANARratio">qh_COPLANARratio</a>
what is qh.MINvisible? </li>
<li><a href="user.h#DIMreduceBuild">qh_DIMreduceBuild</a>
max dimension for vertex reduction </li>
<li><a href="user.h#DIMmergeVertex">qh_DIMmergeVertex</a>
max dimension for vertex merging </li>
<li><a href="user.h#DISToutside">qh_DISToutside</a>
when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
<li><a href="user.h#MAXnarrow">qh_MAXnarrow</a> max.
cosine for qh.NARROWhull </li>
<li><a href="user.h#MAXnewcentrum">qh_MAXnewcentrum</a>
when does qh_reducevertices_centrum() reset the
centrum? </li>
<li><a href="user.h#MAXnewmerges">qh_MAXnewmerges</a>
when does qh_merge_nonconvex() call
qh_reducevertices_centrums? </li>
<li><a href="user.h#RATIOnearinside">qh_RATIOnearinside</a>
ratio for retaining inside points for
qh_check_maxout() </li>
<li><a href="user.h#SEARCHdist">qh_SEARCHdist</a>
when is facet coplanar with the best facet for qh_findbesthorizon</li>
<li><a href="user.h#USEfindbestnew">qh_USEfindbestnew</a>
when to use qh_findbestnew for qh_partitionpoint()</li>
<li><a href="user.h#WARNnarrow">qh_WARNnarrow</a>
max. cosine to warn about qh.NARROWhull </li>
<li><a href="user.h#WIDEcoplanar">qh_WIDEcoplanar</a>
what is a wide facet? </li>
<li><a href="user.h#WIDEduplicate">qh_WIDEduplicate</a>
what is a wide ratio on merging duplicate ridges? </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ufunc">user.c
functions</a></h3>
<ul>
<li><a href="user.c#qhull_template">Qhull template</a> for calling qh_new_qhull from your program</li>
<li><a href="user.c#errexit">qh_errexit</a> report
error and exit qhull()</li>
<li><a href="user.c#errprint">qh_errprint</a> print
information about facets and ridges </li>
<li><a href="user.c#new_qhull">qh_new_qhull</a> call qhull on an array
of points</li>
<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
print all fields of all facets </li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u2func">usermem.c
functions</a></h3>
<ul>
<li><a href="usermem.c#qh_exit">qh_exit</a> exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp</li>
<li><a href="usermem.c#qh_fprintf_stderr">qh_fprintf_stderr</a> print to stderr when qh.ferr is not defined.</li>
<li><a href="usermem.c#qh_free">qh_free</a> free memory, same as free().</li>
<li><a href="usermem.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
</ul>
<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u3func">userprintf.c
and userprintf_rbox,c functions</a></h3>
<ul>
<li><a href="userprintf.c#qh_fprintf">qh_fprintf</a> print
information from Qhull, sames as fprintf(). </li>
<li><a href="userprintf_rbox.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
information from Rbox, sames as fprintf(). </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
&#149; <a href="qh-user.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,417 @@
; qhull-exports.def -- msvc module-definition file
;
; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
; [mar'11] 399 symbols
; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse
; Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat
; Same as ../libqhullp/qhull_p-exports.def without qh_save_qhull and qh_restore_qhull
;
; $Id: //main/2015/qhull/src/libqhull/qhull-exports.def#3 $$Change: 2047 $
; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
;
; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
VERSION 7.0
EXPORTS
qh_addhash
qh_addpoint
qh_all_merges
qh_allstatA
qh_allstatB
qh_allstatC
qh_allstatD
qh_allstatE
qh_allstatE2
qh_allstatF
qh_allstatG
qh_allstatH
qh_allstatI
qh_allstatistics
qh_appendfacet
qh_appendmergeset
qh_appendprint
qh_appendvertex
qh_argv_to_command
qh_argv_to_command_size
qh_attachnewfacets
qh_backnormal
qh_basevertices
qh_build_withrestart
qh_buildhull
qh_buildtracing
qh_check_bestdist
qh_check_dupridge
qh_check_maxout
qh_check_output
qh_check_point
qh_check_points
qh_checkconnect
qh_checkconvex
qh_checkfacet
qh_checkflags
qh_checkflipped
qh_checkflipped_all
qh_checkpolygon
qh_checkvertex
qh_checkzero
qh_clear_outputflags
qh_clearcenters
qh_clock
qh_collectstatistics
qh_compare_facetarea
qh_compare_facetmerge
qh_compare_facetvisit
qh_compare_vertexpoint
qh_compareangle
qh_comparemerge
qh_comparevisit
qh_copyfilename
qh_copynonconvex
qh_copypoints
qh_countfacets
qh_createsimplex
qh_crossproduct
qh_degen_redundant_facet
qh_degen_redundant_neighbors
qh_deletevisible
qh_delfacet
qh_delridge
qh_delvertex
qh_determinant
qh_detjoggle
qh_detroundoff
qh_detsimplex
qh_detvnorm
qh_detvridge
qh_detvridge3
qh_dfacet
qh_distnorm
qh_distplane
qh_distround
qh_divzero
qh_dvertex
qh_eachvoronoi
qh_eachvoronoi_all
qh_errexit
qh_errexit2
qh_errexit_rbox
qh_errprint
qh_exit
qh_facet2point
qh_facet3vertex
qh_facetarea
qh_facetarea_simplex
qh_facetcenter
qh_facetintersect
qh_facetvertices
qh_find_newvertex
qh_findbest
qh_findbest_test
qh_findbestfacet
qh_findbesthorizon
qh_findbestlower
qh_findbestneighbor
qh_findbestnew
qh_findfacet_all
qh_findgood
qh_findgood_all
qh_findgooddist
qh_findhorizon
qh_flippedmerges
qh_forcedmerges
qh_fprintf
qh_fprintf_rbox
qh_fprintf_stderr
qh_free
qh_freebuffers
qh_freebuild
qh_freeqhull
qh_freeqhull2
qh_freestatistics
qh_furthestnext
qh_furthestout
qh_gausselim
qh_geomplanes
qh_getangle
qh_getarea
qh_getcenter
qh_getcentrum
qh_getdistance
qh_gethash
qh_getmergeset
qh_getmergeset_initial
qh_gram_schmidt
qh_hashridge
qh_hashridge_find
qh_infiniteloop
qh_init_A
qh_init_B
qh_init_qhull_command
qh_initbuild
qh_initflags
qh_initialhull
qh_initialvertices
qh_initqhull_buffers
qh_initqhull_globals
qh_initqhull_mem
qh_initqhull_outputflags
qh_initqhull_start
qh_initqhull_start2
qh_initstatistics
qh_initthresholds
qh_inthresholds
qh_isvertex
qh_joggleinput
; Mark as DATA, otherwise links a separate qh_last_random. No __declspec.
qh_last_random DATA
qh_lib_check
qh_makenew_nonsimplicial
qh_makenew_simplicial
qh_makenewfacet
qh_makenewfacets
qh_makenewplanes
qh_makeridges
qh_malloc
qh_mark_dupridges
qh_markkeep
qh_markvoronoi
qh_matchduplicates
qh_matchneighbor
qh_matchnewfacets
qh_matchvertices
qh_maxabsval
qh_maxmin
qh_maxouter
qh_maxsimplex
qh_maydropneighbor
qh_memalloc
qh_memfree
qh_memfreeshort
qh_meminit
qh_meminitbuffers
qh_memsetup
qh_memsize
qh_memstatistics
qh_memtotal
qh_merge_degenredundant
qh_merge_nonconvex
qh_mergecycle
qh_mergecycle_all
qh_mergecycle_facets
qh_mergecycle_neighbors
qh_mergecycle_ridges
qh_mergecycle_vneighbors
qh_mergefacet
qh_mergefacet2d
qh_mergeneighbors
qh_mergeridges
qh_mergesimplex
qh_mergevertex_del
qh_mergevertex_neighbors
qh_mergevertices
qh_minabsval
qh_mindiff
qh_nearcoplanar
qh_nearvertex
qh_neighbor_intersections
qh_new_qhull
qh_newfacet
qh_newhashtable
qh_newridge
qh_newstats
qh_newvertex
qh_newvertices
qh_nextfurthest
qh_nextridge3d
qh_normalize
qh_normalize2
qh_nostatistic
qh_option
qh_order_vertexneighbors
qh_orientoutside
qh_out1
qh_out2n
qh_out3n
qh_outcoplanar
qh_outerinner
qh_partitionall
qh_partitioncoplanar
qh_partitionpoint
qh_partitionvisible
qh_point
qh_point_add
qh_pointdist
qh_pointfacet
qh_pointid
qh_pointvertex
qh_postmerge
qh_precision
qh_premerge
qh_prepare_output
qh_prependfacet
qh_printafacet
qh_printallstatistics
qh_printbegin
qh_printcenter
qh_printcentrum
qh_printend
qh_printend4geom
qh_printextremes
qh_printextremes_2d
qh_printextremes_d
qh_printfacet
qh_printfacet2geom
qh_printfacet2geom_points
qh_printfacet2math
qh_printfacet3geom_nonsimplicial
qh_printfacet3geom_points
qh_printfacet3geom_simplicial
qh_printfacet3math
qh_printfacet3vertex
qh_printfacet4geom_nonsimplicial
qh_printfacet4geom_simplicial
qh_printfacetNvertex_nonsimplicial
qh_printfacetNvertex_simplicial
qh_printfacetheader
qh_printfacetlist
qh_printfacetridges
qh_printfacets
qh_printhashtable
qh_printhelp_degenerate
qh_printhelp_narrowhull
qh_printhelp_singular
qh_printhyperplaneintersection
qh_printline3geom
qh_printlists
qh_printmatrix
qh_printneighborhood
qh_printpoint
qh_printpoint3
qh_printpointid
qh_printpoints
qh_printpoints_out
qh_printpointvect
qh_printpointvect2
qh_printridge
qh_printspheres
qh_printstatistics
qh_printstatlevel
qh_printstats
qh_printsummary
qh_printvdiagram
qh_printvdiagram2
qh_printvertex
qh_printvertexlist
qh_printvertices
qh_printvneighbors
qh_printvnorm
qh_printvoronoi
qh_printvridge
qh_produce_output
qh_produce_output2
qh_projectdim3
qh_projectinput
qh_projectpoint
qh_projectpoints
; Mark as DATA, otherwise links a separate qh_qh. qh_qh and qh_qhstat requires __declspec
qh_qh DATA
qh_qhstat DATA
qh_qhull
qh_rand
qh_randomfactor
qh_randommatrix
qh_rboxpoints
qh_readfeasible
qh_readpoints
qh_reducevertices
qh_redundant_vertex
qh_remove_extravertices
qh_removefacet
qh_removevertex
qh_rename_sharedvertex
qh_renameridgevertex
qh_renamevertex
qh_resetlists
qh_rotateinput
qh_rotatepoints
qh_roundi
qh_scaleinput
qh_scalelast
qh_scalepoints
qh_setaddnth
qh_setaddsorted
qh_setappend
qh_setappend2ndlast
qh_setappend_set
qh_setcheck
qh_setcompact
qh_setcopy
qh_setdel
qh_setdelaunay
qh_setdellast
qh_setdelnth
qh_setdelnthsorted
qh_setdelsorted
qh_setduplicate
qh_setequal
qh_setequal_except
qh_setequal_skip
qh_setfacetplane
qh_setfeasible
qh_setfree
qh_setfree2
qh_setfreelong
qh_sethalfspace
qh_sethalfspace_all
qh_sethyperplane_det
qh_sethyperplane_gauss
qh_setin
qh_setindex
qh_setlarger
qh_setlast
qh_setnew
qh_setnew_delnthsorted
qh_setprint
qh_setreplace
qh_setsize
qh_settemp
qh_settempfree
qh_settempfree_all
qh_settemppop
qh_settemppush
qh_settruncate
qh_setunique
qh_setvoronoi_all
qh_setzero
qh_sharpnewfacets
qh_skipfacet
qh_skipfilename
qh_srand
qh_stddev
qh_strtod
qh_strtol
qh_test_appendmerge
qh_test_vneighbors
qh_tracemerge
qh_tracemerging
qh_triangulate
qh_triangulate_facet
qh_triangulate_link
qh_triangulate_mirror
qh_triangulate_null
qh_updatetested
qh_updatevertices
qh_user_memsizes
qh_version
qh_version2
qh_vertexintersect
qh_vertexintersect_new
qh_vertexneighbors
qh_vertexridges
qh_vertexridges_facet
qh_vertexsubset
qh_voronoi_center
qh_willdelete
; Mark as DATA, otherwise links a separate qhmem. No __declspec
qhmem DATA
rbox DATA
rbox_inuse DATA

View File

@@ -0,0 +1,150 @@
/*<html><pre> -<a href="qh-qhull.htm"
>-------------------------------</a><a name="TOP">-</a>
qhull_a.h
all header files for compiling qhull with non-reentrant code
included before C++ headers for user_r.h:QHULL_CRTDBG
see qh-qhull.htm
see libqhull.h for user-level definitions
see user.h for user-definable constants
defines internal functions for libqhull.c global.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/qhull_a.h#4 $$Change: 2064 $
$DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
Notes: grep for ((" and (" to catch fprintf("lkasdjf");
full parens around (x?y:z)
use '#include "libqhull/qhull_a.h"' to avoid name clashes
*/
#ifndef qhDEFqhulla
#define qhDEFqhulla 1
#include "libqhull.h" /* Includes user_r.h and data types */
#include "stat.h"
#include "random.h"
#include "mem.h"
#include "qset.h"
#include "geom.h"
#include "merge.h"
#include "poly.h"
#include "io.h"
#include <setjmp.h>
#include <string.h>
#include <math.h>
#include <float.h> /* some compilers will not need float.h */
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/*** uncomment here and qset.c
if string.h does not define memcpy()
#include <memory.h>
*/
#if qh_CLOCKtype == 2 /* defined in user.h from libqhull.h */
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#endif
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4100) /* unreferenced formal parameter */
#pragma warning( disable : 4127) /* conditional expression is constant */
#pragma warning( disable : 4706) /* assignment within conditional function */
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
#endif
/* ======= -macros- =========== */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="traceN">-</a>
traceN((qh ferr, 0Nnnn, "format\n", vars));
calls qh_fprintf if qh.IStracing >= N
Add debugging traps to the end of qh_fprintf
notes:
removing tracing reduces code size but doesn't change execution speed
*/
#ifndef qh_NOtrace
#define trace0(args) {if (qh IStracing) qh_fprintf args;}
#define trace1(args) {if (qh IStracing >= 1) qh_fprintf args;}
#define trace2(args) {if (qh IStracing >= 2) qh_fprintf args;}
#define trace3(args) {if (qh IStracing >= 3) qh_fprintf args;}
#define trace4(args) {if (qh IStracing >= 4) qh_fprintf args;}
#define trace5(args) {if (qh IStracing >= 5) qh_fprintf args;}
#else /* qh_NOtrace */
#define trace0(args) {}
#define trace1(args) {}
#define trace2(args) {}
#define trace3(args) {}
#define trace4(args) {}
#define trace5(args) {}
#endif /* qh_NOtrace */
/*-<a href="qh-qhull.htm#TOC"
>--------------------------------</a><a name="QHULL_UNUSED">-</a>
Define an unused variable to avoid compiler warnings
Derived from Qt's corelib/global/qglobal.h
*/
#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
template <typename T>
inline void qhullUnused(T &x) { (void)x; }
# define QHULL_UNUSED(x) qhullUnused(x);
#else
# define QHULL_UNUSED(x) (void)x;
#endif
/***** -libqhull.c prototypes (alphabetical after qhull) ********************/
void qh_qhull(void);
boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist);
void qh_buildhull(void);
void qh_buildtracing(pointT *furthest, facetT *facet);
void qh_build_withrestart(void);
void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
pointT *qh_nextfurthest(facetT **visible);
void qh_partitionall(setT *vertices, pointT *points,int npoints);
void qh_partitioncoplanar(pointT *point, facetT *facet, realT *dist);
void qh_partitionpoint(pointT *point, facetT *facet);
void qh_partitionvisible(boolT allpoints, int *numpoints);
void qh_precision(const char *reason);
void qh_printsummary(FILE *fp);
/***** -global.c internal prototypes (alphabetical) ***********************/
void qh_appendprint(qh_PRINT format);
void qh_freebuild(boolT allmem);
void qh_freebuffers(void);
void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc);
/***** -stat.c internal prototypes (alphabetical) ***********************/
void qh_allstatA(void);
void qh_allstatB(void);
void qh_allstatC(void);
void qh_allstatD(void);
void qh_allstatE(void);
void qh_allstatE2(void);
void qh_allstatF(void);
void qh_allstatG(void);
void qh_allstatH(void);
void qh_freebuffers(void);
void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc);
#endif /* qhDEFqhulla */

View File

@@ -0,0 +1,418 @@
; qhull_p-exports.def -- msvc module-definition file
;
; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
; [mar'11] 399 symbols [jan'15] added 3 symbols
; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse
; Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat
;
; $Id: //main/2011/qhull/src/libqhull/qhull-exports.def#2 $$Change: 1368 $
; $DateTime: 2011/04/16 08:12:32 $$Author: bbarber $
;
; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
VERSION 7.0
EXPORTS
qh_addhash
qh_addpoint
qh_all_merges
qh_allstatA
qh_allstatB
qh_allstatC
qh_allstatD
qh_allstatE
qh_allstatE2
qh_allstatF
qh_allstatG
qh_allstatH
qh_allstatI
qh_allstatistics
qh_appendfacet
qh_appendmergeset
qh_appendprint
qh_appendvertex
qh_argv_to_command
qh_argv_to_command_size
qh_attachnewfacets
qh_backnormal
qh_basevertices
qh_build_withrestart
qh_buildhull
qh_buildtracing
qh_check_bestdist
qh_check_dupridge
qh_check_maxout
qh_check_output
qh_check_point
qh_check_points
qh_checkconnect
qh_checkconvex
qh_checkfacet
qh_checkflags
qh_checkflipped
qh_checkflipped_all
qh_checkpolygon
qh_checkvertex
qh_checkzero
qh_clear_outputflags
qh_clearcenters
qh_clock
qh_collectstatistics
qh_compare_facetarea
qh_compare_facetmerge
qh_compare_facetvisit
qh_compare_vertexpoint
qh_compareangle
qh_comparemerge
qh_comparevisit
qh_copyfilename
qh_copynonconvex
qh_copypoints
qh_countfacets
qh_createsimplex
qh_crossproduct
qh_degen_redundant_facet
qh_degen_redundant_neighbors
qh_deletevisible
qh_delfacet
qh_delridge
qh_delvertex
qh_determinant
qh_detjoggle
qh_detroundoff
qh_detsimplex
qh_detvnorm
qh_detvridge
qh_detvridge3
qh_dfacet
qh_distnorm
qh_distplane
qh_distround
qh_divzero
qh_dvertex
qh_eachvoronoi
qh_eachvoronoi_all
qh_errexit
qh_errexit2
qh_errexit_rbox
qh_errprint
qh_exit
qh_facet2point
qh_facet3vertex
qh_facetarea
qh_facetarea_simplex
qh_facetcenter
qh_facetintersect
qh_facetvertices
qh_find_newvertex
qh_findbest
qh_findbest_test
qh_findbestfacet
qh_findbesthorizon
qh_findbestlower
qh_findbestneighbor
qh_findbestnew
qh_findfacet_all
qh_findgood
qh_findgood_all
qh_findgooddist
qh_findhorizon
qh_flippedmerges
qh_forcedmerges
qh_fprintf
qh_fprintf_rbox
qh_fprintf_stderr
qh_free
qh_freebuffers
qh_freebuild
qh_freeqhull
qh_freeqhull2
qh_freestatistics
qh_furthestnext
qh_furthestout
qh_gausselim
qh_geomplanes
qh_getangle
qh_getarea
qh_getcenter
qh_getcentrum
qh_getdistance
qh_gethash
qh_getmergeset
qh_getmergeset_initial
qh_gram_schmidt
qh_hashridge
qh_hashridge_find
qh_infiniteloop
qh_init_A
qh_init_B
qh_init_qhull_command
qh_initbuild
qh_initflags
qh_initialhull
qh_initialvertices
qh_initqhull_buffers
qh_initqhull_globals
qh_initqhull_mem
qh_initqhull_outputflags
qh_initqhull_start
qh_initqhull_start2
qh_initstatistics
qh_initthresholds
qh_inthresholds
qh_isvertex
qh_joggleinput
; Mark as DATA, otherwise links a separate qh_last_random. No __declspec.
qh_last_random DATA
qh_lib_check
qh_makenew_nonsimplicial
qh_makenew_simplicial
qh_makenewfacet
qh_makenewfacets
qh_makenewplanes
qh_makeridges
qh_malloc
qh_mark_dupridges
qh_markkeep
qh_markvoronoi
qh_matchduplicates
qh_matchneighbor
qh_matchnewfacets
qh_matchvertices
qh_maxabsval
qh_maxmin
qh_maxouter
qh_maxsimplex
qh_maydropneighbor
qh_memalloc
qh_memfree
qh_memfreeshort
qh_meminit
qh_meminitbuffers
qh_memsetup
qh_memsize
qh_memstatistics
qh_memtotal
qh_merge_degenredundant
qh_merge_nonconvex
qh_mergecycle
qh_mergecycle_all
qh_mergecycle_facets
qh_mergecycle_neighbors
qh_mergecycle_ridges
qh_mergecycle_vneighbors
qh_mergefacet
qh_mergefacet2d
qh_mergeneighbors
qh_mergeridges
qh_mergesimplex
qh_mergevertex_del
qh_mergevertex_neighbors
qh_mergevertices
qh_minabsval
qh_mindiff
qh_nearcoplanar
qh_nearvertex
qh_neighbor_intersections
qh_new_qhull
qh_newfacet
qh_newhashtable
qh_newridge
qh_newstats
qh_newvertex
qh_newvertices
qh_nextfurthest
qh_nextridge3d
qh_normalize
qh_normalize2
qh_nostatistic
qh_option
qh_order_vertexneighbors
qh_orientoutside
qh_out1
qh_out2n
qh_out3n
qh_outcoplanar
qh_outerinner
qh_partitionall
qh_partitioncoplanar
qh_partitionpoint
qh_partitionvisible
qh_point
qh_point_add
qh_pointdist
qh_pointfacet
qh_pointid
qh_pointvertex
qh_postmerge
qh_precision
qh_premerge
qh_prepare_output
qh_prependfacet
qh_printafacet
qh_printallstatistics
qh_printbegin
qh_printcenter
qh_printcentrum
qh_printend
qh_printend4geom
qh_printextremes
qh_printextremes_2d
qh_printextremes_d
qh_printfacet
qh_printfacet2geom
qh_printfacet2geom_points
qh_printfacet2math
qh_printfacet3geom_nonsimplicial
qh_printfacet3geom_points
qh_printfacet3geom_simplicial
qh_printfacet3math
qh_printfacet3vertex
qh_printfacet4geom_nonsimplicial
qh_printfacet4geom_simplicial
qh_printfacetNvertex_nonsimplicial
qh_printfacetNvertex_simplicial
qh_printfacetheader
qh_printfacetlist
qh_printfacetridges
qh_printfacets
qh_printhashtable
qh_printhelp_degenerate
qh_printhelp_narrowhull
qh_printhelp_singular
qh_printhyperplaneintersection
qh_printline3geom
qh_printlists
qh_printmatrix
qh_printneighborhood
qh_printpoint
qh_printpoint3
qh_printpointid
qh_printpoints
qh_printpoints_out
qh_printpointvect
qh_printpointvect2
qh_printridge
qh_printspheres
qh_printstatistics
qh_printstatlevel
qh_printstats
qh_printsummary
qh_printvdiagram
qh_printvdiagram2
qh_printvertex
qh_printvertexlist
qh_printvertices
qh_printvneighbors
qh_printvnorm
qh_printvoronoi
qh_printvridge
qh_produce_output
qh_produce_output2
qh_projectdim3
qh_projectinput
qh_projectpoint
qh_projectpoints
; Mark as DATA, otherwise links a separate qh_qh. qh_qh and qh_qhstat requires __declspec
qh_qh DATA
qh_qhstat DATA
qh_qhull
qh_rand
qh_randomfactor
qh_randommatrix
qh_rboxpoints
qh_readfeasible
qh_readpoints
qh_reducevertices
qh_redundant_vertex
qh_remove_extravertices
qh_removefacet
qh_removevertex
qh_rename_sharedvertex
qh_renameridgevertex
qh_renamevertex
qh_resetlists
qh_restore_qhull
qh_rotateinput
qh_rotatepoints
qh_roundi
qh_save_qhull
qh_scaleinput
qh_scalelast
qh_scalepoints
qh_setaddnth
qh_setaddsorted
qh_setappend
qh_setappend2ndlast
qh_setappend_set
qh_setcheck
qh_setcompact
qh_setcopy
qh_setdel
qh_setdelaunay
qh_setdellast
qh_setdelnth
qh_setdelnthsorted
qh_setdelsorted
qh_setduplicate
qh_setequal
qh_setequal_except
qh_setequal_skip
qh_setfacetplane
qh_setfeasible
qh_setfree
qh_setfree2
qh_setfreelong
qh_sethalfspace
qh_sethalfspace_all
qh_sethyperplane_det
qh_sethyperplane_gauss
qh_setin
qh_setindex
qh_setlarger
qh_setlast
qh_setnew
qh_setnew_delnthsorted
qh_setprint
qh_setreplace
qh_setsize
qh_settemp
qh_settempfree
qh_settempfree_all
qh_settemppop
qh_settemppush
qh_settruncate
qh_setunique
qh_setvoronoi_all
qh_setzero
qh_sharpnewfacets
qh_skipfacet
qh_skipfilename
qh_srand
qh_stddev
qh_strtod
qh_strtol
qh_test_appendmerge
qh_test_vneighbors
qh_tracemerge
qh_tracemerging
qh_triangulate
qh_triangulate_facet
qh_triangulate_link
qh_triangulate_mirror
qh_triangulate_null
qh_updatetested
qh_updatevertices
qh_user_memsizes
qh_version
qh_version2
qh_vertexintersect
qh_vertexintersect_new
qh_vertexneighbors
qh_vertexridges
qh_vertexridges_facet
qh_vertexsubset
qh_voronoi_center
qh_willdelete
; Mark as DATA, otherwise links a separate qhmem. No __declspec
qhmem DATA
rbox DATA
rbox_inuse DATA

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,490 @@
/*<html><pre> -<a href="qh-set.htm"
>-------------------------------</a><a name="TOP">-</a>
qset.h
header file for qset.c that implements set
see qh-set.htm and qset.c
only uses mem.c, malloc/free
for error handling, writes message and calls
qh_errexit(qhmem_ERRqhull, NULL, NULL);
set operations satisfy the following properties:
- sets have a max size, the actual size (if different) is stored at the end
- every set is NULL terminated
- sets may be sorted or unsorted, the caller must distinguish this
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/qset.h#2 $$Change: 2062 $
$DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
*/
#ifndef qhDEFset
#define qhDEFset 1
#include <stdio.h>
/*================= -structures- ===============*/
#ifndef DEFsetT
#define DEFsetT 1
typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
#endif
/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
/*-<a href="qh-set.htm#TOC"
>----------------------------------------</a><a name="setT">-</a>
setT
a set or list of pointers with maximum size and actual size.
variations:
unsorted, unique -- a list of unique pointers with NULL terminator
user guarantees uniqueness
sorted -- a sorted list of unique pointers with NULL terminator
qset.c guarantees uniqueness
unsorted -- a list of pointers terminated with NULL
indexed -- an array of pointers with NULL elements
structure for set of n elements:
--------------
| maxsize
--------------
| e[0] - a pointer, may be NULL for indexed sets
--------------
| e[1]
--------------
| ...
--------------
| e[n-1]
--------------
| e[n] = NULL
--------------
| ...
--------------
| e[maxsize] - n+1 or NULL (determines actual size of set)
--------------
*/
/*-- setelemT -- internal type to allow both pointers and indices
*/
typedef union setelemT setelemT;
union setelemT {
void *p;
int i; /* integer used for e[maxSize] */
};
struct setT {
int maxsize; /* maximum number of elements (except NULL) */
setelemT e[1]; /* array of pointers, tail is NULL */
/* last slot (unless NULL) is actual size+1
e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
/* this may generate a warning since e[] contains
maxsize elements */
};
/*=========== -constants- =========================*/
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="SETelemsize">-</a>
SETelemsize
size of a set element in bytes
*/
#define SETelemsize ((int)sizeof(setelemT))
/*=========== -macros- =========================*/
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelement_">-</a>
FOREACHsetelement_(type, set, variable)
define FOREACH iterator
declare:
assumes *variable and **variablep are declared
no space in "variable)" [DEC Alpha cc compiler]
each iteration:
variable is set element
variablep is one beyond variable.
to repeat an element:
variablep--; / *repeat* /
at exit:
variable is NULL at end of loop
example:
#define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
notes:
use FOREACHsetelement_i_() if need index or include NULLs
WARNING:
nested loops can't use the same variable (define another FOREACH)
needs braces if nested inside another FOREACH
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
*/
#define FOREACHsetelement_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##p= (type **)&((set)->e[0].p); \
(variable= *variable##p++);)
/*-<a href="qh-set.htm#TOC"
>----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
FOREACHsetelement_i_(type, set, variable)
define indexed FOREACH iterator
declare:
type *variable, variable_n, variable_i;
each iteration:
variable is set element, may be NULL
variable_i is index, variable_n is qh_setsize()
to repeat an element:
variable_i--; variable_n-- repeats for deleted element
at exit:
variable==NULL and variable_i==variable_n
example:
#define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
WARNING:
nested loops can't use the same variable (define another FOREACH)
needs braces if nested inside another FOREACH
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
*/
#define FOREACHsetelement_i_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##_i= 0, variable= (type *)((set)->e[0].p), \
variable##_n= qh_setsize(set);\
variable##_i < variable##_n;\
variable= (type *)((set)->e[++variable##_i].p) )
/*-<a href="qh-set.htm#TOC"
>--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
FOREACHsetelementreverse_(type, set, variable)-
define FOREACH iterator in reverse order
declare:
assumes *variable and **variablep are declared
also declare 'int variabletemp'
each iteration:
variable is set element
to repeat an element:
variabletemp++; / *repeat* /
at exit:
variable is NULL
example:
#define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
notes:
use FOREACHsetelementreverse12_() to reverse first two elements
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHsetelementreverse_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
variable; variable= \
((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
FOREACHsetelementreverse12_(type, set, variable)-
define FOREACH iterator with e[1] and e[0] reversed
declare:
assumes *variable and **variablep are declared
each iteration:
variable is set element
variablep is one after variable.
to repeat an element:
variablep--; / *repeat* /
at exit:
variable is NULL at end of loop
example
#define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHsetelementreverse12_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##p= (type **)&((set)->e[1].p); \
(variable= *variable##p); \
variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
(variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHelem_">-</a>
FOREACHelem_( set )-
iterate elements in a set
declare:
void *elem, *elemp;
each iteration:
elem is set element
elemp is one beyond
to repeat an element:
elemp--; / *repeat* /
at exit:
elem == NULL at end of loop
example:
FOREACHelem_(set) {
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
/*-<a href="qh-set.htm#TOC"
>-----------------------------------</a><a name="FOREACHset_">-</a>
FOREACHset_( set )-
iterate a set of sets
declare:
setT *set, **setp;
each iteration:
set is set element
setp is one beyond
to repeat an element:
setp--; / *repeat* /
at exit:
set == NULL at end of loop
example
FOREACHset_(sets) {
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
/*-<a href="qh-set.htm#TOC"
>-----------------------------------------</a><a name="SETindex_">-</a>
SETindex_( set, elem )
return index of elem in set
notes:
for use with FOREACH iteration
WARN64 -- Maximum set size is 2G
example:
i= SETindex_(ridges, ridge)
*/
#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETref_">-</a>
SETref_( elem )
l.h.s. for modifying the current element in a FOREACH iteration
example:
SETref_(ridge)= anotherridge;
*/
#define SETref_(elem) (elem##p[-1])
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelem_">-</a>
SETelem_(set, n)
return the n'th element of set
notes:
assumes that n is valid [0..size] and that set is defined
use SETelemt_() for type cast
*/
#define SETelem_(set, n) ((set)->e[n].p)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelemt_">-</a>
SETelemt_(set, n, type)
return the n'th element of set as a type
notes:
assumes that n is valid [0..size] and that set is defined
*/
#define SETelemt_(set, n, type) ((type*)((set)->e[n].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETelemaddr_">-</a>
SETelemaddr_(set, n, type)
return address of the n'th element of a set
notes:
assumes that n is valid [0..size] and set is defined
*/
#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETfirst_">-</a>
SETfirst_(set)
return first element of set
*/
#define SETfirst_(set) ((set)->e[0].p)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETfirstt_">-</a>
SETfirstt_(set, type)
return first element of set as a type
*/
#define SETfirstt_(set, type) ((type*)((set)->e[0].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETsecond_">-</a>
SETsecond_(set)
return second element of set
*/
#define SETsecond_(set) ((set)->e[1].p)
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETsecondt_">-</a>
SETsecondt_(set, type)
return second element of set as a type
*/
#define SETsecondt_(set, type) ((type*)((set)->e[1].p))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETaddr_">-</a>
SETaddr_(set, type)
return address of set's elements
*/
#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETreturnsize_">-</a>
SETreturnsize_(set, size)
return size of a set
notes:
set must be defined
use qh_setsize(set) unless speed is critical
*/
#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETempty_">-</a>
SETempty_(set)
return true(1) if set is empty
notes:
set may be NULL
*/
#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
/*-<a href="qh-set.htm#TOC"
>-------------------------------<a name="SETsizeaddr_">-</a>
SETsizeaddr_(set)
return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
Its type is setelemT* for strict aliasing
All SETelemaddr_ must be cast to setelemT
notes:
*SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
*/
#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
/*-<a href="qh-set.htm#TOC"
>---------------------------------------</a><a name="SETtruncate_">-</a>
SETtruncate_(set, size)
truncate set to size
see:
qh_settruncate()
*/
#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
set->e[size].p= NULL;}
/*======= prototypes in alphabetical order ============*/
void qh_setaddsorted(setT **setp, void *elem);
void qh_setaddnth(setT **setp, int nth, void *newelem);
void qh_setappend(setT **setp, void *elem);
void qh_setappend_set(setT **setp, setT *setA);
void qh_setappend2ndlast(setT **setp, void *elem);
void qh_setcheck(setT *set, const char *tname, unsigned id);
void qh_setcompact(setT *set);
setT *qh_setcopy(setT *set, int extra);
void *qh_setdel(setT *set, void *elem);
void *qh_setdellast(setT *set);
void *qh_setdelnth(setT *set, int nth);
void *qh_setdelnthsorted(setT *set, int nth);
void *qh_setdelsorted(setT *set, void *newelem);
setT *qh_setduplicate( setT *set, int elemsize);
void **qh_setendpointer(setT *set);
int qh_setequal(setT *setA, setT *setB);
int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
void qh_setfree(setT **set);
void qh_setfree2( setT **setp, int elemsize);
void qh_setfreelong(setT **set);
int qh_setin(setT *set, void *setelem);
int qh_setindex(setT *set, void *setelem);
void qh_setlarger(setT **setp);
void *qh_setlast(setT *set);
setT *qh_setnew(int size);
setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
void qh_setprint(FILE *fp, const char* string, setT *set);
void qh_setreplace(setT *set, void *oldelem, void *newelem);
int qh_setsize(setT *set);
setT *qh_settemp(int setsize);
void qh_settempfree(setT **set);
void qh_settempfree_all(void);
setT *qh_settemppop(void);
void qh_settemppush(setT *set);
void qh_settruncate(setT *set, int size);
int qh_setunique(setT **set, void *elem);
void qh_setzero(setT *set, int idx, int size);
#endif /* qhDEFset */

View File

@@ -0,0 +1,245 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
random.c and utilities
Park & Miller's minimimal standard random number generator
argc/argv conversion
Used by rbox. Do not use 'qh'
*/
#include "libqhull.h"
#include "random.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4706) /* assignment within conditional function */
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
#endif
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="argv_to_command">-</a>
qh_argv_to_command( argc, argv, command, max_size )
build command from argc/argv
max_size is at least
returns:
a space-delimited string of options (just as typed)
returns false if max_size is too short
notes:
silently removes
makes option string easy to input and output
matches qh_argv_to_command_size()
argc may be 0
*/
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
int i, remaining;
char *s;
*command= '\0'; /* max_size > 0 */
if (argc) {
if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
|| (s= strrchr( argv[0], '/')))
s++;
else
s= argv[0];
if ((int)strlen(s) < max_size) /* WARN64 */
strcpy(command, s);
else
goto error_argv;
if ((s= strstr(command, ".EXE"))
|| (s= strstr(command, ".exe")))
*s= '\0';
}
for (i=1; i < argc; i++) {
s= argv[i];
remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
if (!*s || strchr(s, ' ')) {
char *t= command + strlen(command);
remaining -= 2;
if (remaining < 0) {
goto error_argv;
}
*t++= ' ';
*t++= '"';
while (*s) {
if (*s == '"') {
if (--remaining < 0)
goto error_argv;
*t++= '\\';
}
*t++= *s++;
}
*t++= '"';
*t= '\0';
}else if (remaining < 0) {
goto error_argv;
}else
strcat(command, " ");
strcat(command, s);
}
return 1;
error_argv:
return 0;
} /* argv_to_command */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="argv_to_command_size">-</a>
qh_argv_to_command_size( argc, argv )
return size to allocate for qh_argv_to_command()
notes:
argc may be 0
actual size is usually shorter
*/
int qh_argv_to_command_size(int argc, char *argv[]) {
unsigned int count= 1; /* null-terminator if argc==0 */
int i;
char *s;
for (i=0; i<argc; i++){
count += (int)strlen(argv[i]) + 1; /* WARN64 */
if (i>0 && strchr(argv[i], ' ')) {
count += 2; /* quote delimiters */
for (s=argv[i]; *s; s++) {
if (*s == '"') {
count++;
}
}
}
}
return count;
} /* argv_to_command_size */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="rand">-</a>
qh_rand()
qh_srand( seed )
generate pseudo-random number between 1 and 2^31 -2
notes:
For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
From Park & Miller's minimal standard random number generator
Communications of the ACM, 31:1192-1201, 1988.
Does not use 0 or 2^31 -1
this is silently enforced by qh_srand()
Can make 'Rn' much faster by moving qh_rand to qh_distplane
*/
/* Global variables and constants */
int qh_last_random= 1; /* define as global variable instead of using qh */
#define qh_rand_a 16807
#define qh_rand_m 2147483647
#define qh_rand_q 127773 /* m div a */
#define qh_rand_r 2836 /* m mod a */
int qh_rand( void) {
int lo, hi, test;
int seed = qh_last_random;
hi = seed / qh_rand_q; /* seed div q */
lo = seed % qh_rand_q; /* seed mod q */
test = qh_rand_a * lo - qh_rand_r * hi;
if (test > 0)
seed= test;
else
seed= test + qh_rand_m;
qh_last_random= seed;
/* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
/* seed = qh_RANDOMmax; for testing */
return seed;
} /* rand */
void qh_srand( int seed) {
if (seed < 1)
qh_last_random= 1;
else if (seed >= qh_rand_m)
qh_last_random= qh_rand_m - 1;
else
qh_last_random= seed;
} /* qh_srand */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="randomfactor">-</a>
qh_randomfactor( scale, offset )
return a random factor r * scale + offset
notes:
qh.RANDOMa/b are defined in global.c
*/
realT qh_randomfactor(realT scale, realT offset) {
realT randr;
randr= qh_RANDOMint;
return randr * scale + offset;
} /* randomfactor */
/*-<a href="qh-geom.htm#TOC"
>-------------------------------</a><a name="randommatrix">-</a>
qh_randommatrix( buffer, dim, rows )
generate a random dim X dim matrix in range [-1,1]
assumes buffer is [dim+1, dim]
returns:
sets buffer to random numbers
sets rows to rows of buffer
sets row[dim] as scratch row
*/
void qh_randommatrix(realT *buffer, int dim, realT **rows) {
int i, k;
realT **rowi, *coord, realr;
coord= buffer;
rowi= rows;
for (i=0; i < dim; i++) {
*(rowi++)= coord;
for (k=0; k < dim; k++) {
realr= qh_RANDOMint;
*(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
*rowi= coord;
} /* randommatrix */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="strtol">-</a>
qh_strtol( s, endp) qh_strtod( s, endp)
internal versions of strtol() and strtod()
does not skip trailing spaces
notes:
some implementations of strtol()/strtod() skip trailing spaces
*/
double qh_strtod(const char *s, char **endp) {
double result;
result= strtod(s, endp);
if (s < (*endp) && (*endp)[-1] == ' ')
(*endp)--;
return result;
} /* strtod */
int qh_strtol(const char *s, char **endp) {
int result;
result= (int) strtol(s, endp, 10); /* WARN64 */
if (s< (*endp) && (*endp)[-1] == ' ')
(*endp)--;
return result;
} /* strtol */

View File

@@ -0,0 +1,34 @@
/*<html><pre> -<a href="qh-geom.htm"
>-------------------------------</a><a name="TOP">-</a>
random.h
header file for random and utility routines
see qh-geom.htm and random.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/random.h#2 $$Change: 2026 $
$DateTime: 2015/11/07 22:44:39 $$Author: bbarber $
*/
#ifndef qhDEFrandom
#define qhDEFrandom 1
#include "libqhull.h"
/*============= prototypes in alphabetical order ======= */
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
int qh_argv_to_command_size(int argc, char *argv[]);
int qh_rand( void);
void qh_srand( int seed);
realT qh_randomfactor(realT scale, realT offset);
void qh_randommatrix(realT *buffer, int dim, realT **row);
int qh_strtol(const char *s, char **endp);
double qh_strtod(const char *s, char **endp);
#endif /* qhDEFrandom */

View File

@@ -0,0 +1,870 @@
/*<html><pre> -<a href="index.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
rboxlib.c
Generate input points
notes:
For documentation, see prompt[] of rbox.c
50 points generated for 'rbox D4'
WARNING:
incorrect range if qh_RANDOMmax is defined wrong (user.h)
*/
#include "libqhull.h" /* First for user.h */
#include "random.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER /* Microsoft Visual C++ */
#pragma warning( disable : 4706) /* assignment within conditional expression. */
#pragma warning( disable : 4996) /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
#endif
#define MAXdim 200
#define PI 3.1415926535897932384
/* ------------------------------ prototypes ----------------*/
int qh_roundi( double a);
void qh_out1( double a);
void qh_out2n( double a, double b);
void qh_out3n( double a, double b, double c);
void qh_outcoord(int iscdd, double *coord, int dim);
void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim);
void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
void qh_free(void *mem);
void *qh_malloc(size_t size);
int qh_rand( void);
void qh_srand( int seed);
/* ------------------------------ globals -------------------*/
/* No state is carried between rbox requests */
typedef struct rboxT rboxT;
struct rboxT {
FILE *fout;
FILE *ferr;
int isinteger;
double out_offset;
jmp_buf errexit; /* exit label for rboxpoints, defined by setjmp(), called by qh_errexit_rbox() */
char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
};
int rbox_inuse= 0;
rboxT rbox;
/*-<a href="qh-qhull.htm#TOC"
>-------------------------------</a><a name="rboxpoints">-</a>
qh_rboxpoints( fout, ferr, rbox_command )
Generate points to fout according to rbox options
Report errors on ferr
returns:
0 (qh_ERRnone) on success
1 (qh_ERRinput) on input error
4 (qh_ERRmem) on memory error
5 (qh_ERRqhull) on internal error
notes:
To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
design:
Straight line code (consider defining a struct and functions):
Parse arguments into variables
Determine the number of points
Generate the points
*/
int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
int i,j,k;
int gendim;
int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
int cubesize, diamondsize, seed=0, count, apex;
int dim=3, numpoints=0, totpoints, addpoints=0;
int issphere=0, isaxis=0, iscdd=0, islens=0, isregular=0, iswidth=0, addcube=0;
int isgap=0, isspiral=0, NOcommand=0, adddiamond=0;
int israndom=0, istime=0;
int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
double *coordp, *simplex= NULL, *simplexp;
int nthroot, mult[MAXdim];
double norm, factor, randr, rangap, lensangle=0, lensbase=1;
double anglediff, angle, x, y, cube=0.0, diamond=0.0;
double box= qh_DEFAULTbox; /* scale all numbers before output */
double randmax= qh_RANDOMmax;
char command[200], seedbuf[200];
char *s= command, *t, *first_point= NULL;
time_t timedata;
int exitcode;
if (rbox_inuse) {
qh_fprintf_rbox(rbox.ferr, 6188, "rbox error: rbox in use by another process. Please lock calls to rbox.\n");
return qh_ERRqhull;
}
rbox_inuse= True;
rbox.ferr= ferr;
rbox.fout= fout;
exitcode= setjmp(rbox.errexit);
if (exitcode) {
/* same code for error exit and normal return. qh.NOerrexit is set */
if (simplex)
qh_free(simplex);
rbox_inuse= False;
return exitcode;
}
*command= '\0';
strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
while (*s && !isspace(*s)) /* skip program name */
s++;
while (*s) {
while (*s && isspace(*s))
s++;
if (*s == '-')
s++;
if (!*s)
break;
if (isdigit(*s)) {
numpoints= qh_strtol(s, &s);
continue;
}
/* ============= read flags =============== */
switch (*s++) {
case 'c':
addcube= 1;
t= s;
while (isspace(*t))
t++;
if (*t == 'G')
cube= qh_strtod(++t, &s);
break;
case 'd':
adddiamond= 1;
t= s;
while (isspace(*t))
t++;
if (*t == 'G')
diamond= qh_strtod(++t, &s);
break;
case 'h':
iscdd= 1;
break;
case 'l':
isspiral= 1;
break;
case 'n':
NOcommand= 1;
break;
case 'r':
isregular= 1;
break;
case 's':
issphere= 1;
break;
case 't':
istime= 1;
if (isdigit(*s)) {
seed= qh_strtol(s, &s);
israndom= 0;
}else
israndom= 1;
break;
case 'x':
issimplex= 1;
break;
case 'y':
issimplex2= 1;
break;
case 'z':
rbox.isinteger= 1;
break;
case 'B':
box= qh_strtod(s, &s);
isbox= 1;
break;
case 'C':
if (*s)
coincidentpoints= qh_strtol(s, &s);
if (*s == ',') {
++s;
coincidentradius= qh_strtod(s, &s);
}
if (*s == ',') {
++s;
coincidenttotal= qh_strtol(s, &s);
}
if (*s && !isspace(*s)) {
qh_fprintf_rbox(rbox.ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
qh_errexit_rbox(qh_ERRinput);
}
if (coincidentpoints==0){
qh_fprintf_rbox(rbox.ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
qh_errexit_rbox(qh_ERRinput);
}
if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
qh_fprintf_rbox(rbox.ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
qh_errexit_rbox(qh_ERRinput);
}
break;
case 'D':
dim= qh_strtol(s, &s);
if (dim < 1
|| dim > MAXdim) {
qh_fprintf_rbox(rbox.ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
qh_errexit_rbox(qh_ERRinput);
}
break;
case 'G':
if (isdigit(*s))
gap= qh_strtod(s, &s);
else
gap= 0.5;
isgap= 1;
break;
case 'L':
if (isdigit(*s))
radius= qh_strtod(s, &s);
else
radius= 10;
islens= 1;
break;
case 'M':
ismesh= 1;
if (*s)
meshn= qh_strtod(s, &s);
if (*s == ',') {
++s;
meshm= qh_strtod(s, &s);
}else
meshm= 0.0;
if (*s == ',') {
++s;
meshr= qh_strtod(s, &s);
}else
meshr= sqrt(meshn*meshn + meshm*meshm);
if (*s && !isspace(*s)) {
qh_fprintf_rbox(rbox.ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
meshn= 3.0, meshm=4.0, meshr=5.0;
}
break;
case 'O':
rbox.out_offset= qh_strtod(s, &s);
break;
case 'P':
if (!first_point)
first_point= s-1;
addpoints++;
while (*s && !isspace(*s)) /* read points later */
s++;
break;
case 'W':
width= qh_strtod(s, &s);
iswidth= 1;
break;
case 'Z':
if (isdigit(*s))
radius= qh_strtod(s, &s);
else
radius= 1.0;
isaxis= 1;
break;
default:
qh_fprintf_rbox(rbox.ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
qh_errexit_rbox(qh_ERRinput);
}
if (*s && !isspace(*s)) {
qh_fprintf_rbox(rbox.ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
qh_errexit_rbox(qh_ERRinput);
}
}
/* ============= defaults, constants, and sizes =============== */
if (rbox.isinteger && !isbox)
box= qh_DEFAULTzbox;
if (addcube) {
cubesize= (int)floor(ldexp(1.0,dim)+0.5);
if (cube == 0.0)
cube= box;
}else
cubesize= 0;
if (adddiamond) {
diamondsize= 2*dim;
if (diamond == 0.0)
diamond= box;
}else
diamondsize= 0;
if (islens) {
if (isaxis) {
qh_fprintf_rbox(rbox.ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
qh_errexit_rbox(qh_ERRinput);
}
if (radius <= 1.0) {
qh_fprintf_rbox(rbox.ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
radius);
qh_errexit_rbox(qh_ERRinput);
}
lensangle= asin(1.0/radius);
lensbase= radius * cos(lensangle);
}
if (!numpoints) {
if (issimplex2)
; /* ok */
else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
qh_fprintf_rbox(rbox.ferr, 6192, "rbox error: missing count\n");
qh_errexit_rbox(qh_ERRinput);
}else if (adddiamond + addcube + addpoints)
; /* ok */
else {
numpoints= 50; /* ./rbox D4 is the test case */
issphere= 1;
}
}
if ((issimplex + islens + isspiral + ismesh > 1)
|| (issimplex + issphere + isspiral + ismesh > 1)) {
qh_fprintf_rbox(rbox.ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
qh_errexit_rbox(qh_ERRinput);
}
if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
qh_fprintf_rbox(rbox.ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
qh_errexit_rbox(qh_ERRinput);
}
if (coincidenttotal == 0)
coincidenttotal= numpoints;
/* ============= print header with total points =============== */
if (issimplex || ismesh)
totpoints= numpoints;
else if (issimplex2)
totpoints= numpoints+dim+1;
else if (isregular) {
totpoints= numpoints;
if (dim == 2) {
if (islens)
totpoints += numpoints - 2;
}else if (dim == 3) {
if (islens)
totpoints += 2 * numpoints;
else if (isgap)
totpoints += 1 + numpoints;
else
totpoints += 2;
}
}else
totpoints= numpoints + isaxis;
totpoints += cubesize + diamondsize + addpoints;
totpoints += coincidentpoints*coincidenttotal;
/* ============= seed randoms =============== */
if (istime == 0) {
for (s=command; *s; s++) {
if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
i= 'x';
else
i= *s;
seed= 11*seed + i;
}
}else if (israndom) {
seed= (int)time(&timedata);
sprintf(seedbuf, " t%d", seed); /* appends an extra t, not worth removing */
strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
t= strstr(command, " t ");
if (t)
strcpy(t+1, t+3); /* remove " t " */
} /* else, seed explicitly set to n */
qh_RANDOMseed_(seed);
/* ============= print header =============== */
if (iscdd)
qh_fprintf_rbox(rbox.fout, 9391, "%s\nbegin\n %d %d %s\n",
NOcommand ? "" : command,
totpoints, dim+1,
rbox.isinteger ? "integer" : "real");
else if (NOcommand)
qh_fprintf_rbox(rbox.fout, 9392, "%d\n%d\n", dim, totpoints);
else
/* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
qh_fprintf_rbox(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
/* ============= explicit points =============== */
if ((s= first_point)) {
while (s && *s) { /* 'P' */
count= 0;
if (iscdd)
qh_out1( 1.0);
while (*++s) {
qh_out1( qh_strtod(s, &s));
count++;
if (isspace(*s) || !*s)
break;
if (*s != ',') {
qh_fprintf_rbox(rbox.ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
qh_errexit_rbox(qh_ERRinput);
}
}
if (count < dim) {
for (k=dim-count; k--; )
qh_out1( 0.0);
}else if (count > dim) {
qh_fprintf_rbox(rbox.ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
count, dim, s);
qh_errexit_rbox(qh_ERRinput);
}
qh_fprintf_rbox(rbox.fout, 9394, "\n");
while ((s= strchr(s, 'P'))) {
if (isspace(s[-1]))
break;
}
}
}
/* ============= simplex distribution =============== */
if (issimplex+issimplex2) {
if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
qh_fprintf_rbox(rbox.ferr, 6196, "rbox error: insufficient memory for simplex\n");
qh_errexit_rbox(qh_ERRmem); /* qh_ERRmem */
}
simplexp= simplex;
if (isregular) {
for (i=0; i<dim; i++) {
for (k=0; k<dim; k++)
*(simplexp++)= i==k ? 1.0 : 0.0;
}
for (k=0; k<dim; k++)
*(simplexp++)= -1.0;
}else {
for (i=0; i<dim+1; i++) {
for (k=0; k<dim; k++) {
randr= qh_RANDOMint;
*(simplexp++)= 2.0 * randr/randmax - 1.0;
}
}
}
if (issimplex2) {
simplexp= simplex;
for (i=0; i<dim+1; i++) {
if (iscdd)
qh_out1( 1.0);
for (k=0; k<dim; k++)
qh_out1( *(simplexp++) * box);
qh_fprintf_rbox(rbox.fout, 9395, "\n");
}
}
for (j=0; j<numpoints; j++) {
if (iswidth)
apex= qh_RANDOMint % (dim+1);
else
apex= -1;
for (k=0; k<dim; k++)
coord[k]= 0.0;
norm= 0.0;
for (i=0; i<dim+1; i++) {
randr= qh_RANDOMint;
factor= randr/randmax;
if (i == apex)
factor *= width;
norm += factor;
for (k=0; k<dim; k++) {
simplexp= simplex + i*dim + k;
coord[k] += factor * (*simplexp);
}
}
for (k=0; k<dim; k++)
coord[k] *= box/norm;
qh_outcoord(iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
}
isregular= 0; /* continue with isbox */
numpoints= 0;
}
/* ============= mesh distribution =============== */
if (ismesh) {
nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
for (k=dim; k--; )
mult[k]= 0;
for (i=0; i < numpoints; i++) {
coordp= coord;
for (k=0; k < dim; k++) {
if (k == 0)
*(coordp++)= mult[0] * meshn + mult[1] * (-meshm);
else if (k == 1)
*(coordp++)= mult[0] * meshm + mult[1] * meshn;
else
*(coordp++)= mult[k] * meshr;
}
qh_outcoord(iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
for (k=0; k < dim; k++) {
if (++mult[k] < nthroot)
break;
mult[k]= 0;
}
}
}
/* ============= regular points for 's' =============== */
else if (isregular && !islens) {
if (dim != 2 && dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(rbox.ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(qh_ERRinput);
}
if (!isaxis || radius == 0.0) {
isaxis= 1;
radius= 1.0;
}
if (dim == 3) {
if (iscdd)
qh_out1( 1.0);
qh_out3n( 0.0, 0.0, -box);
if (!isgap) {
if (iscdd)
qh_out1( 1.0);
qh_out3n( 0.0, 0.0, box);
}
}
angle= 0.0;
anglediff= 2.0 * PI/numpoints;
for (i=0; i < numpoints; i++) {
angle += anglediff;
x= radius * cos(angle);
y= radius * sin(angle);
if (dim == 2) {
if (iscdd)
qh_out1( 1.0);
qh_out2n( x*box, y*box);
}else {
norm= sqrt(1.0 + x*x + y*y);
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x/norm, box*y/norm, box/norm);
if (isgap) {
x *= 1-gap;
y *= 1-gap;
norm= sqrt(1.0 + x*x + y*y);
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x/norm, box*y/norm, box/norm);
}
}
}
}
/* ============= regular points for 'r Ln D2' =============== */
else if (isregular && islens && dim == 2) {
double cos_0;
angle= lensangle;
anglediff= 2 * lensangle/(numpoints - 1);
cos_0= cos(lensangle);
for (i=0; i < numpoints; i++, angle -= anglediff) {
x= radius * sin(angle);
y= radius * (cos(angle) - cos_0);
if (iscdd)
qh_out1( 1.0);
qh_out2n( x*box, y*box);
if (i != 0 && i != numpoints - 1) {
if (iscdd)
qh_out1( 1.0);
qh_out2n( x*box, -y*box);
}
}
}
/* ============= regular points for 'r Ln D3' =============== */
else if (isregular && islens && dim != 2) {
if (dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(rbox.ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(qh_ERRinput);
}
angle= 0.0;
anglediff= 2* PI/numpoints;
if (!isgap) {
isgap= 1;
gap= 0.5;
}
offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
for (i=0; i < numpoints; i++, angle += anglediff) {
x= cos(angle);
y= sin(angle);
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x, box*y, 0.0);
x *= 1-gap;
y *= 1-gap;
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x, box*y, box * offset);
if (iscdd)
qh_out1( 1.0);
qh_out3n( box*x, box*y, -box * offset);
}
}
/* ============= apex of 'Zn' distribution + gendim =============== */
else {
if (isaxis) {
gendim= dim-1;
if (iscdd)
qh_out1( 1.0);
for (j=0; j < gendim; j++)
qh_out1( 0.0);
qh_out1( -box);
qh_fprintf_rbox(rbox.fout, 9398, "\n");
}else if (islens)
gendim= dim-1;
else
gendim= dim;
/* ============= generate random point in unit cube =============== */
for (i=0; i < numpoints; i++) {
norm= 0.0;
for (j=0; j < gendim; j++) {
randr= qh_RANDOMint;
coord[j]= 2.0 * randr/randmax - 1.0;
norm += coord[j] * coord[j];
}
norm= sqrt(norm);
/* ============= dim-1 point of 'Zn' distribution ========== */
if (isaxis) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= radius * rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln s' distribution =========== */
}else if (islens && issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln' distribution ========== */
}else if (islens && !issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * gap;
else
coord[j]= 1.0 - coord[j] * gap;
/* ============= point of 'l' distribution =============== */
}else if (isspiral) {
if (dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(rbox.ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
qh_errexit_rbox(qh_ERRinput);
}
coord[0]= cos(2*PI*i/(numpoints - 1));
coord[1]= sin(2*PI*i/(numpoints - 1));
coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
/* ============= point of 's' distribution =============== */
}else if (issphere) {
factor= 1.0/norm;
if (iswidth) {
randr= qh_RANDOMint;
factor *= 1.0 - width * randr/randmax;
}
for (j=0; j<dim; j++)
coord[j]= factor * coord[j];
}
/* ============= project 'Zn s' point in to sphere =============== */
if (isaxis && issphere) {
coord[dim-1]= 1.0;
norm= 1.0;
for (j=0; j<gendim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] / norm;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
/* ============= project 'Zn' point onto cube =============== */
}else if (isaxis && !issphere) { /* not very interesting */
randr= qh_RANDOMint;
coord[dim-1]= 2.0 * randr/randmax - 1.0;
/* ============= project 'Ln' point out to sphere =============== */
}else if (islens) {
coord[dim-1]= lensbase;
for (j=0, norm= 0; j<dim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] * radius/ norm;
coord[dim-1] -= lensbase;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
if (qh_RANDOMint > randmax/2)
coord[dim-1]= -coord[dim-1];
/* ============= project 'Wn' point toward boundary =============== */
}else if (iswidth && !issphere) {
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * width;
else
coord[j]= 1.0 - coord[j] * width;
}
/* ============= scale point to box =============== */
for (k=0; k<dim; k++)
coord[k]= coord[k] * box;
/* ============= write output =============== */
qh_outcoord(iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
}
}
/* ============= write cube vertices =============== */
if (addcube) {
for (j=0; j<cubesize; j++) {
if (iscdd)
qh_out1( 1.0);
for (k=dim-1; k>=0; k--) {
if (j & ( 1 << k))
qh_out1( cube);
else
qh_out1( -cube);
}
qh_fprintf_rbox(rbox.fout, 9400, "\n");
}
}
/* ============= write diamond vertices =============== */
if (adddiamond) {
for (j=0; j<diamondsize; j++) {
if (iscdd)
qh_out1( 1.0);
for (k=dim-1; k>=0; k--) {
if (j/2 != k)
qh_out1( 0.0);
else if (j & 0x1)
qh_out1( diamond);
else
qh_out1( -diamond);
}
qh_fprintf_rbox(rbox.fout, 9401, "\n");
}
}
if (iscdd)
qh_fprintf_rbox(rbox.fout, 9402, "end\nhull\n");
/* same code for error exit and normal return */
qh_free(simplex);
rbox_inuse= False;
return qh_ERRnone;
} /* rboxpoints */
/*------------------------------------------------
outxxx - output functions for qh_rboxpoints
*/
int qh_roundi( double a) {
if (a < 0.0) {
if (a - 0.5 < INT_MIN) {
qh_fprintf_rbox(rbox.ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
qh_errexit_rbox(qh_ERRinput);
}
return (int)(a - 0.5);
}else {
if (a + 0.5 > INT_MAX) {
qh_fprintf_rbox(rbox.ferr, 6201, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a);
qh_errexit_rbox(qh_ERRinput);
}
return (int)(a + 0.5);
}
} /* qh_roundi */
void qh_out1(double a) {
if (rbox.isinteger)
qh_fprintf_rbox(rbox.fout, 9403, "%d ", qh_roundi( a+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset);
} /* qh_out1 */
void qh_out2n( double a, double b) {
if (rbox.isinteger)
qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset);
} /* qh_out2n */
void qh_out3n( double a, double b, double c) {
if (rbox.isinteger)
qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset), qh_roundi(c+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9408, qh_REAL_3n, a+rbox.out_offset, b+rbox.out_offset, c+rbox.out_offset);
} /* qh_out3n */
void qh_outcoord(int iscdd, double *coord, int dim) {
double *p= coord;
int k;
if (iscdd)
qh_out1( 1.0);
for (k=0; k < dim; k++)
qh_out1(*(p++));
qh_fprintf_rbox(rbox.fout, 9396, "\n");
} /* qh_outcoord */
void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
double *p;
double randr, delta;
int i,k;
double randmax= qh_RANDOMmax;
for (i= 0; i<coincidentpoints; i++) {
p= coord;
if (iscdd)
qh_out1( 1.0);
for (k=0; k < dim; k++) {
randr= qh_RANDOMint;
delta= 2.0 * randr/randmax - 1.0; /* -1..+1 */
delta *= radius;
qh_out1(*(p++) + delta);
}
qh_fprintf_rbox(rbox.fout, 9410, "\n");
}
} /* qh_outcoincident */
/*------------------------------------------------
Only called from qh_rboxpoints or qh_fprintf_rbox
qh_fprintf_rbox is only called from qh_rboxpoints
*/
void qh_errexit_rbox(int exitcode)
{
longjmp(rbox.errexit, exitcode);
} /* qh_errexit_rbox */

View File

@@ -0,0 +1,717 @@
/*<html><pre> -<a href="qh-stat.htm"
>-------------------------------</a><a name="TOP">-</a>
stat.c
contains all statistics that are collected for qhull
see qh-stat.htm and stat.h
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/stat.c#5 $$Change: 2062 $
$DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
*/
#include "qhull_a.h"
/*============ global data structure ==========*/
#if qh_QHpointer
qhstatT *qh_qhstat=NULL; /* global data structure */
#else
qhstatT qh_qhstat; /* add "={0}" if this causes a compiler error */
#endif
/*========== functions in alphabetic order ================*/
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="allstatA">-</a>
qh_allstatA()
define statistics in groups of 20
notes:
(otherwise, 'gcc -O2' uses too much memory)
uses qhstat.next
*/
void qh_allstatA(void) {
/* zdef_(type,name,doc,average) */
zzdef_(zdoc, Zdoc2, "precision statistics", -1);
zdef_(zinc, Znewvertex, NULL, -1);
zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet(!0s)", Znewvertex);
zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
qhstat precision= qhstat next; /* call qh_precision for each of these */
zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
}
void qh_allstatB(void) {
zzdef_(zdoc, Zdoc1, "summary information", -1);
zdef_(zinc, Zvertices, "number of vertices in output", -1);
zdef_(zinc, Znumfacets, "number of facets in output", -1);
zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
zdef_(zinc, Znumridges, "number of ridges in output", -1);
zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
zzdef_(zinc, Zsetplane, "facets created altogether", -1);
zdef_(zinc, Ztotridges, "ridges created altogether", -1);
zdef_(zinc, Zpostfacets, "facets before post merge", -1);
zdef_(zadd, Znummergetot, "average merges per facet(at most 511)", Znumfacets);
zdef_(zmax, Znummergemax, " maximum merges for a facet(at most 511)", -1);
zdef_(zinc, Zangle, NULL, -1);
zdef_(wadd, Wangle, "average angle(cosine) of facet normals for all ridges", Zangle);
zdef_(wmax, Wanglemax, " maximum angle(cosine) of facet normals across a ridge", -1);
zdef_(wmin, Wanglemin, " minimum angle(cosine) of facet normals across a ridge", -1);
zdef_(wadd, Wareatot, "total area of facets", -1);
zdef_(wmax, Wareamax, " maximum facet area", -1);
zdef_(wmin, Wareamin, " minimum facet area", -1);
}
void qh_allstatC(void) {
zdef_(zdoc, Zdoc9, "build hull statistics", -1);
zzdef_(zinc, Zprocessed, "points processed", -1);
zzdef_(zinc, Zretry, "retries due to precision problems", -1);
zdef_(wmax, Wretrymax, " max. random joggle", -1);
zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
zdef_(zinc, Zinsidevisible, " ave. visible facets without an horizon neighbor", Zprocessed);
zdef_(zadd, Zvisfacettot, " ave. facets deleted per iteration", Zprocessed);
zdef_(zmax, Zvisfacetmax, " maximum", -1);
zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
zdef_(zmax, Zvisvertexmax, " maximum", -1);
zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
zdef_(zadd, Znewfacettot, "ave. new or merged facets per iteration", Zprocessed);
zdef_(zmax, Znewfacetmax, " maximum(includes initial simplex)", -1);
zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
zdef_(wadd, Wnewbalance2, " standard deviation", -1);
zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
zdef_(wadd, Wpbalance2, " standard deviation", -1);
zdef_(zinc, Zpbalance, " number of trials", -1);
zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
zdef_(zinc, Zdetsimplex, "determinants computed(area & initial hull)", -1);
zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
zdef_(zinc, Znotmax, "points ignored(!above max_outside)", -1);
zdef_(zinc, Znotgood, "points ignored(!above a good facet)", -1);
zdef_(zinc, Znotgoodnew, "points ignored(didn't create a good new facet)", -1);
zdef_(zinc, Zgoodfacet, "good facets found", -1);
zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
zzdef_(zinc, Zcheckpart, " ave. distance tests per check", Ztotcheck);
}
void qh_allstatD(void) {
zdef_(zinc, Zvisit, "resets of visit_id", -1);
zdef_(zinc, Zvvisit, " resets of vertex_visit", -1);
zdef_(zmax, Zvisit2max, " max visit_id/2", -1);
zdef_(zmax, Zvvisit2max, " max vertex_visit/2", -1);
zdef_(zdoc, Zdoc4, "partitioning statistics(see previous for outer planes)", -1);
zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
zdef_(zmax, Zdelvertexmax, " maximum vertices deleted per iteration", -1);
zdef_(zinc, Zfindbest, "calls to findbest", -1);
zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
zdef_(zinc, Zfindjump, " ave. clearly better", Zfindhorizon);
zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
zdef_(zinc, Zpartflip, " repartitioned coplanar points for flipped orientation", -1);
}
void qh_allstatE(void) {
zdef_(zinc, Zpartinside, "inside points", -1);
zdef_(zinc, Zpartnear, " inside points kept with a facet", -1);
zdef_(zinc, Zcoplanarinside, " inside points that were coplanar with a facet", -1);
zdef_(zinc, Zbestlower, "calls to findbestlower", -1);
zdef_(zinc, Zbestlowerv, " with search of vertex neighbors", -1);
zdef_(zinc, Zbestlowerall, " with rare search of all facets", -1);
zdef_(zmax, Zbestloweralln, " facets per search of all facets", -1);
zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
zdef_(zinc, Ztotpartition, "partitions of a point", -1);
zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1);
zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1);
zdef_(zinc, Zdistgood, "distance tests for checking good point", -1);
zdef_(zinc, Zdistio, "distance tests for output", -1);
zdef_(zinc, Zdiststat, "distance tests for statistics", -1);
zdef_(zinc, Zdistplane, "total number of distance tests", -1);
zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
zzdef_(zinc, Zpartcoplanar, " distance tests for these partitions", -1);
zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
}
void qh_allstatE2(void) {
zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
zdef_(zinc, Zhashridge, "total lookups of subridges(duplicates and boundary)", -1);
zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
}
void qh_allstatF(void) {
zdef_(zdoc, Zdoc7, "statistics for merging", -1);
zdef_(zinc, Zpremergetot, "merge iterations", -1);
zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
zdef_(zadd, Zmergeinitmax, " maximum", -1);
zdef_(zadd, Zmergesettot, " ave. additional non-convex ridges per iteration", Zpremergetot);
zdef_(zadd, Zmergesetmax, " maximum additional in one pass", -1);
zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
zdef_(zadd, Zmergesettot2, " additional non-convex ridges", -1);
zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet(w/roundoff)", -1);
zdef_(wmin, Wminvertex, "max distance of merged vertex below facet(or roundoff)", -1);
zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
zzdef_(zadd, Zcyclefacettot, " ave. facets per cycle", Zcyclehorizon);
zdef_(zmax, Zcyclefacetmax, " max. facets", -1);
zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
zdef_(zinc, Zmergenew, "new facets merged", -1);
zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1);
}
void qh_allstatG(void) {
zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
zdef_(wadd, Wacoplanartot, " average merge distance", Zacoplanar);
zdef_(wmax, Wacoplanarmax, " maximum merge distance", -1);
zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
zdef_(wadd, Wcoplanartot, " average merge distance", Zcoplanar);
zdef_(wmax, Wcoplanarmax, " maximum merge distance", -1);
zdef_(zinc, Zconcave, "merges due to concave facets", -1);
zdef_(wadd, Wconcavetot, " average merge distance", Zconcave);
zdef_(wmax, Wconcavemax, " maximum merge distance", -1);
zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
zdef_(wadd, Wavoidoldtot, " average merge distance", Zavoidold);
zdef_(wmax, Wavoidoldmax, " maximum merge distance", -1);
zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
zdef_(wadd, Wdegentot, " average merge distance", Zdegen);
zdef_(wmax, Wdegenmax, " maximum merge distance", -1);
zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
zdef_(wadd, Wflippedtot, " average merge distance", Zflipped);
zdef_(wmax, Wflippedmax, " maximum merge distance", -1);
zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
zdef_(wadd, Wduplicatetot, " average merge distance", Zduplicate);
zdef_(wmax, Wduplicatemax, " maximum merge distance", -1);
}
void qh_allstatH(void) {
zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
zdef_(zinc, Zdupridge, " duplicate ridges detected", -1);
zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
zdef_(zinc, Zdelfacetdup, " facets deleted because of no neighbors", -1);
zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
zdef_(zinc, Zremvertexdel, " deleted", -1);
zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
zdef_(zadd, Zintersecttot, " ave. number found per vertex", Zintersect);
zdef_(zmax, Zintersectmax, " max. found for a vertex", -1);
zdef_(zinc, Zvertexridge, NULL, -1);
zdef_(zadd, Zvertexridgetot, " ave. number of ridges per tested vertex", Zvertexridge);
zdef_(zmax, Zvertexridgemax, " max. number of ridges per tested vertex", -1);
zdef_(zdoc, Zdoc10, "memory usage statistics(in bytes)", -1);
zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
zdef_(zadd, Zmempoints, "for input points and outside and coplanar sets",-1);
zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
} /* allstat */
void qh_allstatI(void) {
qhstat vridges= qhstat next;
zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
zzdef_(wadd, Wridge, " ave. distance to ridge", Zridge);
zzdef_(wmax, Wridgemax, " max. distance to ridge", -1);
zzdef_(zinc, Zridgemid, "bounded ridges", -1);
zzdef_(wadd, Wridgemid, " ave. distance of midpoint to ridge", Zridgemid);
zzdef_(wmax, Wridgemidmax, " max. distance of midpoint to ridge", -1);
zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
zzdef_(wadd, Wridgeok, " ave. angle to ridge", Zridgeok);
zzdef_(wmax, Wridgeokmax, " max. angle to ridge", -1);
zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0);
zzdef_(wmax, Wridge0max, " max. angle to ridge", -1);
zdef_(zdoc, Zdoc12, "Triangulation statistics(Qt)", -1);
zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
zdef_(zadd, Ztricoplanartot, " ave. new facets created(may be deleted)", Ztricoplanar);
zdef_(zmax, Ztricoplanarmax, " max. new facets created", -1);
zdef_(zinc, Ztrinull, "null new facets deleted(duplicated vertex)", -1);
zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted(same vertices)", -1);
zdef_(zinc, Ztridegen, "degenerate new facets in output(same ridge)", -1);
} /* allstat */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="allstatistics">-</a>
qh_allstatistics()
reset printed flag for all statistics
*/
void qh_allstatistics(void) {
int i;
for(i=ZEND; i--; )
qhstat printed[i]= False;
} /* allstatistics */
#if qh_KEEPstatistics
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="collectstatistics">-</a>
qh_collectstatistics()
collect statistics for qh.facet_list
*/
void qh_collectstatistics(void) {
facetT *facet, *neighbor, **neighborp;
vertexT *vertex, **vertexp;
realT dotproduct, dist;
int sizneighbors, sizridges, sizvertices, i;
qh old_randomdist= qh RANDOMdist;
qh RANDOMdist= False;
zval_(Zmempoints)= qh num_points * qh normal_size +
sizeof(qhT) + sizeof(qhstatT);
zval_(Zmemfacets)= 0;
zval_(Zmemridges)= 0;
zval_(Zmemvertices)= 0;
zval_(Zangle)= 0;
wval_(Wangle)= 0.0;
zval_(Znumridges)= 0;
zval_(Znumfacets)= 0;
zval_(Znumneighbors)= 0;
zval_(Znumvertices)= 0;
zval_(Znumvneighbors)= 0;
zval_(Znummergetot)= 0;
zval_(Znummergemax)= 0;
zval_(Zvertices)= qh num_vertices - qh_setsize(qh del_vertices);
if (qh MERGING || qh APPROXhull || qh JOGGLEmax < REALmax/2)
wmax_(Wmaxoutside, qh max_outside);
if (qh MERGING)
wmin_(Wminvertex, qh min_vertex);
FORALLfacets
facet->seen= False;
if (qh DELAUNAY) {
FORALLfacets {
if (facet->upperdelaunay != qh UPPERdelaunay)
facet->seen= True; /* remove from angle statistics */
}
}
FORALLfacets {
if (facet->visible && qh NEWfacets)
continue;
sizvertices= qh_setsize(facet->vertices);
sizneighbors= qh_setsize(facet->neighbors);
sizridges= qh_setsize(facet->ridges);
zinc_(Znumfacets);
zadd_(Znumvertices, sizvertices);
zmax_(Zmaxvertices, sizvertices);
zadd_(Znumneighbors, sizneighbors);
zmax_(Zmaxneighbors, sizneighbors);
zadd_(Znummergetot, facet->nummerge);
i= facet->nummerge; /* avoid warnings */
zmax_(Znummergemax, i);
if (!facet->simplicial) {
if (sizvertices == qh hull_dim) {
zinc_(Znowsimplicial);
}else {
zinc_(Znonsimplicial);
}
}
if (sizridges) {
zadd_(Znumridges, sizridges);
zmax_(Zmaxridges, sizridges);
}
zadd_(Zmemfacets, sizeof(facetT) + qh normal_size + 2*sizeof(setT)
+ SETelemsize * (sizneighbors + sizvertices));
if (facet->ridges) {
zadd_(Zmemridges,
sizeof(setT) + SETelemsize * sizridges + sizridges *
(sizeof(ridgeT) + sizeof(setT) + SETelemsize * (qh hull_dim-1))/2);
}
if (facet->outsideset)
zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->outsideset));
if (facet->coplanarset)
zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->coplanarset));
if (facet->seen) /* Delaunay upper envelope */
continue;
facet->seen= True;
FOREACHneighbor_(facet) {
if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
|| neighbor->seen || !facet->normal || !neighbor->normal)
continue;
dotproduct= qh_getangle(facet->normal, neighbor->normal);
zinc_(Zangle);
wadd_(Wangle, dotproduct);
wmax_(Wanglemax, dotproduct)
wmin_(Wanglemin, dotproduct)
}
if (facet->normal) {
FOREACHvertex_(facet->vertices) {
zinc_(Zdiststat);
qh_distplane(vertex->point, facet, &dist);
wmax_(Wvertexmax, dist);
wmin_(Wvertexmin, dist);
}
}
}
FORALLvertices {
if (vertex->deleted)
continue;
zadd_(Zmemvertices, sizeof(vertexT));
if (vertex->neighbors) {
sizneighbors= qh_setsize(vertex->neighbors);
zadd_(Znumvneighbors, sizneighbors);
zmax_(Zmaxvneighbors, sizneighbors);
zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors);
}
}
qh RANDOMdist= qh old_randomdist;
} /* collectstatistics */
#endif /* qh_KEEPstatistics */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="freestatistics">-</a>
qh_freestatistics( )
free memory used for statistics
*/
void qh_freestatistics(void) {
#if qh_QHpointer
qh_free(qh_qhstat);
qh_qhstat= NULL;
#endif
} /* freestatistics */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="initstatistics">-</a>
qh_initstatistics( )
allocate and initialize statistics
notes:
uses qh_malloc() instead of qh_memalloc() since mem.c not set up yet
NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
On first call, only qhmem.ferr is defined. qh_memalloc is not setup.
Also invoked by QhullQh().
*/
void qh_initstatistics(void) {
int i;
realT realx;
int intx;
#if qh_QHpointer
if(qh_qhstat){ /* qh_initstatistics may be called from Qhull::resetStatistics() */
qh_free(qh_qhstat);
qh_qhstat= 0;
}
if (!(qh_qhstat= (qhstatT *)qh_malloc(sizeof(qhstatT)))) {
qh_fprintf_stderr(6183, "qhull error (qh_initstatistics): insufficient memory\n");
qh_exit(qh_ERRmem); /* can not use qh_errexit() */
}
#endif
qhstat next= 0;
qh_allstatA();
qh_allstatB();
qh_allstatC();
qh_allstatD();
qh_allstatE();
qh_allstatE2();
qh_allstatF();
qh_allstatG();
qh_allstatH();
qh_allstatI();
if (qhstat next > (int)sizeof(qhstat id)) {
qh_fprintf(qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
qhstat.next %d should be <= sizeof(qhstat id) %d\n", qhstat next, (int)sizeof(qhstat id));
#if 0 /* for locating error, Znumridges should be duplicated */
for(i=0; i < ZEND; i++) {
int j;
for(j=i+1; j < ZEND; j++) {
if (qhstat id[i] == qhstat id[j]) {
qh_fprintf(qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
qhstat id[i], i, j);
}
}
}
#endif
qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
}
qhstat init[zinc].i= 0;
qhstat init[zadd].i= 0;
qhstat init[zmin].i= INT_MAX;
qhstat init[zmax].i= INT_MIN;
qhstat init[wadd].r= 0;
qhstat init[wmin].r= REALmax;
qhstat init[wmax].r= -REALmax;
for(i=0; i < ZEND; i++) {
if (qhstat type[i] > ZTYPEreal) {
realx= qhstat init[(unsigned char)(qhstat type[i])].r;
qhstat stats[i].r= realx;
}else if (qhstat type[i] != zdoc) {
intx= qhstat init[(unsigned char)(qhstat type[i])].i;
qhstat stats[i].i= intx;
}
}
} /* initstatistics */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="newstats">-</a>
qh_newstats( )
returns True if statistics for zdoc
returns:
next zdoc
*/
boolT qh_newstats(int idx, int *nextindex) {
boolT isnew= False;
int start, i;
if (qhstat type[qhstat id[idx]] == zdoc)
start= idx+1;
else
start= idx;
for(i= start; i < qhstat next && qhstat type[qhstat id[i]] != zdoc; i++) {
if (!qh_nostatistic(qhstat id[i]) && !qhstat printed[qhstat id[i]])
isnew= True;
}
*nextindex= i;
return isnew;
} /* newstats */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="nostatistic">-</a>
qh_nostatistic( index )
true if no statistic to print
*/
boolT qh_nostatistic(int i) {
if ((qhstat type[i] > ZTYPEreal
&&qhstat stats[i].r == qhstat init[(unsigned char)(qhstat type[i])].r)
|| (qhstat type[i] < ZTYPEreal
&&qhstat stats[i].i == qhstat init[(unsigned char)(qhstat type[i])].i))
return True;
return False;
} /* nostatistic */
#if qh_KEEPstatistics
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printallstatistics">-</a>
qh_printallstatistics( fp, string )
print all statistics with header 'string'
*/
void qh_printallstatistics(FILE *fp, const char *string) {
qh_allstatistics();
qh_collectstatistics();
qh_printstatistics(fp, string);
qh_memstatistics(fp);
}
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstatistics">-</a>
qh_printstatistics( fp, string )
print statistics to a file with header 'string'
skips statistics with qhstat.printed[] (reset with qh_allstatistics)
see:
qh_printallstatistics()
*/
void qh_printstatistics(FILE *fp, const char *string) {
int i, k;
realT ave;
if (qh num_points != qh num_vertices) {
wval_(Wpbalance)= 0;
wval_(Wpbalance2)= 0;
}else
wval_(Wpbalance2)= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
wval_(Wpbalance2), &ave);
wval_(Wnewbalance2)= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
wval_(Wnewbalance2), &ave);
qh_fprintf(fp, 9350, "\n\
%s\n\
qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh rbox_command,
qh qhull_command, qh_version, qh qhull_options);
qh_fprintf(fp, 9351, "\nprecision constants:\n\
%6.2g max. abs. coordinate in the (transformed) input('Qbd:n')\n\
%6.2g max. roundoff error for distance computation('En')\n\
%6.2g max. roundoff error for angle computations\n\
%6.2g min. distance for outside points ('Wn')\n\
%6.2g min. distance for visible facets ('Vn')\n\
%6.2g max. distance for coplanar facets ('Un')\n\
%6.2g max. facet width for recomputing centrum and area\n\
",
qh MAXabs_coord, qh DISTround, qh ANGLEround, qh MINoutside,
qh MINvisible, qh MAXcoplanar, qh WIDEfacet);
if (qh KEEPnearinside)
qh_fprintf(fp, 9352, "\
%6.2g max. distance for near-inside points\n", qh NEARinside);
if (qh premerge_cos < REALmax/2) qh_fprintf(fp, 9353, "\
%6.2g max. cosine for pre-merge angle\n", qh premerge_cos);
if (qh PREmerge) qh_fprintf(fp, 9354, "\
%6.2g radius of pre-merge centrum\n", qh premerge_centrum);
if (qh postmerge_cos < REALmax/2) qh_fprintf(fp, 9355, "\
%6.2g max. cosine for post-merge angle\n", qh postmerge_cos);
if (qh POSTmerge) qh_fprintf(fp, 9356, "\
%6.2g radius of post-merge centrum\n", qh postmerge_centrum);
qh_fprintf(fp, 9357, "\
%6.2g max. distance for merging two simplicial facets\n\
%6.2g max. roundoff error for arithmetic operations\n\
%6.2g min. denominator for divisions\n\
zero diagonal for Gauss: ", qh ONEmerge, REALepsilon, qh MINdenom);
for(k=0; k < qh hull_dim; k++)
qh_fprintf(fp, 9358, "%6.2e ", qh NEARzero[k]);
qh_fprintf(fp, 9359, "\n\n");
for(i=0 ; i < qhstat next; )
qh_printstats(fp, i, &i);
} /* printstatistics */
#endif /* qh_KEEPstatistics */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstatlevel">-</a>
qh_printstatlevel( fp, id )
print level information for a statistic
notes:
nop if id >= ZEND, printed, or same as initial value
*/
void qh_printstatlevel(FILE *fp, int id) {
#define NULLfield " "
if (id >= ZEND || qhstat printed[id])
return;
if (qhstat type[id] == zdoc) {
qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]);
return;
}
if (qh_nostatistic(id) || !qhstat doc[id])
return;
qhstat printed[id]= True;
if (qhstat count[id] != -1
&& qhstat stats[(unsigned char)(qhstat count[id])].i == 0)
qh_fprintf(fp, 9361, " *0 cnt*");
else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1)
qh_fprintf(fp, 9362, "%7.2g", qhstat stats[id].r);
else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1)
qh_fprintf(fp, 9363, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i);
else if (qhstat type[id] < ZTYPEreal && qhstat count[id] == -1)
qh_fprintf(fp, 9364, "%7d", qhstat stats[id].i);
else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1)
qh_fprintf(fp, 9365, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i);
qh_fprintf(fp, 9366, " %s\n", qhstat doc[id]);
} /* printstatlevel */
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="printstats">-</a>
qh_printstats( fp, index, nextindex )
print statistics for a zdoc group
returns:
next zdoc if non-null
*/
void qh_printstats(FILE *fp, int idx, int *nextindex) {
int j, nexti;
if (qh_newstats(idx, &nexti)) {
qh_fprintf(fp, 9367, "\n");
for (j=idx; j<nexti; j++)
qh_printstatlevel(fp, qhstat id[j]);
}
if (nextindex)
*nextindex= nexti;
} /* printstats */
#if qh_KEEPstatistics
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="stddev">-</a>
qh_stddev( num, tot, tot2, ave )
compute the standard deviation and average from statistics
tot2 is the sum of the squares
notes:
computes r.m.s.:
(x-ave)^2
== x^2 - 2x tot/num + (tot/num)^2
== tot2 - 2 tot tot/num + tot tot/num
== tot2 - tot ave
*/
realT qh_stddev(int num, realT tot, realT tot2, realT *ave) {
realT stddev;
*ave= tot/num;
stddev= sqrt(tot2/num - *ave * *ave);
return stddev;
} /* stddev */
#endif /* qh_KEEPstatistics */
#if !qh_KEEPstatistics
void qh_collectstatistics(void) {}
void qh_printallstatistics(FILE *fp, char *string) {};
void qh_printstatistics(FILE *fp, char *string) {}
#endif

View File

@@ -0,0 +1,543 @@
/*<html><pre> -<a href="qh-stat.htm"
>-------------------------------</a><a name="TOP">-</a>
stat.h
contains all statistics that are collected for qhull
see qh-stat.htm and stat.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull/stat.h#4 $$Change: 2062 $
$DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
recompile qhull if you change this file
Integer statistics are Z* while real statistics are W*.
define maydebugx to call a routine at every statistic event
*/
#ifndef qhDEFstat
#define qhDEFstat 1
#include "libqhull.h"
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
*/
#ifndef qh_KEEPstatistics
#define qh_KEEPstatistics 1
#endif
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="statistics">-</a>
Zxxx for integers, Wxxx for reals
notes:
be sure that all statistics are defined in stat.c
otherwise initialization may core dump
can pick up all statistics by:
grep '[zw].*_[(][ZW]' *.c >z.x
remove trailers with query">-</a>
remove leaders with query-replace-regexp [ ^I]+ (
*/
#if qh_KEEPstatistics
enum qh_statistics { /* alphabetical after Z/W */
Zacoplanar,
Wacoplanarmax,
Wacoplanartot,
Zangle,
Wangle,
Wanglemax,
Wanglemin,
Zangletests,
Wareatot,
Wareamax,
Wareamin,
Zavoidold,
Wavoidoldmax,
Wavoidoldtot,
Zback0,
Zbestcentrum,
Zbestdist,
Zbestlower,
Zbestlowerall,
Zbestloweralln,
Zbestlowerv,
Zcentrumtests,
Zcheckpart,
Zcomputefurthest,
Zconcave,
Wconcavemax,
Wconcavetot,
Zconcaveridges,
Zconcaveridge,
Zcoplanar,
Wcoplanarmax,
Wcoplanartot,
Zcoplanarangle,
Zcoplanarcentrum,
Zcoplanarhorizon,
Zcoplanarinside,
Zcoplanarpart,
Zcoplanarridges,
Wcpu,
Zcyclefacetmax,
Zcyclefacettot,
Zcyclehorizon,
Zcyclevertex,
Zdegen,
Wdegenmax,
Wdegentot,
Zdegenvertex,
Zdelfacetdup,
Zdelridge,
Zdelvertextot,
Zdelvertexmax,
Zdetsimplex,
Zdistcheck,
Zdistconvex,
Zdistgood,
Zdistio,
Zdistplane,
Zdiststat,
Zdistvertex,
Zdistzero,
Zdoc1,
Zdoc2,
Zdoc3,
Zdoc4,
Zdoc5,
Zdoc6,
Zdoc7,
Zdoc8,
Zdoc9,
Zdoc10,
Zdoc11,
Zdoc12,
Zdropdegen,
Zdropneighbor,
Zdupflip,
Zduplicate,
Wduplicatemax,
Wduplicatetot,
Zdupridge,
Zdupsame,
Zflipped,
Wflippedmax,
Wflippedtot,
Zflippedfacets,
Zfindbest,
Zfindbestmax,
Zfindbesttot,
Zfindcoplanar,
Zfindfail,
Zfindhorizon,
Zfindhorizonmax,
Zfindhorizontot,
Zfindjump,
Zfindnew,
Zfindnewmax,
Zfindnewtot,
Zfindnewjump,
Zfindnewsharp,
Zgauss0,
Zgoodfacet,
Zhashlookup,
Zhashridge,
Zhashridgetest,
Zhashtests,
Zinsidevisible,
Zintersect,
Zintersectfail,
Zintersectmax,
Zintersectnum,
Zintersecttot,
Zmaxneighbors,
Wmaxout,
Wmaxoutside,
Zmaxridges,
Zmaxvertex,
Zmaxvertices,
Zmaxvneighbors,
Zmemfacets,
Zmempoints,
Zmemridges,
Zmemvertices,
Zmergeflipdup,
Zmergehorizon,
Zmergeinittot,
Zmergeinitmax,
Zmergeinittot2,
Zmergeintohorizon,
Zmergenew,
Zmergesettot,
Zmergesetmax,
Zmergesettot2,
Zmergesimplex,
Zmergevertex,
Wmindenom,
Wminvertex,
Zminnorm,
Zmultiridge,
Znearlysingular,
Zneighbor,
Wnewbalance,
Wnewbalance2,
Znewfacettot,
Znewfacetmax,
Znewvertex,
Wnewvertex,
Wnewvertexmax,
Znoarea,
Znonsimplicial,
Znowsimplicial,
Znotgood,
Znotgoodnew,
Znotmax,
Znumfacets,
Znummergemax,
Znummergetot,
Znumneighbors,
Znumridges,
Znumvertices,
Znumvisibility,
Znumvneighbors,
Zonehorizon,
Zpartangle,
Zpartcoplanar,
Zpartflip,
Zparthorizon,
Zpartinside,
Zpartition,
Zpartitionall,
Zpartnear,
Zpbalance,
Wpbalance,
Wpbalance2,
Zpostfacets,
Zpremergetot,
Zprocessed,
Zremvertex,
Zremvertexdel,
Zrenameall,
Zrenamepinch,
Zrenameshare,
Zretry,
Wretrymax,
Zridge,
Wridge,
Wridgemax,
Zridge0,
Wridge0,
Wridge0max,
Zridgemid,
Wridgemid,
Wridgemidmax,
Zridgeok,
Wridgeok,
Wridgeokmax,
Zsearchpoints,
Zsetplane,
Ztestvneighbor,
Ztotcheck,
Ztothorizon,
Ztotmerge,
Ztotpartcoplanar,
Ztotpartition,
Ztotridges,
Ztotvertices,
Ztotvisible,
Ztricoplanar,
Ztricoplanarmax,
Ztricoplanartot,
Ztridegen,
Ztrimirror,
Ztrinull,
Wvertexmax,
Wvertexmin,
Zvertexridge,
Zvertexridgetot,
Zvertexridgemax,
Zvertices,
Zvisfacettot,
Zvisfacetmax,
Zvisit,
Zvisit2max,
Zvisvertextot,
Zvisvertexmax,
Zvvisit,
Zvvisit2max,
Zwidefacet,
Zwidevertices,
ZEND};
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="ZZstat">-</a>
Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
notes:
be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
*/
#else
enum qh_statistics { /* for zzdef etc. macros */
Zback0,
Zbestdist,
Zcentrumtests,
Zcheckpart,
Zconcaveridges,
Zcoplanarhorizon,
Zcoplanarpart,
Zcoplanarridges,
Zcyclefacettot,
Zcyclehorizon,
Zdelvertextot,
Zdistcheck,
Zdistconvex,
Zdistzero,
Zdoc1,
Zdoc2,
Zdoc3,
Zdoc11,
Zflippedfacets,
Zgauss0,
Zminnorm,
Zmultiridge,
Znearlysingular,
Wnewvertexmax,
Znumvisibility,
Zpartcoplanar,
Zpartition,
Zpartitionall,
Zprocessed,
Zretry,
Zridge,
Wridge,
Wridgemax,
Zridge0,
Wridge0,
Wridge0max,
Zridgemid,
Wridgemid,
Wridgemidmax,
Zridgeok,
Wridgeok,
Wridgeokmax,
Zsetplane,
Ztotcheck,
Ztotmerge,
ZEND};
#endif
/*-<a href="qh-stat.htm#TOC"
>-------------------------------</a><a name="ztype">-</a>
ztype
the type of a statistic sets its initial value.
notes:
The type should be the same as the macro for collecting the statistic
*/
enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
/*========== macros and constants =============*/
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="MAYdebugx">-</a>
MAYdebugx
define as maydebug() to be called frequently for error trapping
*/
#define MAYdebugx
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zdef_">-</a>
zzdef_, zdef_( type, name, doc, -1)
define a statistic (assumes 'qhstat.next= 0;')
zdef_( type, name, doc, count)
define an averaged statistic
printed as name/count
*/
#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
#if qh_KEEPstatistics
#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
#else
#define zdef_(type,name,doc,count)
#endif
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zinc_">-</a>
zzinc_( name ), zinc_( name)
increment an integer statistic
*/
#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
#if qh_KEEPstatistics
#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
#else
#define zinc_(id) {}
#endif
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zadd_">-</a>
zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
add value to an integer or real statistic
*/
#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
#if qh_KEEPstatistics
#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
#else
#define zadd_(id, val) {}
#define wadd_(id, val) {}
#endif
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zval_">-</a>
zzval_( name ), zval_( name ), wwval_( name )
set or return value of a statistic
*/
#define zzval_(id) ((qhstat stats[id]).i)
#define wwval_(id) ((qhstat stats[id]).r)
#if qh_KEEPstatistics
#define zval_(id) ((qhstat stats[id]).i)
#define wval_(id) ((qhstat stats[id]).r)
#else
#define zval_(id) qhstat tempi
#define wval_(id) qhstat tempr
#endif
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zmax_">-</a>
zmax_( id, val ), wmax_( id, value )
maximize id with val
*/
#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
#if qh_KEEPstatistics
#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
#else
#define zmax_(id, val) {}
#define wmax_(id, val) {}
#endif
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="zmin_">-</a>
zmin_( id, val ), wmin_( id, value )
minimize id with val
*/
#if qh_KEEPstatistics
#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
#else
#define zmin_(id, val) {}
#define wmin_(id, val) {}
#endif
/*================== stat.h types ==============*/
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="intrealT">-</a>
intrealT
union of integer and real, used for statistics
*/
typedef union intrealT intrealT; /* union of int and realT */
union intrealT {
int i;
realT r;
};
/*-<a href="qh-stat.htm#TOC"
>--------------------------------</a><a name="qhstat">-</a>
qhstat
global data structure for statistics, similar to qh and qhrbox
notes:
access to qh_qhstat is via the "qhstat" macro. There are two choices
qh_QHpointer = 1 access globals via a pointer
enables qh_saveqhull() and qh_restoreqhull()
= 0 qh_qhstat is a static data structure
only one instance of qhull() can be active at a time
default value
qh_QHpointer is defined in libqhull.h
qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
allocated in stat.c using qh_malloc()
*/
#ifndef DEFqhstatT
#define DEFqhstatT 1
typedef struct qhstatT qhstatT;
#endif
#if qh_QHpointer_dllimport
#define qhstat qh_qhstat->
__declspec(dllimport) extern qhstatT *qh_qhstat;
#elif qh_QHpointer
#define qhstat qh_qhstat->
extern qhstatT *qh_qhstat;
#elif qh_dllimport
#define qhstat qh_qhstat.
__declspec(dllimport) extern qhstatT qh_qhstat;
#else
#define qhstat qh_qhstat.
extern qhstatT qh_qhstat;
#endif
struct qhstatT {
intrealT stats[ZEND]; /* integer and real statistics */
unsigned char id[ZEND+10]; /* id's in print order */
const char *doc[ZEND]; /* array of documentation strings */
short int count[ZEND]; /* -1 if none, else index of count to use */
char type[ZEND]; /* type, see ztypes above */
char printed[ZEND]; /* true, if statistic has been printed */
intrealT init[ZTYPEend]; /* initial values by types, set initstatistics */
int next; /* next index for zdef_ */
int precision; /* index for precision problems */
int vridges; /* index for Voronoi ridges */
int tempi;
realT tempr;
};
/*========== function prototypes ===========*/
void qh_allstatA(void);
void qh_allstatB(void);
void qh_allstatC(void);
void qh_allstatD(void);
void qh_allstatE(void);
void qh_allstatE2(void);
void qh_allstatF(void);
void qh_allstatG(void);
void qh_allstatH(void);
void qh_allstatI(void);
void qh_allstatistics(void);
void qh_collectstatistics(void);
void qh_freestatistics(void);
void qh_initstatistics(void);
boolT qh_newstats(int idx, int *nextindex);
boolT qh_nostatistic(int i);
void qh_printallstatistics(FILE *fp, const char *string);
void qh_printstatistics(FILE *fp, const char *string);
void qh_printstatlevel(FILE *fp, int id);
void qh_printstats(FILE *fp, int idx, int *nextindex);
realT qh_stddev(int num, realT tot, realT tot2, realT *ave);
#endif /* qhDEFstat */

View File

@@ -0,0 +1,538 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
user.c
user redefinable functions
see user2.c for qh_fprintf, qh_malloc, qh_free
see README.txt see COPYING.txt for copyright information.
see libqhull.h for data structures, macros, and user-callable functions.
see user_eg.c, user_eg2.c, and unix.c for examples.
see user.h for user-definable constants
use qh_NOmem in mem.h to turn off memory management
use qh_NOmerge in user.h to turn off facet merging
set qh_KEEPstatistics in user.h to 0 to turn off statistics
This is unsupported software. You're welcome to make changes,
but you're on your own if something goes wrong. Use 'Tc' to
check frequently. Usually qhull will report an error if
a data structure becomes inconsistent. If so, it also reports
the last point added to the hull, e.g., 102. You can then trace
the execution of qhull with "T4P102".
Please report any errors that you fix to qhull@qhull.org
Qhull-template is a template for calling qhull from within your application
if you recompile and load this module, then user.o will not be loaded
from qhull.a
you can add additional quick allocation sizes in qh_user_memsizes
if the other functions here are redefined to not use qh_print...,
then io.o will not be loaded from qhull.a. See user_eg.c for an
example. We recommend keeping io.o for the extra debugging
information it supplies.
*/
#include "qhull_a.h"
#include <stdarg.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qhull_template">-</a>
Qhull-template
Template for calling qhull from inside your program
returns:
exit code(see qh_ERR... in libqhull.h)
all memory freed
notes:
This can be called any number of times.
*/
#if 0
{
int dim; /* dimension of points */
int numpoints; /* number of points */
coordT *points; /* array of coordinates for each point */
boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= stdout; /* output from qh_produce_output()
use NULL to skip qh_produce_output() */
FILE *errfile= stderr; /* error messages from qhull code */
int exitcode; /* 0 if no error from qhull */
facetT *facet; /* set by FORALLfacets */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
QHULL_LIB_CHECK /* Check for compatible library */
#if qh_QHpointer /* see user.h */
if (qh_qh){ /* should be NULL */
qh_printf_stderr(6238, "Qhull link error. The global variable qh_qh was not initialized\n\
to NULL by global.c. Please compile this program with -Dqh_QHpointer_dllimport\n\
as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
exit(1);
}
#endif
/* initialize dim, numpoints, points[], ismalloc here */
exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
flags, outfile, errfile);
if (!exitcode) { /* if no error */
/* 'qh facet_list' contains the convex hull */
FORALLfacets {
/* ... your code ... */
}
}
qh_freeqhull(!qh_ALL);
qh_memfreeshort(&curlong, &totlong);
if (curlong || totlong)
qh_fprintf(errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
}
#endif
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="new_qhull">-</a>
qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
build new qhull data structure and return exitcode (0 if no errors)
if numpoints=0 and points=NULL, initializes qhull
notes:
do not modify points until finished with results.
The qhull data structure contains pointers into the points array.
do not call qhull functions before qh_new_qhull().
The qhull data structure is not initialized until qh_new_qhull().
Default errfile is stderr, outfile may be null
qhull_cmd must start with "qhull "
projects points to a new point array for Delaunay triangulations ('d' and 'v')
transforms points into a new point array for halfspace intersection ('H')
To allow multiple, concurrent calls to qhull()
- set qh_QHpointer in user.h
- use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
- use qh_freeqhull(qh_ALL) to free intermediate convex hulls
see:
Qhull-template at the beginning of this file.
An example of using qh_new_qhull is user_eg.c
*/
int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
char *qhull_cmd, FILE *outfile, FILE *errfile) {
/* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
These parameters are not referenced after a longjmp() and hence not clobbered.
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
int exitcode, hulldim;
boolT new_ismalloc;
static boolT firstcall = True;
coordT *new_points;
if(!errfile){
errfile= stderr;
}
if (firstcall) {
qh_meminit(errfile);
firstcall= False;
} else {
qh_memcheck();
}
if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
qh_fprintf(errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
return qh_ERRinput;
}
qh_initqhull_start(NULL, outfile, errfile);
if(numpoints==0 && points==NULL){
trace1((qh ferr, 1047, "qh_new_qhull: initialize Qhull\n"));
return 0;
}
trace1((qh ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
exitcode = setjmp(qh errexit);
if (!exitcode)
{
qh NOerrexit = False;
qh_initflags(qhull_cmd);
if (qh DELAUNAY)
qh PROJECTdelaunay= True;
if (qh HALFspace) {
/* points is an array of halfspaces,
the last coordinate of each halfspace is its offset */
hulldim= dim-1;
qh_setfeasible(hulldim);
new_points= qh_sethalfspace_all(dim, numpoints, points, qh feasible_point);
new_ismalloc= True;
if (ismalloc)
qh_free(points);
}else {
hulldim= dim;
new_points= points;
new_ismalloc= ismalloc;
}
qh_init_B(new_points, numpoints, hulldim, new_ismalloc);
qh_qhull();
qh_check_output();
if (outfile) {
qh_produce_output();
}else {
qh_prepare_output();
}
if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
qh_check_points();
}
qh NOerrexit = True;
return exitcode;
} /* new_qhull */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="errexit">-</a>
qh_errexit( exitcode, facet, ridge )
report and exit from an error
report facet and ridge if non-NULL
reports useful information such as last point processed
set qh.FORCEoutput to print neighborhood of facet
see:
qh_errexit2() in libqhull.c for printing 2 facets
design:
check for error within error processing
compute qh.hulltime
print facet and ridge (if any)
report commandString, options, qh.furthest_id
print summary and statistics (including precision statistics)
if qh_ERRsingular
print help text for singular data set
exit program via long jump (if defined) or exit()
*/
void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
if (qh ERREXITcalled) {
qh_fprintf(qh ferr, 8126, "\nqhull error while processing previous error. Exit program\n");
qh_exit(qh_ERRqhull);
}
qh ERREXITcalled= True;
if (!qh QHULLfinished)
qh hulltime= qh_CPUclock - qh hulltime;
qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
qh_fprintf(qh ferr, 8127, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
qh_fprintf(qh ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
if (qh furthest_id >= 0) {
qh_fprintf(qh ferr, 8129, "Last point added to hull was p%d.", qh furthest_id);
if (zzval_(Ztotmerge))
qh_fprintf(qh ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge));
if (qh QHULLfinished)
qh_fprintf(qh ferr, 8131, "\nQhull has finished constructing the hull.");
else if (qh POSTmerging)
qh_fprintf(qh ferr, 8132, "\nQhull has started post-merging.");
qh_fprintf(qh ferr, 8133, "\n");
}
if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
qh_produce_output();
else if (exitcode != qh_ERRinput) {
if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
qh_fprintf(qh ferr, 8134, "\nAt error exit:\n");
qh_printsummary(qh ferr);
if (qh PRINTstatistics) {
qh_collectstatistics();
qh_printstatistics(qh ferr, "at error exit");
qh_memstatistics(qh ferr);
}
}
if (qh PRINTprecision)
qh_printstats(qh ferr, qhstat precision, NULL);
}
if (!exitcode)
exitcode= qh_ERRqhull;
else if (exitcode == qh_ERRsingular)
qh_printhelp_singular(qh ferr);
else if (exitcode == qh_ERRprec && !qh PREmerge)
qh_printhelp_degenerate(qh ferr);
if (qh NOerrexit) {
qh_fprintf(qh ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
qh_exit(qh_ERRqhull);
}
qh ERREXITcalled= False;
qh NOerrexit= True;
qh ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
longjmp(qh errexit, exitcode);
} /* errexit */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="errprint">-</a>
qh_errprint( fp, string, atfacet, otherfacet, atridge, atvertex )
prints out the information of facets and ridges to fp
also prints neighbors and geomview output
notes:
except for string, any parameter may be NULL
*/
void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
int i;
if (atfacet) {
qh_fprintf(qh ferr, 8135, "%s FACET:\n", string);
qh_printfacet(qh ferr, atfacet);
}
if (otherfacet) {
qh_fprintf(qh ferr, 8136, "%s OTHER FACET:\n", string);
qh_printfacet(qh ferr, otherfacet);
}
if (atridge) {
qh_fprintf(qh ferr, 8137, "%s RIDGE:\n", string);
qh_printridge(qh ferr, atridge);
if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
qh_printfacet(qh ferr, atridge->top);
if (atridge->bottom
&& atridge->bottom != atfacet && atridge->bottom != otherfacet)
qh_printfacet(qh ferr, atridge->bottom);
if (!atfacet)
atfacet= atridge->top;
if (!otherfacet)
otherfacet= otherfacet_(atridge, atfacet);
}
if (atvertex) {
qh_fprintf(qh ferr, 8138, "%s VERTEX:\n", string);
qh_printvertex(qh ferr, atvertex);
}
if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
qh_fprintf(qh ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
for (i=0; i < qh_PRINTEND; i++) /* use fout for geomview output */
qh_printneighborhood(qh fout, qh PRINTout[i], atfacet, otherfacet,
!qh_ALL);
}
} /* errprint */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="printfacetlist">-</a>
qh_printfacetlist( fp, facetlist, facets, printall )
print all fields for a facet list and/or set of facets to fp
if !printall,
only prints good facets
notes:
also prints all vertices
*/
void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
facetT *facet, **facetp;
qh_printbegin(qh ferr, qh_PRINTfacets, facetlist, facets, printall);
FORALLfacet_(facetlist)
qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
FOREACHfacet_(facets)
qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
qh_printend(qh ferr, qh_PRINTfacets, facetlist, facets, printall);
} /* printfacetlist */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_degenerate">-</a>
qh_printhelp_degenerate( fp )
prints descriptive message for precision error
notes:
no message if qh_QUICKhelp
*/
void qh_printhelp_degenerate(FILE *fp) {
if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
qh_fprintf(fp, 9368, "\n\
A Qhull error has occurred. Qhull should have corrected the above\n\
precision error. Please send the input and all of the output to\n\
qhull_bug@qhull.org\n");
else if (!qh_QUICKhelp) {
qh_fprintf(fp, 9369, "\n\
Precision problems were detected during construction of the convex hull.\n\
This occurs because convex hull algorithms assume that calculations are\n\
exact, but floating-point arithmetic has roundoff errors.\n\
\n\
To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
in Qhull\" (qh-impre.htm).\n\
\n\
If you use 'Q0', the output may include\n\
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
Qhull may produce a ridge with four neighbors or two facets with the same \n\
vertices. Qhull reports these events when they occur. It stops when a\n\
concave ridge, flipped facet, or duplicate facet occurs.\n");
#if REALfloat
qh_fprintf(fp, 9370, "\
\n\
Qhull is currently using single precision arithmetic. The following\n\
will probably remove the precision problems:\n\
- recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
#endif
if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
qh_fprintf(fp, 9371, "\
\n\
When computing the Delaunay triangulation of coordinates > 1.0,\n\
- use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
if (qh DELAUNAY && !qh ATinfinity)
qh_fprintf(fp, 9372, "\
When computing the Delaunay triangulation:\n\
- use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
qh_fprintf(fp, 9373, "\
\n\
If you need triangular output:\n\
- use option 'Qt' to triangulate the output\n\
- use option 'QJ' to joggle the input points and remove precision errors\n\
- use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
\n\
If you must use 'Q0',\n\
try one or more of the following options. They can not guarantee an output.\n\
- use 'QbB' to scale the input to a cube.\n\
- use 'Po' to produce output and prevent partitioning for flipped facets\n\
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
- options 'Qf', 'Qbb', and 'QR0' may also help\n",
qh DISTround);
qh_fprintf(fp, 9374, "\
\n\
To guarantee simplicial output:\n\
- use option 'Qt' to triangulate the output\n\
- use option 'QJ' to joggle the input points and remove precision errors\n\
- use option 'Ft' to triangulate the output by adding points\n\
- use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
");
}
} /* printhelp_degenerate */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="printhelp_narrowhull">-</a>
qh_printhelp_narrowhull( minangle )
Warn about a narrow hull
notes:
Alternatively, reduce qh_WARNnarrow in user.h
*/
void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
qh_fprintf(fp, 9375, "qhull precision warning: \n\
The initial hull is narrow (cosine of min. angle is %.16f).\n\
Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may\n\
produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
last coordinate) may remove this warning. Use 'Pp' to skip this warning.\n\
See 'Limitations' in qh-impre.htm.\n",
-minangle); /* convert from angle between normals to angle between facets */
} /* printhelp_narrowhull */
/*-<a href="qh-io.htm#TOC"
>-------------------------------</a><a name="printhelp_singular">-</a>
qh_printhelp_singular( fp )
prints descriptive message for singular input
*/
void qh_printhelp_singular(FILE *fp) {
facetT *facet;
vertexT *vertex, **vertexp;
realT min, max, *coord, dist;
int i,k;
qh_fprintf(fp, 9376, "\n\
The input to qhull appears to be less than %d dimensional, or a\n\
computation has overflowed.\n\n\
Qhull could not construct a clearly convex simplex from points:\n",
qh hull_dim);
qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
if (!qh_QUICKhelp)
qh_fprintf(fp, 9377, "\n\
The center point is coplanar with a facet, or a vertex is coplanar\n\
with a neighboring facet. The maximum round off error for\n\
computing distances is %2.2g. The center point, facets and distances\n\
to the center point are as follows:\n\n", qh DISTround);
qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, qh_IDunknown);
qh_fprintf(fp, 9378, "\n");
FORALLfacets {
qh_fprintf(fp, 9379, "facet");
FOREACHvertex_(facet->vertices)
qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
zinc_(Zdistio);
qh_distplane(qh interior_point, facet, &dist);
qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
}
if (!qh_QUICKhelp) {
if (qh HALFspace)
qh_fprintf(fp, 9382, "\n\
These points are the dual of the given halfspaces. They indicate that\n\
the intersection is degenerate.\n");
qh_fprintf(fp, 9383,"\n\
These points either have a maximum or minimum x-coordinate, or\n\
they maximize the determinant for k coordinates. Trial points\n\
are first selected from points that maximize a coordinate.\n");
if (qh hull_dim >= qh_INITIALmax)
qh_fprintf(fp, 9384, "\n\
Because of the high dimension, the min x-coordinate and max-coordinate\n\
points are used if the determinant is non-zero. Option 'Qs' will\n\
do a better, though much slower, job. Instead of 'Qs', you can change\n\
the points by randomly rotating the input with 'QR0'.\n");
}
qh_fprintf(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
for (k=0; k < qh hull_dim; k++) {
min= REALmax;
max= -REALmin;
for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
maximize_(max, *coord);
minimize_(min, *coord);
}
qh_fprintf(fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
}
if (!qh_QUICKhelp) {
qh_fprintf(fp, 9387, "\n\
If the input should be full dimensional, you have several options that\n\
may determine an initial simplex:\n\
- use 'QJ' to joggle the input and make it full dimensional\n\
- use 'QbB' to scale the points to the unit cube\n\
- use 'QR0' to randomly rotate the input for different maximum points\n\
- use 'Qs' to search all points for the initial simplex\n\
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
- trace execution with 'T3' to see the determinant for each point.\n",
qh DISTround);
#if REALfloat
qh_fprintf(fp, 9388, "\
- recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
#endif
qh_fprintf(fp, 9389, "\n\
If the input is lower dimensional:\n\
- use 'QJ' to joggle the input and make it full dimensional\n\
- use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
pick the coordinate with the least range. The hull will have the\n\
correct topology.\n\
- determine the flat containing the points, rotate the points\n\
into a coordinate plane, and delete the other coordinates.\n\
- add one or more points to make the input full dimensional.\n\
");
}
} /* printhelp_singular */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="user_memsizes">-</a>
qh_user_memsizes()
allocate up to 10 additional, quick allocation sizes
notes:
increase maximum number of allocations in qh_initqhull_mem()
*/
void qh_user_memsizes(void) {
/* qh_memsize(size); */
} /* user_memsizes */

View File

@@ -0,0 +1,909 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
user.h
user redefinable constants
for each source file, user.h is included first
see qh-user.htm. see COPYING for copyright information.
See user.c for sample code.
before reading any code, review libqhull.h for data structure definitions and
the "qh" macro.
Sections:
============= qhull library constants ======================
============= data types and configuration macros ==========
============= performance related constants ================
============= memory constants =============================
============= joggle constants =============================
============= conditional compilation ======================
============= -merge constants- ============================
Code flags --
NOerrors -- the code does not call qh_errexit()
WARN64 -- the code may be incompatible with 64-bit pointers
*/
#include <time.h>
#ifndef qhDEFuser
#define qhDEFuser 1
/* Derived from Qt's corelib/global/qglobal.h */
#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
# define QHULL_OS_WIN
#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
# define QHULL_OS_WIN
#endif
/*============================================================*/
/*============= qhull library constants ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="filenamelen">-</a>
FILENAMElen -- max length for TI and TO filenames
*/
#define qh_FILENAMElen 500
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="msgcode">-</a>
msgcode -- Unique message codes for qh_fprintf
If add new messages, assign these values and increment in user.h and user_r.h
See QhullError.h for 10000 errors.
def counters = [27, 1048, 2059, 3026, 4068, 5003,
6273, 7081, 8147, 9411, 10000, 11029]
See: qh_ERR* [libqhull.h]
*/
#define MSG_TRACE0 0
#define MSG_TRACE1 1000
#define MSG_TRACE2 2000
#define MSG_TRACE3 3000
#define MSG_TRACE4 4000
#define MSG_TRACE5 5000
#define MSG_ERROR 6000 /* errors written to qh.ferr */
#define MSG_WARNING 7000
#define MSG_STDERR 8000 /* log messages Written to qh.ferr */
#define MSG_OUTPUT 9000
#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
#define MSG_FIXUP 11000 /* FIXUP QH11... */
#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="qh_OPTIONline">-</a>
qh_OPTIONline -- max length of an option line 'FO'
*/
#define qh_OPTIONline 80
/*============================================================*/
/*============= data types and configuration macros ==========*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="realT">-</a>
realT
set the size of floating point numbers
qh_REALdigits
maximimum number of significant digits
qh_REAL_1, qh_REAL_2n, qh_REAL_3n
format strings for printf
qh_REALmax, qh_REALmin
maximum and minimum (near zero) values
qh_REALepsilon
machine roundoff. Maximum roundoff error for addition and multiplication.
notes:
Select whether to store floating point numbers in single precision (float)
or double precision (double).
Use 'float' to save about 8% in time and 25% in space. This is particularly
helpful if high-d where convex hulls are space limited. Using 'float' also
reduces the printed size of Qhull's output since numbers have 8 digits of
precision.
Use 'double' when greater arithmetic precision is needed. This is needed
for Delaunay triangulations and Voronoi diagrams when you are not merging
facets.
If 'double' gives insufficient precision, your data probably includes
degeneracies. If so you should use facet merging (done by default)
or exact arithmetic (see imprecision section of manual, qh-impre.htm).
You may also use option 'Po' to force output despite precision errors.
You may use 'long double', but many format statements need to be changed
and you may need a 'long double' square root routine. S. Grundmann
(sg@eeiwzb.et.tu-dresden.de) has done this. He reports that the code runs
much slower with little gain in precision.
WARNING: on some machines, int f(){realT a= REALmax;return (a == REALmax);}
returns False. Use (a > REALmax/2) instead of (a == REALmax).
REALfloat = 1 all numbers are 'float' type
= 0 all numbers are 'double' type
*/
#define REALfloat 0
#if (REALfloat == 1)
#define realT float
#define REALmax FLT_MAX
#define REALmin FLT_MIN
#define REALepsilon FLT_EPSILON
#define qh_REALdigits 8 /* maximum number of significant digits */
#define qh_REAL_1 "%6.8g "
#define qh_REAL_2n "%6.8g %6.8g\n"
#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
#elif (REALfloat == 0)
#define realT double
#define REALmax DBL_MAX
#define REALmin DBL_MIN
#define REALepsilon DBL_EPSILON
#define qh_REALdigits 16 /* maximum number of significant digits */
#define qh_REAL_1 "%6.16g "
#define qh_REAL_2n "%6.16g %6.16g\n"
#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
#else
#error unknown float option
#endif
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="CPUclock">-</a>
qh_CPUclock
define the clock() function for reporting the total time spent by Qhull
returns CPU ticks as a 'long int'
qh_CPUclock is only used for reporting the total time spent by Qhull
qh_SECticks
the number of clock ticks per second
notes:
looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
to define a custom clock, set qh_CLOCKtype to 0
if your system does not use clock() to return CPU ticks, replace
qh_CPUclock with the corresponding function. It is converted
to 'unsigned long' to prevent wrap-around during long runs. By default,
<time.h> defines clock_t as 'long'
Set qh_CLOCKtype to
1 for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
Note: may fail if more than 1 hour elapsed time
2 use qh_clock() with POSIX times() (see global.c)
*/
#define qh_CLOCKtype 1 /* change to the desired number */
#if (qh_CLOCKtype == 1)
#if defined(CLOCKS_PER_SECOND)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLOCKS_PER_SECOND
#elif defined(CLOCKS_PER_SEC)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLOCKS_PER_SEC
#elif defined(CLK_TCK)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLK_TCK
#else
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks 1E6
#endif
#elif (qh_CLOCKtype == 2)
#define qh_CPUclock qh_clock() /* return CPU clock */
#define qh_SECticks 100
#else /* qh_CLOCKtype == ? */
#error unknown clock option
#endif
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RANDOM">-</a>
qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
define random number generator
qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.
qh_RANDOMseed sets the random number seed for qh_RANDOMint
Set qh_RANDOMtype (default 5) to:
1 for random() with 31 bits (UCB)
2 for rand() with RAND_MAX or 15 bits (system 5)
3 for rand() with 31 bits (Sun)
4 for lrand48() with 31 bits (Solaris)
5 for qh_rand() with 31 bits (included with Qhull)
notes:
Random numbers are used by rbox to generate point sets. Random
numbers are used by Qhull to rotate the input ('QRn' option),
simulate a randomized algorithm ('Qr' option), and to simulate
roundoff errors ('Rn' option).
Random number generators differ between systems. Most systems provide
rand() but the period varies. The period of rand() is not critical
since qhull does not normally use random numbers.
The default generator is Park & Miller's minimal standard random
number generator [CACM 31:1195 '88]. It is included with Qhull.
If qh_RANDOMmax is wrong, qhull will report a warning and Geomview
output will likely be invisible.
*/
#define qh_RANDOMtype 5 /* *** change to the desired number *** */
#if (qh_RANDOMtype == 1)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, random()/MAX */
#define qh_RANDOMint random()
#define qh_RANDOMseed_(seed) srandom(seed);
#elif (qh_RANDOMtype == 2)
#ifdef RAND_MAX
#define qh_RANDOMmax ((realT)RAND_MAX)
#else
#define qh_RANDOMmax ((realT)32767) /* 15 bits (System 5) */
#endif
#define qh_RANDOMint rand()
#define qh_RANDOMseed_(seed) srand((unsigned)seed);
#elif (qh_RANDOMtype == 3)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, Sun */
#define qh_RANDOMint rand()
#define qh_RANDOMseed_(seed) srand((unsigned)seed);
#elif (qh_RANDOMtype == 4)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, lrand38()/MAX */
#define qh_RANDOMint lrand48()
#define qh_RANDOMseed_(seed) srand48(seed);
#elif (qh_RANDOMtype == 5)
#define qh_RANDOMmax ((realT)2147483646UL) /* 31 bits, qh_rand/MAX */
#define qh_RANDOMint qh_rand()
#define qh_RANDOMseed_(seed) qh_srand(seed);
/* unlike rand(), never returns 0 */
#else
#error: unknown random option
#endif
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ORIENTclock">-</a>
qh_ORIENTclock
0 for inward pointing normals by Geomview convention
*/
#define qh_ORIENTclock 0
/*============================================================*/
/*============= joggle constants =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEdefault">-</a>
qh_JOGGLEdefault
default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
notes:
rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
the later have about 20 points per facet, each of which may interfere
pick a value large enough to avoid retries on most inputs
*/
#define qh_JOGGLEdefault 30000.0
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEincrease">-</a>
qh_JOGGLEincrease
factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
*/
#define qh_JOGGLEincrease 10.0
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEretry">-</a>
qh_JOGGLEretry
if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
notes:
try twice at the original value in case of bad luck the first time
*/
#define qh_JOGGLEretry 2
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEagain">-</a>
qh_JOGGLEagain
every following qh_JOGGLEagain, increase qh.JOGGLEmax
notes:
1 is OK since it's already failed qh_JOGGLEretry times
*/
#define qh_JOGGLEagain 1
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
qh_JOGGLEmaxincrease
maximum qh.JOGGLEmax due to qh_JOGGLEincrease
relative to qh.MAXwidth
notes:
qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
*/
#define qh_JOGGLEmaxincrease 1e-2
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
qh_JOGGLEmaxretry
stop after qh_JOGGLEmaxretry attempts
*/
#define qh_JOGGLEmaxretry 100
/*============================================================*/
/*============= performance related constants ================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="HASHfactor">-</a>
qh_HASHfactor
total hash slots / used hash slots. Must be at least 1.1.
notes:
=2 for at worst 50% occupancy for qh.hash_table and normally 25% occupancy
*/
#define qh_HASHfactor 2
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="VERIFYdirect">-</a>
qh_VERIFYdirect
with 'Tv' verify all points against all facets if op count is smaller
notes:
if greater, calls qh_check_bestdist() instead
*/
#define qh_VERIFYdirect 1000000
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALsearch">-</a>
qh_INITIALsearch
if qh_INITIALmax, search points up to this dimension
*/
#define qh_INITIALsearch 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INITIALmax">-</a>
qh_INITIALmax
if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
notes:
from points with non-zero determinants
use option 'Qs' to override (much slower)
*/
#define qh_INITIALmax 8
/*============================================================*/
/*============= memory constants =============================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMalign">-</a>
qh_MEMalign
memory alignment for qh_meminitbuffers() in global.c
notes:
to avoid bus errors, memory allocation must consider alignment requirements.
malloc() automatically takes care of alignment. Since mem.c manages
its own memory, we need to explicitly specify alignment in
qh_meminitbuffers().
A safe choice is sizeof(double). sizeof(float) may be used if doubles
do not occur in data structures and pointers are the same size. Be careful
of machines (e.g., DEC Alpha) with large pointers.
If using gcc, best alignment is [fmax_() is defined in geom_r.h]
#define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
*/
#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMbufsize">-</a>
qh_MEMbufsize
size of additional memory buffers
notes:
used for qh_meminitbuffers() in global.c
*/
#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MEMinitbuf">-</a>
qh_MEMinitbuf
size of initial memory buffer
notes:
use for qh_meminitbuffers() in global.c
*/
#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="INFINITE">-</a>
qh_INFINITE
on output, indicates Voronoi center at infinity
*/
#define qh_INFINITE -10.101
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DEFAULTbox">-</a>
qh_DEFAULTbox
default box size (Geomview expects 0.5)
qh_DEFAULTbox
default box size for integer coorindate (rbox only)
*/
#define qh_DEFAULTbox 0.5
#define qh_DEFAULTzbox 1e6
/*============================================================*/
/*============= conditional compilation ======================*/
/*============================================================*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="compiler">-</a>
__cplusplus
defined by C++ compilers
__MSC_VER
defined by Microsoft Visual C++
__MWERKS__ && __INTEL__
defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
__MWERKS__ && __POWERPC__
defined by Metrowerks when compiling for PowerPC-based Macintosh
__STDC__
defined for strict ANSI C
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COMPUTEfurthest">-</a>
qh_COMPUTEfurthest
compute furthest distance to an outside point instead of storing it with the facet
=1 to compute furthest
notes:
computing furthest saves memory but costs time
about 40% more distance tests for partitioning
removes facet->furthestdist
*/
#define qh_COMPUTEfurthest 0
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
=0 removes most of statistic gathering and reporting
notes:
if 0, code size is reduced by about 4%.
*/
#define qh_KEEPstatistics 1
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXoutside">-</a>
qh_MAXoutside
record outer plane for each facet
=1 to record facet->maxoutside
notes:
this takes a realT per facet and slightly slows down qhull
it produces better outer planes for geomview output
*/
#define qh_MAXoutside 1
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOmerge">-</a>
qh_NOmerge
disables facet merging if defined
notes:
This saves about 10% space.
Unless 'Q0'
qh_NOmerge sets 'QJ' to avoid precision errors
#define qh_NOmerge
see:
<a href="mem.h#NOmem">qh_NOmem</a> in mem.c
see user.c/user_eg.c for removing io.o
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="NOtrace">-</a>
qh_NOtrace
no tracing if defined
notes:
This saves about 5% space.
#define qh_NOtrace
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="QHpointer">-</a>
qh_QHpointer
access global data with pointer or static structure
qh_QHpointer = 1 access globals via a pointer to allocated memory
enables qh_saveqhull() and qh_restoreqhull()
[2010, gcc] costs about 4% in time and 4% in space
[2003, msvc] costs about 8% in time and 2% in space
= 0 qh_qh and qh_qhstat are static data structures
only one instance of qhull() can be active at a time
default value
qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
It is required for msvc-2005. It is not needed for gcc.
notes:
[jan'16] qh_QHpointer is deprecated for Qhull. Use libqhull_r instead.
all global variables for qhull are in qh, qhmem, and qhstat
qh is defined in libqhull.h
qhmem is defined in mem.h
qhstat is defined in stat.h
*/
#ifdef qh_QHpointer
#if qh_dllimport
#error QH6207 Qhull error: Use qh_QHpointer_dllimport instead of qh_dllimport with qh_QHpointer
#endif
#else
#define qh_QHpointer 0
#if qh_QHpointer_dllimport
#error QH6234 Qhull error: Use qh_dllimport instead of qh_QHpointer_dllimport when qh_QHpointer is not defined
#endif
#endif
#if 0 /* sample code */
qhT *oldqhA, *oldqhB;
exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
flags, outfile, errfile);
/* use results from first call to qh_new_qhull */
oldqhA= qh_save_qhull();
exitcode= qh_new_qhull(dimB, numpointsB, pointsB, ismalloc,
flags, outfile, errfile);
/* use results from second call to qh_new_qhull */
oldqhB= qh_save_qhull();
qh_restore_qhull(&oldqhA);
/* use results from first call to qh_new_qhull */
qh_freeqhull(qh_ALL); /* frees all memory used by first call */
qh_restore_qhull(&oldqhB);
/* use results from second call to qh_new_qhull */
qh_freeqhull(!qh_ALL); /* frees long memory used by second call */
qh_memfreeshort(&curlong, &totlong); /* frees short memory and memory allocator */
#endif
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="QUICKhelp">-</a>
qh_QUICKhelp
=1 to use abbreviated help messages, e.g., for degenerate inputs
*/
#define qh_QUICKhelp 0
/*============================================================*/
/*============= -merge constants- ============================*/
/*============================================================*/
/*
These constants effect facet merging. You probably will not need
to modify them. They effect the performance of facet merging.
*/
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMmergeVertex">-</a>
qh_DIMmergeVertex
max dimension for vertex merging (it is not effective in high-d)
*/
#define qh_DIMmergeVertex 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DIMreduceBuild">-</a>
qh_DIMreduceBuild
max dimension for vertex reduction during build (slow in high-d)
*/
#define qh_DIMreduceBuild 5
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTcentrum">-</a>
qh_BESTcentrum
if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
else, qh_findbestneighbor() tests all vertices (much better merges)
qh_BESTcentrum2
if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
*/
#define qh_BESTcentrum 20
#define qh_BESTcentrum2 2
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="BESTnonconvex">-</a>
qh_BESTnonconvex
if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
notes:
It is needed because qh_findbestneighbor is slow for large facets
*/
#define qh_BESTnonconvex 15
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewmerges">-</a>
qh_MAXnewmerges
if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
notes:
It is needed because postmerge can merge many facets at once
*/
#define qh_MAXnewmerges 2
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnewcentrum">-</a>
qh_MAXnewcentrum
if <= dim+n vertices (n approximates the number of merges),
reset the centrum in qh_updatetested() and qh_mergecycle_facets()
notes:
needed to reduce cost and because centrums may move too much if
many vertices in high-d
*/
#define qh_MAXnewcentrum 5
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="COPLANARratio">-</a>
qh_COPLANARratio
for 3-d+ merging, qh.MINvisible is n*premerge_centrum
notes:
for non-merging, it's DISTround
*/
#define qh_COPLANARratio 3
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="DISToutside">-</a>
qh_DISToutside
When is a point clearly outside of a facet?
Stops search in qh_findbestnew or qh_partitionall
qh_findbest uses qh.MINoutside since since it is only called if no merges.
notes:
'Qf' always searches for best facet
if !qh.MERGING, same as qh.MINoutside.
if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
[Note: Zdelvertextot occurs normally with interior points]
RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
When there is a sharp edge, need to move points to a
clearly good facet; otherwise may be lost in another partitioning.
if too big then O(n^2) behavior for partitioning in cone
if very small then important points not processed
Needed in qh_partitionall for
RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
Needed in qh_findbestnew for many instances of
RBOX 1000 s Z1 G1e-13 t | QHULL Tv
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="RATIOnearinside">-</a>
qh_RATIOnearinside
ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
qh_check_maxout().
notes:
This is overkill since do not know the correct value.
It effects whether 'Qc' reports all coplanar points
Not used for 'd' since non-extreme points are coplanar
*/
#define qh_RATIOnearinside 5
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="SEARCHdist">-</a>
qh_SEARCHdist
When is a facet coplanar with the best facet?
qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
(qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="USEfindbestnew">-</a>
qh_USEfindbestnew
Always use qh_findbestnew for qh_partitionpoint, otherwise use
qh_findbestnew if merged new facet or sharpnewfacets.
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WIDEcoplanar">-</a>
qh_WIDEcoplanar
n*MAXcoplanar or n*MINvisible for a WIDEfacet
if vertex is further than qh.WIDEfacet from the hyperplane
then its ridges are not counted in computing the area, and
the facet's centrum is frozen.
notes:
qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
qh_WIDEcoplanar * qh.MINvisible);
*/
#define qh_WIDEcoplanar 6
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WIDEduplicate">-</a>
qh_WIDEduplicate
Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
Override with option Q12 no-wide-duplicate
Notes:
Merging a duplicate ridge can lead to very wide facets.
A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
*/
#define qh_WIDEduplicate 100
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="MAXnarrow">-</a>
qh_MAXnarrow
max. cosine in initial hull that sets qh.NARROWhull
notes:
If qh.NARROWhull, the initial partition does not make
coplanar points. If narrow, a coplanar point can be
coplanar to two facets of opposite orientations and
distant from the exact convex hull.
Conservative estimate. Don't actually see problems until it is -1.0
*/
#define qh_MAXnarrow -0.99999999
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="WARNnarrow">-</a>
qh_WARNnarrow
max. cosine in initial hull to warn about qh.NARROWhull
notes:
this is a conservative estimate.
Don't actually see problems until it is -1.0. See qh-impre.htm
*/
#define qh_WARNnarrow -0.999999999999999
/*-<a href="qh-user.htm#TOC"
>--------------------------------</a><a name="ZEROdelaunay">-</a>
qh_ZEROdelaunay
a zero Delaunay facet occurs for input sites coplanar with their convex hull
the last normal coefficient of a zero Delaunay facet is within
qh_ZEROdelaunay * qh.ANGLEround of 0
notes:
qh_ZEROdelaunay does not allow for joggled input ('QJ').
You can avoid zero Delaunay facets by surrounding the input with a box.
Use option 'PDk:-n' to explicitly define zero Delaunay facets
k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
*/
#define qh_ZEROdelaunay 2
/*============================================================*/
/*============= Microsoft DevStudio ==========================*/
/*============================================================*/
/*
Finding Memory Leaks Using the CRT Library
https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
Reports enabled in qh_lib_check for Debug window and stderr
From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
Watch: {,,msvcr80d.dll}_crtBreakAlloc Value from {n} in the leak report
_CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
Examples
http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
*/
#if 0 /* off (0) by default for QHULL_CRTDBG */
#define QHULL_CRTDBG
#endif
#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#endif /* qh_DEFuser */

View File

@@ -0,0 +1,94 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
usermem.c
qh_exit(), qh_free(), and qh_malloc()
See README.txt.
If you redefine one of these functions you must redefine all of them.
If you recompile and load this file, then usermem.o will not be loaded
from qhull.a or qhull.lib
See libqhull.h for data structures, macros, and user-callable functions.
See user.c for qhull-related, redefinable functions
see user.h for user-definable constants
See userprintf.c for qh_fprintf and userprintf_rbox.c for qh_fprintf_rbox
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull.h"
#include <stdarg.h>
#include <stdlib.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_exit">-</a>
qh_exit( exitcode )
exit program
notes:
qh_exit() is called when qh_errexit() and longjmp() are not available.
This is the only use of exit() in Qhull
To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
*/
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_stderr">-</a>
qh_fprintf_stderr( msgcode, format, list of args )
fprintf to stderr with msgcode (non-zero)
notes:
qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
It is typically followed by qh_errexit().
Redefine this function to avoid using stderr
Use qh_fprintf [userprintf.c] for normal printing
*/
void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
va_list args;
va_start(args, fmt);
if(msgcode)
fprintf(stderr, "QH%.4d ", msgcode);
vfprintf(stderr, fmt, args);
va_end(args);
} /* fprintf_stderr */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_free">-</a>
qh_free( mem )
free memory
notes:
same as free()
No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
} /* free */
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_malloc">-</a>
qh_malloc( mem )
allocate memory
notes:
same as malloc()
*/
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */

View File

@@ -0,0 +1,66 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
userprintf.c
qh_fprintf()
see README.txt see COPYING.txt for copyright information.
If you recompile and load this file, then userprintf.o will not be loaded
from qhull.a or qhull.lib
See libqhull.h for data structures, macros, and user-callable functions.
See user.c for qhull-related, redefinable functions
see user.h for user-definable constants
See usermem.c for qh_exit(), qh_free(), and qh_malloc()
see Qhull.cpp and RboxPoints.cpp for examples.
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull.h"
#include "mem.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf">-</a>
qh_fprintf(fp, msgcode, format, list of args )
print arguments to *fp according to format
Use qh_fprintf_rbox() for rboxlib.c
notes:
same as fprintf()
fgets() is not trapped like fprintf()
exit qh_fprintf via qh_errexit()
may be called for errors in qh_initstatistics and qh_meminit
*/
void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
/* could use qhmem.ferr, but probably better to be cautious */
qh_fprintf_stderr(6232, "Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf called.\n");
qh_errexit(6232, NULL, NULL);
}
va_start(args, fmt);
#if qh_QHpointer
if (qh_qh && qh ANNOTATEoutput) {
#else
if (qh ANNOTATEoutput) {
#endif
fprintf(fp, "[QH%.4d]", msgcode);
}else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
fprintf(fp, "QH%.4d ", msgcode);
}
vfprintf(fp, fmt, args);
va_end(args);
/* Place debugging traps here. Use with option 'Tn' */
} /* qh_fprintf */

View File

@@ -0,0 +1,53 @@
/*<html><pre> -<a href="qh-user.htm"
>-------------------------------</a><a name="TOP">-</a>
userprintf_rbox.c
qh_fprintf_rbox()
see README.txt see COPYING.txt for copyright information.
If you recompile and load this file, then userprintf_rbox.o will not be loaded
from qhull.a or qhull.lib
See libqhull.h for data structures, macros, and user-callable functions.
See user.c for qhull-related, redefinable functions
see user.h for user-definable constants
See usermem.c for qh_exit(), qh_free(), and qh_malloc()
see Qhull.cpp and RboxPoints.cpp for examples.
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/*-<a href="qh-user.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
qh_fprintf_rbox(fp, msgcode, format, list of args )
print arguments to *fp according to format
Use qh_fprintf_rbox() for rboxlib.c
notes:
same as fprintf()
fgets() is not trapped like fprintf()
exit qh_fprintf_rbox via qh_errexit_rbox()
*/
void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
qh_errexit_rbox(6231);
}
if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
fprintf(fp, "QH%.4d ", msgcode);
va_start(args, fmt);
vfprintf(fp, fmt, args);
va_end(args);
} /* qh_fprintf_rbox */

View File

@@ -0,0 +1,240 @@
# Simple gcc Makefile for reentrant qhull and rbox (default gcc/g++)
#
# make help
# See README.txt and ../../Makefile
#
# Variables
# BINDIR directory where to copy executables
# DESTDIR destination directory for 'make install'
# DOCDIR directory where to copy html documentation
# INCDIR directory where to copy headers
# LIBDIR directory where to copy libraries
# MANDIR directory where to copy manual pages
# PRINTMAN command for printing manual pages
# PRINTC command for printing C files
# CC ANSI C or C++ compiler
# CC_OPTS1 options used to compile .c files
# CC_OPTS2 options used to link .o files
# CC_OPTS3 options to build shared libraries
#
# LIBQHULL_OBJS .o files for linking
# LIBQHULL_HDRS .h files for printing
# CFILES .c files for printing
# DOCFILES documentation files
# FILES miscellaneous files for printing
# TFILES .txt versions of html files
# FILES all other files
# LIBQHULL_OBJS specifies the object files of libqhullstatic_r.a
#
# Results
# rbox Generates points sets for qhull, qconvex, etc.
# qhull Computes convex hulls and related structures
# qconvex, qdelaunay, qhalf, qvoronoi
# Specializations of qhull for each geometric structure
# libqhullstatic_r.a Static library for reentrant qhull
# testqset_r Standalone test of reentrant qset_r.c with mem_r.c
# user_eg An example of using qhull (reentrant)
# user_eg2 An example of using qhull (reentrant)
#
# Make targets
# make Build results using gcc or another compiler
# make clean Remove object files
# make cleanall Remove generated files
# make doc Print documentation
# make help
# make install Copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
# make new Rebuild qhull and rbox from source
# make printall Print all files
# make qtest Quick test of qset, rbox, and qhull
# make test Quck test of qhull, qconvex, etc.
#
# Do not replace tabs with spaces. Needed for build rules
# Unix line endings (\n)
# $Id: //main/2015/qhull/src/libqhull_r/Makefile#6 $
DESTDIR = /usr/local
BINDIR = $(DESTDIR)/bin
INCDIR = $(DESTDIR)/include
LIBDIR = $(DESTDIR)/lib
DOCDIR = $(DESTDIR)/share/doc/qhull
MANDIR = $(DESTDIR)/share/man/man1
# if you do not have enscript, try a2ps or just use lpr. The files are text.
PRINTMAN = enscript -2rl
PRINTC = enscript -2r
# PRINTMAN = lpr
# PRINTC = lpr
#for Gnu's gcc compiler, -O3 for optimization, -g for debugging, -pg for profiling
# -fpic needed for gcc x86_64-linux-gnu. Not needed for mingw
CC = gcc
CC_OPTS1 = -O3 -ansi -I../../src -fpic $(CC_WARNINGS)
# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
#CC = cc
#CC_OPTS1 = -Xc -v -fast -I../../src
# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
#CC = cc
#CC_OPTS1 = -ansi -O2 -I../../src
# for Next cc compiler with fat executable
#CC = cc
#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
# For loader, ld,
CC_OPTS2 = $(CC_OPTS1)
# Default targets for make
all: qhull_links qhull_all qtest
help:
head -n 50 Makefile
clean:
rm -f *.o
# Delete linked files from other directories [qhull_links]
rm -f qconvex_r.c unix_r.c qdelaun_r.c qhalf_r.c qvoronoi_r.c rbox_r.c
rm -f user_eg_r.c user_eg2_r.c testqset_r.c
cleanall: clean
rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
rm -f core user_eg_r user_eg2_r testqset_r libqhullstatic_r.a
doc:
$(PRINTMAN) $(TXTFILES) $(DOCFILES)
install:
mkdir -p $(BINDIR)
mkdir -p $(DOCDIR)
mkdir -p $(INCDIR)/libqhull
mkdir -p $(MANDIR)
cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(BINDIR)
cp -p libqhullstatic_r.a $(LIBDIR)
cp -p ../../html/qhull.man $(MANDIR)/qhull.1
cp -p ../../html/rbox.man $(MANDIR)/rbox.1
cp -p ../../html/* $(DOCDIR)
cp *.h $(INCDIR)/libqhull_r
new: cleanall all
printall: doc printh printc printf
printh:
$(PRINTC) $(LIBQHULL_HDRS)
printc:
$(PRINTC) $(CFILES)
# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end. Better locality.
# Same definitions as ../../Makefile
LIBQHULLS_OBJS_1= global_r.o stat_r.o geom2_r.o poly2_r.o merge_r.o \
libqhull_r.o geom_r.o poly_r.o qset_r.o mem_r.o random_r.o
LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem_r.o userprintf_r.o io_r.o user_r.o
LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib_r.o userprintf_rbox_r.o
LIBQHULL_HDRS= user_r.h libqhull_r.h qhull_ra.h geom_r.h \
io_r.h mem_r.h merge_r.h poly_r.h random_r.h \
qset_r.h stat_r.h
# CFILES ordered alphabetically after libqhull.c
CFILES= ../qhull/unix_r.c libqhull_r.c geom_r.c geom2_r.c global_r.c io_r.c \
mem_r.c merge_r.c poly_r.c poly2_r.c random_r.c rboxlib_r.c \
qset_r.c stat_r.c user_r.c usermem_r.c userprintf_r.c \
../qconvex/qconvex.c ../qdelaunay/qdelaun.c ../qhalf/qhalf.c ../qvoronoi/qvoronoi.c
TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
.c.o:
$(CC) -c $(CC_OPTS1) -o $@ $<
# Work around problems with ../ in Red Hat Linux
qhull_links:
# On MINSYS, 'ln -s' may create a copy instead of a symbolic link
[ -f qconvex_r.c ] || ln -s ../qconvex/qconvex_r.c
[ -f qdelaun_r.c ] || ln -s ../qdelaunay/qdelaun_r.c
[ -f qhalf_r.c ] || ln -s ../qhalf/qhalf_r.c
[ -f qvoronoi_r.c ] || ln -s ../qvoronoi/qvoronoi_r.c
[ -f rbox_r.c ] || ln -s ../rbox/rbox_r.c
[ -f testqset_r.c ] || ln -s ../testqset_r/testqset_r.c
[ -f unix_r.c ] || ln -s ../qhull/unix_r.c
[ -f user_eg_r.c ] || ln -s ../user_eg/user_eg_r.c
[ -f user_eg2_r.c ] || ln -s ../user_eg2/user_eg2_r.c
# compile qhull without using bin/libqhullstatic_r.a
qhull_all: qconvex_r.o qdelaun_r.o qhalf_r.o qvoronoi_r.o unix_r.o user_eg_r.o user_eg2_r.o rbox_r.o testqset_r.o $(LIBQHULLS_OBJS)
$(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex_r.o
$(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun_r.o
$(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf_r.o
$(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi_r.o
$(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix_r.o
$(CC) -o rbox $(CC_OPTS2) -lm $(LIBQHULLS_OBJS) rbox_r.o
$(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg_r.o
$(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2_r.o usermem_r.o userprintf_r.o io_r.o
$(CC) -o testqset_r $(CC_OPTS2) -lm mem_r.o qset_r.o usermem_r.o testqset_r.o
-ar -rs libqhullstatic_r.a $(LIBQHULLS_OBJS)
#libqhullstatic_r.a is not needed for qhull
#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
#ranlib libqhullstatic_r.a
qtest:
@echo ============================================
@echo == make qtest ==============================
@echo ============================================
@echo -n "== "
@date
@echo
@echo Testing qset.c and mem.c with testqset
./testqset_r 10000
@echo Run the qhull smoketest
./rbox D4 | ./qhull
@echo ============================================
@echo == To smoketest qhull programs
@echo '== make test'
@echo ============================================
@echo
@echo ============================================
@echo == For all make targets
@echo '== make help'
@echo ============================================
@echo
test: qtest
@echo ==============================
@echo ========= qconvex ============
@echo ==============================
-./rbox 10 | ./qconvex Tv
@echo
@echo ==============================
@echo ========= qdelaunay ==========
@echo ==============================
-./rbox 10 | ./qdelaunay Tv
@echo
@echo ==============================
@echo ========= qhalf ==============
@echo ==============================
-./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
@echo
@echo ==============================
@echo ========= qvoronoi ===========
@echo ==============================
-./rbox 10 | ./qvoronoi Tv
@echo
@echo ==============================
@echo ========= user_eg ============
@echo == w/o shared library ========
@echo ==============================
-./user_eg
@echo
@echo ==============================
@echo ========= user_eg2 ===========
@echo ==============================
-./user_eg2
@echo
# end of Makefile

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
/*<html><pre> -<a href="qh-geom_r.htm"
>-------------------------------</a><a name="TOP">-</a>
geom_r.h
header file for geometric routines
see qh-geom_r.htm and geom_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/geom_r.h#3 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFgeom
#define qhDEFgeom 1
#include "libqhull_r.h"
/* ============ -macros- ======================== */
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="fabs_">-</a>
fabs_(a)
returns the absolute value of a
*/
#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="fmax_">-</a>
fmax_(a,b)
returns the maximum value of a and b
*/
#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="fmin_">-</a>
fmin_(a,b)
returns the minimum value of a and b
*/
#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="maximize_">-</a>
maximize_(maxval, val)
set maxval to val if val is greater than maxval
*/
#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="minimize_">-</a>
minimize_(minval, val)
set minval to val if val is less than minval
*/
#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="det2_">-</a>
det2_(a1, a2,
b1, b2)
compute a 2-d determinate
*/
#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="det3_">-</a>
det3_(a1, a2, a3,
b1, b2, b3,
c1, c2, c3)
compute a 3-d determinate
*/
#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
- ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="dX">-</a>
dX( p1, p2 )
dY( p1, p2 )
dZ( p1, p2 )
given two indices into rows[],
compute the difference between X, Y, or Z coordinates
*/
#define dX( p1,p2 ) ( *( rows[p1] ) - *( rows[p2] ))
#define dY( p1,p2 ) ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
#define dZ( p1,p2 ) ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
#define dW( p1,p2 ) ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
/*============= prototypes in alphabetical order, infrequent at end ======= */
#ifdef __cplusplus
extern "C" {
#endif
void qh_backnormal(qhT *qh, realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
void qh_distplane(qhT *qh, pointT *point, facetT *facet, realT *dist);
facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
boolT bestoutside, boolT isnewfacets, boolT noupper,
realT *dist, boolT *isoutside, int *numpart);
facetT *qh_findbesthorizon(qhT *qh, boolT ischeckmax, pointT *point,
facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet, realT *dist,
boolT bestoutside, boolT *isoutside, int *numpart);
void qh_gausselim(qhT *qh, realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
realT qh_getangle(qhT *qh, pointT *vect1, pointT *vect2);
pointT *qh_getcenter(qhT *qh, setT *vertices);
pointT *qh_getcentrum(qhT *qh, facetT *facet);
realT qh_getdistance(qhT *qh, facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
void qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient);
void qh_normalize2(qhT *qh, coordT *normal, int dim, boolT toporient,
realT *minnorm, boolT *ismin);
pointT *qh_projectpoint(qhT *qh, pointT *point, facetT *facet, realT dist);
void qh_setfacetplane(qhT *qh, facetT *newfacets);
void qh_sethyperplane_det(qhT *qh, int dim, coordT **rows, coordT *point0,
boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
void qh_sethyperplane_gauss(qhT *qh, int dim, coordT **rows, pointT *point0,
boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
boolT qh_sharpnewfacets(qhT *qh);
/*========= infrequently used code in geom2_r.c =============*/
coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension);
void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
realT qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero);
realT qh_detjoggle(qhT *qh, pointT *points, int numpoints, int dimension);
void qh_detroundoff(qhT *qh);
realT qh_detsimplex(qhT *qh, pointT *apex, setT *points, int dim, boolT *nearzero);
realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
realT qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs);
realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
realT qh_facetarea(qhT *qh, facetT *facet);
realT qh_facetarea_simplex(qhT *qh, int dim, coordT *apex, setT *vertices,
vertexT *notvertex, boolT toporient, coordT *normal, realT *offset);
pointT *qh_facetcenter(qhT *qh, setT *vertices);
facetT *qh_findgooddist(qhT *qh, pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
void qh_getarea(qhT *qh, facetT *facetlist);
boolT qh_gram_schmidt(qhT *qh, int dim, realT **rows);
boolT qh_inthresholds(qhT *qh, coordT *normal, realT *angle);
void qh_joggleinput(qhT *qh);
realT *qh_maxabsval(realT *normal, int dim);
setT *qh_maxmin(qhT *qh, pointT *points, int numpoints, int dimension);
realT qh_maxouter(qhT *qh);
void qh_maxsimplex(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
realT qh_minabsval(realT *normal, int dim);
int qh_mindiff(realT *vecA, realT *vecB, int dim);
boolT qh_orientoutside(qhT *qh, facetT *facet);
void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
coordT qh_pointdist(pointT *point1, pointT *point2, int dim);
void qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol);
void qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points);
void qh_projectinput(qhT *qh);
void qh_projectpoints(qhT *qh, signed char *project, int n, realT *points,
int numpoints, int dim, realT *newpoints, int newdim);
void qh_rotateinput(qhT *qh, realT **rows);
void qh_rotatepoints(qhT *qh, realT *points, int numpoints, int dim, realT **rows);
void qh_scaleinput(qhT *qh);
void qh_scalelast(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
coordT high, coordT newhigh);
void qh_scalepoints(qhT *qh, pointT *points, int numpoints, int dim,
realT *newlows, realT *newhighs);
boolT qh_sethalfspace(qhT *qh, int dim, coordT *coords, coordT **nextp,
coordT *normal, coordT *offset, coordT *feasible);
coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
pointT *qh_voronoi_center(qhT *qh, int dim, setT *points);
#ifdef __cplusplus
} /* extern "C"*/
#endif
#endif /* qhDEFgeom */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,266 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Reentrant Qhull functions, macros, and data structures</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
<hr>
<!-- Main text of document. -->
<h1>Reentrant Qhull functions, macros, and data structures</h1>
<blockquote>
<p>The following sections provide an overview and index to
reentrant Qhull's functions, macros, and data structures.
Each section starts with an introduction.
See also <a href=../../html/qh-code.htm#library>Calling
Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
<p>Qhull uses the following conventions:</p>
<blockquote>
<ul>
<li>in code, global variables start with &quot;qh &quot;
<li>in documentation, global variables start with 'qh.'
<li>constants start with an upper case word
<li>important globals include an '_'
<li>functions, macros, and constants start with &quot;qh_&quot;</li>
<li>data types end in &quot;T&quot;</li>
<li>macros with arguments end in &quot;_&quot;</li>
<li>iterators are macros that use local variables</li>
<li>iterators for sets start with &quot;FOREACH&quot;</li>
<li>iterators for lists start with &quot;FORALL&quot;</li>
<li>qhull options are in single quotes (e.g., 'Pdn')</li>
<li>lists are sorted alphabetically</li>
<li>preprocessor directives on left margin for older compilers</li>
</ul>
</blockquote>
<p>
Reentrant Qhull is nearly the same as non-reentrant Qhull. In reentrant
Qhull, the qhT data structure is the first parameter to most functions. Qhull accesses
this data structure with 'qh->...'.
In non-reentrant Qhull, the global data structure is either a struct (qh_QHpointer==0)
or a pointer (qh_QHpointer==1). The non-reentrant code looks different because this data
structure is accessed via the 'qh' macro. This macro expands to 'qh_qh.' or 'qh_qh->' (resp.).
<p>
When reading code with an editor, a search for
'<i>&quot;function</i>'
will locate the header of <i>qh_function</i>. A search for '<i>* function</i>'
will locate the tail of <i>qh_function</i>.
<p>A useful starting point is <a href="libqhull_r.h">libqhull_r.h</a>. It defines most
of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
determine the corresponding <a href="libqhull_r.h#qh_PRINT">qh_PRINT...</a> constant.
Search <a href="io_r.c">io_r.c</a> to learn how the print function is implemented.</p>
<p>If your web browser is configured for .c and .h files, the function, macro, and data type links
go to the corresponding source location. To configure your web browser for .c and .h files.
<ul>
<li>In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'.
<li>Opera 12.10
<ol>
<li>In Tools > Preferences > Advanced > Downloads
<li>Uncheck 'Hide file types opened with Opera'
<li>Quick find 'html'
<li>Select 'text/html' > Edit
<li>Add File extensions 'c,h,'
<li>Click 'OK'
</ol>
<li>Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings?
<li>Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type?
<li>Chrome -- Can Chrome be configured?
</ul>
<p>
Please report documentation and link errors
to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
</blockquote>
<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
<hr>
<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
<blockquote>
<p>This sections lists the .c and .h files for Qhull. Please
refer to these files for detailed information.</p>
<blockquote>
<dl>
<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
platforms with <a href=http://www.cmake.org/>CMake</a>.
Qhull includes project files for Visual Studio and Qt.
</dd>
<dt>&nbsp;</dt>
<dt><a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
Data structures are documented under <a href="qh-poly_r.htm">Poly</a>.
Global variables are documented under <a href="qh-globa_r.htm">Global</a>.
Other data structures and variables are documented under
<a href="qh-qhull_r.htm#TOC">Qhull</a> or <a href="qh-geom_r.htm"><b>Geom</b></a><b>.</b></dd>
<dt>&nbsp;</dt>
<dt><a href="qh-geom_r.htm"><b>Geom</b></a><b>, </b>
<a href="geom_r.h"><b>geom_r.h</b></a><b>, </b>
<a href="geom_r.c"><b>geom_r.c</b></a><b>, </b>
<a href="geom2_r.c"><b>geom2_r.c</b></a><b>, </b>
<a href="random_r.c"><b>random_r.c</b></a><b>, </b>
<a href="random_r.h"><b>random_r.h</b></a></dt>
<dd>Geometric routines. These routines implement mathematical
functions such as Gaussian elimination and geometric
routines needed for Qhull. Frequently used routines are
in <tt>geom_r.c</tt> while infrequent ones are in <tt>geom2_r.c</tt>.
</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-globa_r.htm"><b>Global</b></a><b>, </b>
<a href="global_r.c"><b>global_r.c</b></a><b>, </b>
<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
to store globally defined constants, lists, sets, and
variables.
<tt>global_r.c</tt> initializes and frees these
structures. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-io_r.htm"><b>Io</b></a><b>, </b><a href="io_r.h"><b>io_r.h</b></a><b>,
</b><a href="io_r.c"><b>io_r.c</b></a> </dt>
<dd>Input and output routines. Qhull provides a wide range of
input and output options.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-mem_r.htm"><b>Mem</b></a><b>, </b>
<a href="mem_r.h"><b>mem_r.h</b></a><b>, </b>
<a href="mem_r.c"><b>mem_r.c</b></a> </dt>
<dd>Memory routines. Qhull provides memory allocation and
deallocation. It uses quick-fit allocation.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-merge_r.htm"><b>Merge</b></a><b>, </b>
<a href="merge_r.h"><b>merge_r.h</b></a><b>, </b>
<a href="merge_r.c"><b>merge_r.c</b></a> </dt>
<dd>Merge routines. Qhull handles precision problems by
merged facets or joggled input. These routines merge simplicial facets,
merge non-simplicial facets, merge cycles of facets, and
rename redundant vertices.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-poly_r.htm"><b>Poly</b></a><b>, </b>
<a href="poly_r.h"><b>poly_r.h</b></a><b>, </b>
<a href="poly_r.c"><b>poly_r.c</b></a><b>, </b>
<a href="poly2_r.c"><b>poly2_r.c</b></a><b>, </b>
<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
<dd>Polyhedral routines. Qhull produces a polyhedron as a
list of facets with vertices, neighbors, ridges, and
geometric information. <tt>libqhull_r.h</tt> defines the main
data structures. Frequently used routines are in <tt>poly_r.c</tt>
while infrequent ones are in <tt>poly2_r.c</tt>.</dd>
<dt>&nbsp;</dt>
<dt><a href="qh-qhull_r.htm#TOC"><b>Qhull</b></a><b>, </b>
<a href="libqhull_r.c"><b>libqhull_r.c</b></a><b>, </b>
<a href="libqhull_r.h"><b>libqhull_r.h</b></a><b>, </b>
<a href="qhull_ra.h"><b>qhull_ra.h</b></a><b>, </b>
<a href="../qhull/unix_r.c"><b>unix_r.c</b></a> <b>, </b>
<a href="../qconvex/qconvex_r.c"><b>qconvex_r.c</b></a> <b>, </b>
<a href="../qdelaunay/qdelaun_r.c"><b>qdelaun_r.c</b></a> <b>, </b>
<a href="../qhalf/qhalf_r.c"><b>qhalf_r.c</b></a> <b>, </b>
<a href="../qvoronoi/qvoronoi_r.c"><b>qvoronoi_r.c</b></a> </dt>
<dd>Top-level routines. The Quickhull algorithm is
implemented by <tt>libqhull_r.c</tt>. <tt>qhull_ra.h</tt>
includes all header files. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-set_r.htm"><b>Set</b></a><b>, </b>
<a href="qset_r.h"><b>qset_r.h</b></a><b>, </b>
<a href="qset_r.c"><b>qset_r.c</b></a> </dt>
<dd>Set routines. Qhull implements its data structures as
sets. A set is an array of pointers that is expanded as
needed. This is a separate package that may be used in
other applications. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-stat_r.htm"><b>Stat</b></a><b>, </b>
<a href="stat_r.h"><b>stat_r.h</b></a><b>, </b>
<a href="stat_r.c"><b>stat_r.c</b></a> </dt>
<dd>Statistical routines. Qhull maintains statistics about
its implementation. </dd>
<dt>&nbsp;</dt>
<dt><a href="qh-user_r.htm"><b>User</b></a><b>, </b>
<a href="user_r.h"><b>user_r.h</b></a><b>, </b>
<a href="user_r.c"><b>user_r.c</b></a><b>, </b>
<a href="../user_eg/user_eg_r.c"><b>user_eg_r.c</b></a><b>, </b>
<a href="../user_eg2/user_eg2_r.c"><b>user_eg2_r.c</b></a><b>, </b>
<a href="../user_eg3/user_eg3_r.cpp"><b>user_eg3_r.cpp</b></a><b>, </b>
</dt>
<dd>User-defined routines. Qhull allows the user to configure
the code with defined constants and specialized routines.
</dd>
</dl>
</blockquote>
</blockquote>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="#TOC">Qhull files</a><br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
/*<html><pre> -<a href="qh-io_r.htm"
>-------------------------------</a><a name="TOP">-</a>
io_r.h
declarations of Input/Output functions
see README, libqhull_r.h and io_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/io_r.h#3 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFio
#define qhDEFio 1
#include "libqhull_r.h"
/*============ constants and flags ==================*/
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="qh_MAXfirst">-</a>
qh_MAXfirst
maximum length of first two lines of stdin
*/
#define qh_MAXfirst 200
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="qh_MINradius">-</a>
qh_MINradius
min radius for Gp and Gv, fraction of maxcoord
*/
#define qh_MINradius 0.02
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="qh_GEOMepsilon">-</a>
qh_GEOMepsilon
adjust outer planes for 'lines closer' and geomview roundoff.
This prevents bleed through.
*/
#define qh_GEOMepsilon 2e-3
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="qh_WHITESPACE">-</a>
qh_WHITESPACE
possible values of white space
*/
#define qh_WHITESPACE " \n\t\v\r\f"
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="RIDGE">-</a>
qh_RIDGE
to select which ridges to print in qh_eachvoronoi
*/
typedef enum
{
qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
}
qh_RIDGE;
/*-<a href="qh-io_r.htm#TOC"
>--------------------------------</a><a name="printvridgeT">-</a>
printvridgeT
prints results of qh_printvdiagram
see:
<a href="io_r.c#printvridge">qh_printvridge</a> for an example
*/
typedef void (*printvridgeT)(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
/*============== -prototypes in alphabetical order =========*/
#ifdef __cplusplus
extern "C" {
#endif
void qh_dfacet(qhT *qh, unsigned id);
void qh_dvertex(qhT *qh, unsigned id);
int qh_compare_facetarea(const void *p1, const void *p2);
int qh_compare_facetmerge(const void *p1, const void *p2);
int qh_compare_facetvisit(const void *p1, const void *p2);
/* int qh_compare_vertexpoint(const void *p1, const void *p2); Not useable since it depends on qh */
void qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length);
void qh_countfacets(qhT *qh, facetT *facetlist, setT *facets, boolT printall,
int *numfacetsp, int *numsimplicialp, int *totneighborsp,
int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
pointT *qh_detvnorm(qhT *qh, vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
setT *qh_detvridge(qhT *qh, vertexT *vertex);
setT *qh_detvridge3(qhT *qh, vertexT *atvertex, vertexT *vertex);
int qh_eachvoronoi(qhT *qh, FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
int qh_eachvoronoi_all(qhT *qh, FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
void qh_facet2point(qhT *qh, facetT *facet, pointT **point0, pointT **point1, realT *mindist);
setT *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
void qh_geomplanes(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
void qh_markkeep(qhT *qh, facetT *facetlist);
setT *qh_markvoronoi(qhT *qh, facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
void qh_order_vertexneighbors(qhT *qh, vertexT *vertex);
void qh_prepare_output(qhT *qh);
void qh_printafacet(qhT *qh, FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
void qh_printbegin(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet);
void qh_printcentrum(qhT *qh, FILE *fp, facetT *facet, realT radius);
void qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printend4geom(qhT *qh, FILE *fp, facetT *facet, int *num, boolT printall);
void qh_printextremes(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printextremes_2d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printextremes_d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printfacet(qhT *qh, FILE *fp, facetT *facet);
void qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
void qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet2geom_points(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
facetT *facet, realT offset, realT color[3]);
void qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
void qh_printfacet3geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet3geom_points(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
void qh_printfacet3geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet3vertex(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
void qh_printfacet4geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
void qh_printfacet4geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
void qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format);
void qh_printfacetNvertex_simplicial(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
void qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet);
void qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet);
void qh_printfacets(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printhyperplaneintersection(qhT *qh, FILE *fp, facetT *facet1, facetT *facet2,
setT *vertices, realT color[3]);
void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
void qh_printline3geom(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
void qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point);
void qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id);
void qh_printpoint3(qhT *qh, FILE *fp, pointT *point);
void qh_printpoints_out(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
void qh_printpointvect(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
void qh_printpointvect2(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
void qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge);
void qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius);
void qh_printvdiagram(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
int qh_printvdiagram2(qhT *qh, FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
void qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex);
void qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
setT *facets, boolT printall);
void qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices);
void qh_printvneighbors(qhT *qh, FILE *fp, facetT* facetlist, setT *facets, boolT printall);
void qh_printvoronoi(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
void qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
void qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
void qh_produce_output(qhT *qh);
void qh_produce_output2(qhT *qh);
void qh_projectdim3(qhT *qh, pointT *source, pointT *destination);
int qh_readfeasible(qhT *qh, int dim, const char *curline);
coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
void qh_setfeasible(qhT *qh, int dim);
boolT qh_skipfacet(qhT *qh, facetT *facet);
char *qh_skipfilename(qhT *qh, char *filename);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFio */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
# -------------------------------------------------
# libqhull_r.pro -- Qt project for Qhull shared library
#
# It uses reentrant Qhull
# -------------------------------------------------
include(../qhull-warn.pri)
DESTDIR = ../../lib
DLLDESTDIR = ../../bin
TEMPLATE = lib
CONFIG += shared warn_on
CONFIG -= qt
build_pass:CONFIG(debug, debug|release):{
TARGET = qhull_rd
OBJECTS_DIR = Debug
}else:build_pass:CONFIG(release, debug|release):{
TARGET = qhull_r
OBJECTS_DIR = Release
}
win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
win32-msvc* : DEF_FILE += ../../src/libqhull_r/qhull_r-exports.def
# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
SOURCES += ../libqhull_r/global_r.c
SOURCES += ../libqhull_r/stat_r.c
SOURCES += ../libqhull_r/geom2_r.c
SOURCES += ../libqhull_r/poly2_r.c
SOURCES += ../libqhull_r/merge_r.c
SOURCES += ../libqhull_r/libqhull_r.c
SOURCES += ../libqhull_r/geom_r.c
SOURCES += ../libqhull_r/poly_r.c
SOURCES += ../libqhull_r/qset_r.c
SOURCES += ../libqhull_r/mem_r.c
SOURCES += ../libqhull_r/random_r.c
SOURCES += ../libqhull_r/usermem_r.c
SOURCES += ../libqhull_r/userprintf_r.c
SOURCES += ../libqhull_r/io_r.c
SOURCES += ../libqhull_r/user_r.c
SOURCES += ../libqhull_r/rboxlib_r.c
SOURCES += ../libqhull_r/userprintf_rbox_r.c
HEADERS += ../libqhull_r/geom_r.h
HEADERS += ../libqhull_r/io_r.h
HEADERS += ../libqhull_r/libqhull_r.h
HEADERS += ../libqhull_r/mem_r.h
HEADERS += ../libqhull_r/merge_r.h
HEADERS += ../libqhull_r/poly_r.h
HEADERS += ../libqhull_r/random_r.h
HEADERS += ../libqhull_r/qhull_ra.h
HEADERS += ../libqhull_r/qset_r.h
HEADERS += ../libqhull_r/stat_r.h
HEADERS += ../libqhull_r/user_r.h
OTHER_FILES += qh-geom_r.htm
OTHER_FILES += qh-globa_r.htm
OTHER_FILES += qh-io_r.htm
OTHER_FILES += qh-mem_r.htm
OTHER_FILES += qh-merge_r.htm
OTHER_FILES += qh-poly_r.htm
OTHER_FILES += qh-qhull_r.htm
OTHER_FILES += qh-set_r.htm
OTHER_FILES += qh-stat_r.htm
OTHER_FILES += qh-user_r.htm

View File

@@ -0,0 +1,562 @@
/*<html><pre> -<a href="qh-mem_r.htm"
>-------------------------------</a><a name="TOP">-</a>
mem_r.c
memory management routines for qhull
See libqhull/mem_r.c for a standalone program.
To initialize memory:
qh_meminit(qh, stderr);
qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
qh_memsize(qh, (int)sizeof(facetT));
qh_memsize(qh, (int)sizeof(facetT));
...
qh_memsetup(qh);
To free up all memory buffers:
qh_memfreeshort(qh, &curlong, &totlong);
if qh_NOmem,
malloc/free is used instead of mem.c
notes:
uses Quickfit algorithm (freelists for commonly allocated sizes)
assumes small sizes for freelists (it discards the tail of memory buffers)
see:
qh-mem_r.htm and mem_r.h
global_r.c (qh_initbuffers) for an example of using mem_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/mem_r.c#5 $$Change: 2065 $
$DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
*/
#include "libqhull_r.h" /* includes user_r.h and mem_r.h */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef qh_NOmem
/*============= internal functions ==============*/
static int qh_intcompare(const void *i, const void *j);
/*========== functions in alphabetical order ======== */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="intcompare">-</a>
qh_intcompare( i, j )
used by qsort and bsearch to compare two integers
*/
static int qh_intcompare(const void *i, const void *j) {
return(*((const int *)i) - *((const int *)j));
} /* intcompare */
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memalloc">-</a>
qh_memalloc( qh, insize )
returns object of insize bytes
qhmem is the global memory structure
returns:
pointer to allocated memory
errors if insufficient memory
notes:
use explicit type conversion to avoid type warnings on some compilers
actual object may be larger than insize
use qh_memalloc_() for inline code for quick allocations
logs allocations if 'T5'
caller is responsible for freeing the memory.
short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
design:
if size < qh->qhmem.LASTsize
if qh->qhmem.freelists[size] non-empty
return first object on freelist
else
round up request to size of qh->qhmem.freelists[size]
allocate new allocation buffer if necessary
allocate object from allocation buffer
else
allocate object with qh_malloc() in user.c
*/
void *qh_memalloc(qhT *qh, int insize) {
void **freelistp, *newbuffer;
int idx, size, n;
int outsize, bufsize;
void *object;
if (insize<0) {
qh_fprintf(qh, qh->qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
if (insize>=0 && insize <= qh->qhmem.LASTsize) {
idx= qh->qhmem.indextable[insize];
outsize= qh->qhmem.sizetable[idx];
qh->qhmem.totshort += outsize;
freelistp= qh->qhmem.freelists+idx;
if ((object= *freelistp)) {
qh->qhmem.cntquick++;
qh->qhmem.totfree -= outsize;
*freelistp= *((void **)*freelistp); /* replace freelist with next object */
#ifdef qh_TRACEshort
n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
#endif
return(object);
}else {
qh->qhmem.cntshort++;
if (outsize > qh->qhmem.freesize) {
qh->qhmem.totdropped += qh->qhmem.freesize;
if (!qh->qhmem.curbuffer)
bufsize= qh->qhmem.BUFinit;
else
bufsize= qh->qhmem.BUFsize;
if (!(newbuffer= qh_malloc((size_t)bufsize))) {
qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
*((void **)newbuffer)= qh->qhmem.curbuffer; /* prepend newbuffer to curbuffer
list. newbuffer!=0 by QH6080 */
qh->qhmem.curbuffer= newbuffer;
size= (sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
qh->qhmem.freemem= (void *)((char *)newbuffer+size);
qh->qhmem.freesize= bufsize - size;
qh->qhmem.totbuffer += bufsize - size; /* easier to check */
/* Periodically test totbuffer. It matches at beginning and exit of every call */
n = qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
if (qh->qhmem.totbuffer != n) {
qh_fprintf(qh, qh->qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
}
object= qh->qhmem.freemem;
qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
qh->qhmem.freesize -= outsize;
qh->qhmem.totunused += outsize - insize;
#ifdef qh_TRACEshort
n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
#endif
return object;
}
}else { /* long allocation */
if (!qh->qhmem.indextable) {
qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
}
outsize= insize;
qh->qhmem.cntlong++;
qh->qhmem.totlong += outsize;
if (qh->qhmem.maxlong < qh->qhmem.totlong)
qh->qhmem.maxlong= qh->qhmem.totlong;
if (!(object= qh_malloc((size_t)outsize))) {
qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, outsize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
}
return(object);
} /* memalloc */
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memcheck">-</a>
qh_memcheck(qh)
*/
void qh_memcheck(qhT *qh) {
int i, count, totfree= 0;
void *object;
if (!qh) {
qh_fprintf_stderr(6243, "qh_memcheck(qh) error: qh is 0. It does not point to a qhT");
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
qh_fprintf_stderr(6244, "qh_memcheck error: either qh->qhmem is overwritten or qh->qhmem is not initialized. Call qh_mem_new() or qh_new_qhull() before calling qh_mem routines. ferr 0x%x IsTracing %d ALIGNmask 0x%x", qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
if (qh->qhmem.IStracing != 0)
qh_fprintf(qh, qh->qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qh->qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem\n");
for (i=0; i < qh->qhmem.TABLEsize; i++) {
count=0;
for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
count++;
totfree += qh->qhmem.sizetable[i] * count;
}
if (totfree != qh->qhmem.totfree) {
qh_fprintf(qh, qh->qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
}
if (qh->qhmem.IStracing != 0)
qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
} /* memcheck */
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memfree">-</a>
qh_memfree(qh, object, insize )
free up an object of size bytes
size is insize from qh_memalloc
notes:
object may be NULL
type checking warns if using (void **)object
use qh_memfree_() for quick free's of small objects
design:
if size <= qh->qhmem.LASTsize
append object to corresponding freelist
else
call qh_free(object)
*/
void qh_memfree(qhT *qh, void *object, int insize) {
void **freelistp;
int idx, outsize;
if (!object)
return;
if (insize <= qh->qhmem.LASTsize) {
qh->qhmem.freeshort++;
idx= qh->qhmem.indextable[insize];
outsize= qh->qhmem.sizetable[idx];
qh->qhmem.totfree += outsize;
qh->qhmem.totshort -= outsize;
freelistp= qh->qhmem.freelists + idx;
*((void **)object)= *freelistp;
*freelistp= object;
#ifdef qh_TRACEshort
idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
#endif
}else {
qh->qhmem.freelong++;
qh->qhmem.totlong -= insize;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
qh_free(object);
}
} /* memfree */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memfreeshort">-</a>
qh_memfreeshort(qh, curlong, totlong )
frees up all short and qhmem memory allocations
returns:
number and size of current long allocations
notes:
if qh_NOmem (qh_malloc() for all allocations),
short objects (e.g., facetT) are not recovered.
use qh_freeqhull(qh, qh_ALL) instead.
see:
qh_freeqhull(qh, allMem)
qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
*/
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
void *buffer, *nextbuffer;
FILE *ferr;
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
*totlong= qh->qhmem.totlong;
for (buffer= qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
nextbuffer= *((void **) buffer);
qh_free(buffer);
}
qh->qhmem.curbuffer= NULL;
if (qh->qhmem.LASTsize) {
qh_free(qh->qhmem.indextable);
qh_free(qh->qhmem.freelists);
qh_free(qh->qhmem.sizetable);
}
ferr= qh->qhmem.ferr;
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
qh->qhmem.ferr= ferr;
} /* memfreeshort */
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="meminit">-</a>
qh_meminit(qh, ferr )
initialize qhmem and test sizeof( void*)
Does not throw errors. qh_exit on failure
*/
void qh_meminit(qhT *qh, FILE *ferr) {
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
if (ferr)
qh->qhmem.ferr= ferr;
else
qh->qhmem.ferr= stderr;
if (sizeof(void*) < sizeof(int)) {
qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
if (sizeof(void*) > sizeof(ptr_intT)) {
qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
qh_memcheck(qh);
} /* meminit */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="meminitbuffers">-</a>
qh_meminitbuffers(qh, tracelevel, alignment, numsizes, bufsize, bufinit )
initialize qhmem
if tracelevel >= 5, trace memory allocations
alignment= desired address alignment for memory allocations
numsizes= number of freelists
bufsize= size of additional memory buffers for short allocations
bufinit= size of initial memory buffer for short allocations
*/
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
qh->qhmem.IStracing= tracelevel;
qh->qhmem.NUMsizes= numsizes;
qh->qhmem.BUFsize= bufsize;
qh->qhmem.BUFinit= bufinit;
qh->qhmem.ALIGNmask= alignment-1;
if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
}
qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
if (qh->qhmem.IStracing >= 1)
qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
} /* meminitbuffers */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memsetup">-</a>
qh_memsetup(qh)
set up memory after running memsize()
*/
void qh_memsetup(qhT *qh) {
int k,i;
qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
if(qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
qh_fprintf(qh, qh->qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
if (!(qh->qhmem.indextable= (int *)qh_malloc((qh->qhmem.LASTsize+1) * sizeof(int)))) {
qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
for (k=qh->qhmem.LASTsize+1; k--; )
qh->qhmem.indextable[k]= k;
i= 0;
for (k=0; k <= qh->qhmem.LASTsize; k++) {
if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
qh->qhmem.indextable[k]= i;
else
qh->qhmem.indextable[k]= ++i;
}
} /* memsetup */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memsize">-</a>
qh_memsize(qh, size )
define a free list for this size
*/
void qh_memsize(qhT *qh, int size) {
int k;
if(qh->qhmem.LASTsize) {
qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
}
size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
for (k=qh->qhmem.TABLEsize; k--; ) {
if (qh->qhmem.sizetable[k] == size)
return;
}
if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
else
qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
} /* memsize */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memstatistics">-</a>
qh_memstatistics(qh, fp )
print out memory statistics
Verifies that qh->qhmem.totfree == sum of freelists
*/
void qh_memstatistics(qhT *qh, FILE *fp) {
int i;
int count;
void *object;
qh_memcheck(qh);
qh_fprintf(qh, fp, 9278, "\nmemory statistics:\n\
%7d quick allocations\n\
%7d short allocations\n\
%7d long allocations\n\
%7d short frees\n\
%7d long frees\n\
%7d bytes of short memory in use\n\
%7d bytes of short memory in freelists\n\
%7d bytes of dropped short memory\n\
%7d bytes of unused short memory (estimated)\n\
%7d bytes of long memory allocated (max, except for input)\n\
%7d bytes of long memory in use (in %d pieces)\n\
%7d bytes of short memory buffers (minus links)\n\
%7d bytes per short memory buffer (initially %d bytes)\n",
qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
qh->qhmem.freeshort, qh->qhmem.freelong,
qh->qhmem.totshort, qh->qhmem.totfree,
qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
if (qh->qhmem.cntlarger) {
qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
qh->qhmem.cntlarger, ((float)qh->qhmem.totlarger)/(float)qh->qhmem.cntlarger);
qh_fprintf(qh, fp, 9280, " freelists(bytes->count):");
}
for (i=0; i < qh->qhmem.TABLEsize; i++) {
count=0;
for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
count++;
qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
}
qh_fprintf(qh, fp, 9282, "\n\n");
} /* memstatistics */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
qh_NOmem
turn off quick-fit memory allocation
notes:
uses qh_malloc() and qh_free() instead
*/
#else /* qh_NOmem */
void *qh_memalloc(qhT *qh, int insize) {
void *object;
if (!(object= qh_malloc((size_t)insize))) {
qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
}
qh->qhmem.cntlong++;
qh->qhmem.totlong += insize;
if (qh->qhmem.maxlong < qh->qhmem.totlong)
qh->qhmem.maxlong= qh->qhmem.totlong;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
return object;
}
void qh_memfree(qhT *qh, void *object, int insize) {
if (!object)
return;
qh_free(object);
qh->qhmem.freelong++;
qh->qhmem.totlong -= insize;
if (qh->qhmem.IStracing >= 5)
qh_fprintf(qh, qh->qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
}
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
*totlong= qh->qhmem.totlong;
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
}
void qh_meminit(qhT *qh, FILE *ferr) {
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
if (ferr)
qh->qhmem.ferr= ferr;
else
qh->qhmem.ferr= stderr;
if (sizeof(void*) < sizeof(int)) {
qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
}
}
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
qh->qhmem.IStracing= tracelevel;
}
void qh_memsetup(qhT *qh) {
}
void qh_memsize(qhT *qh, int size) {
}
void qh_memstatistics(qhT *qh, FILE *fp) {
qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
%7d long allocations\n\
%7d long frees\n\
%7d bytes of long memory allocated (max, except for input)\n\
%7d bytes of long memory in use (in %d pieces)\n",
qh->qhmem.cntlong,
qh->qhmem.freelong,
qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
}
#endif /* qh_NOmem */
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="memtotlong">-</a>
qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
Return the total, allocated long and short memory
returns:
Returns the total current bytes of long and short allocations
Returns the current count of long and short allocations
Returns the maximum long memory and total short buffer (minus one link per buffer)
Does not error (for deprecated UsingLibQhull.cpp (libqhullpcpp))
*/
void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
*totlong= qh->qhmem.totlong;
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
*totshort= qh->qhmem.totshort;
*curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
*maxlong= qh->qhmem.maxlong;
*totbuffer= qh->qhmem.totbuffer;
} /* memtotlong */

View File

@@ -0,0 +1,234 @@
/*<html><pre> -<a href="qh-mem_r.htm"
>-------------------------------</a><a name="TOP">-</a>
mem_r.h
prototypes for memory management functions
see qh-mem_r.htm, mem_r.c and qset_r.h
for error handling, writes message and calls
qh_errexit(qhT *qh, qhmem_ERRmem, NULL, NULL) if insufficient memory
and
qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL) otherwise
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/mem_r.h#4 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFmem
#define qhDEFmem 1
#include <stdio.h>
#ifndef DEFsetT
#define DEFsetT 1
typedef struct setT setT; /* defined in qset_r.h */
#endif
#ifndef DEFqhT
#define DEFqhT 1
typedef struct qhT qhT; /* defined in libqhull_r.h */
#endif
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="NOmem">-</a>
qh_NOmem
turn off quick-fit memory allocation
notes:
mem_r.c implements Quickfit memory allocation for about 20% time
savings. If it fails on your machine, try to locate the
problem, and send the answer to qhull@qhull.org. If this can
not be done, define qh_NOmem to use malloc/free instead.
#define qh_NOmem
*/
/*-<a href="qh-mem_r.htm#TOC"
>-------------------------------</a><a name="TRACEshort">-</a>
qh_TRACEshort
Trace short and quick memory allocations at T5
*/
#define qh_TRACEshort
/*-------------------------------------------
to avoid bus errors, memory allocation must consider alignment requirements.
malloc() automatically takes care of alignment. Since mem_r.c manages
its own memory, we need to explicitly specify alignment in
qh_meminitbuffers().
A safe choice is sizeof(double). sizeof(float) may be used if doubles
do not occur in data structures and pointers are the same size. Be careful
of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
*/
#define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull_r.h */
#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull_r.h */
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="ptr_intT">-</a>
ptr_intT
for casting a void * to an integer-type that holds a pointer
Used for integer expressions (e.g., computing qh_gethash() in poly_r.c)
notes:
WARN64 -- these notes indicate 64-bit issues
On 64-bit machines, a pointer may be larger than an 'int'.
qh_meminit()/mem_r.c checks that 'ptr_intT' holds a 'void*'
ptr_intT is typically a signed value, but not necessarily so
size_t is typically unsigned, but should match the parameter type
Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
This matches Qt convention and is easier to work with.
*/
#if (defined(__MINGW64__)) && defined(_WIN64)
typedef long long ptr_intT;
#elif (_MSC_VER) && defined(_WIN64)
typedef long long ptr_intT;
#else
typedef long ptr_intT;
#endif
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="qhmemT">-</a>
qhmemT
global memory structure for mem_r.c
notes:
users should ignore qhmem except for writing extensions
qhmem is allocated in mem_r.c
qhmem could be swapable like qh and qhstat, but then
multiple qh's and qhmem's would need to keep in synch.
A swapable qhmem would also waste memory buffers. As long
as memory operations are atomic, there is no problem with
multiple qh structures being active at the same time.
If you need separate address spaces, you can swap the
contents of qh->qhmem.
*/
typedef struct qhmemT qhmemT;
/* Update qhmem in mem_r.c if add or remove fields */
struct qhmemT { /* global memory management variables */
int BUFsize; /* size of memory allocation buffer */
int BUFinit; /* initial size of memory allocation buffer */
int TABLEsize; /* actual number of sizes in free list table */
int NUMsizes; /* maximum number of sizes in free list table */
int LASTsize; /* last size in free list table */
int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
void **freelists; /* free list table, linked by offset 0 */
int *sizetable; /* size of each freelist */
int *indextable; /* size->index table */
void *curbuffer; /* current buffer, linked by offset 0 */
void *freemem; /* free memory in curbuffer */
int freesize; /* size of freemem in bytes */
setT *tempstack; /* stack of temporary memory, managed by users */
FILE *ferr; /* file for reporting errors when 'qh' may be undefined */
int IStracing; /* =5 if tracing memory allocations */
int cntquick; /* count of quick allocations */
/* Note: removing statistics doesn't effect speed */
int cntshort; /* count of short allocations */
int cntlong; /* count of long allocations */
int freeshort; /* count of short memfrees */
int freelong; /* count of long memfrees */
int totbuffer; /* total short memory buffers minus buffer links */
int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */
int totfree; /* total size of free, short memory on freelists */
int totlong; /* total size of long memory in use */
int maxlong; /* maximum totlong */
int totshort; /* total size of short memory in use */
int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */
int cntlarger; /* count of setlarger's */
int totlarger; /* total copied by setlarger */
};
/*==================== -macros ====================*/
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memalloc_">-</a>
qh_memalloc_(qh, insize, freelistp, object, type)
returns object of size bytes
assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
*/
#if defined qh_NOmem
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
object= (type*)qh_memalloc(qh, insize); }
#elif defined qh_TRACEshort
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
freelistp= NULL; /* Avoid warnings */ \
object= (type*)qh_memalloc(qh, insize); }
#else /* !qh_NOmem */
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
if ((object= (type*)*freelistp)) {\
qh->qhmem.totshort += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
qh->qhmem.totfree -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
qh->qhmem.cntquick++; \
*freelistp= *((void **)*freelistp);\
}else object= (type*)qh_memalloc(qh, insize);}
#endif
/*-<a href="qh-mem_r.htm#TOC"
>--------------------------------</a><a name="memfree_">-</a>
qh_memfree_(qh, object, insize, freelistp)
free up an object
notes:
object may be NULL
assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
*/
#if defined qh_NOmem
#define qh_memfree_(qh, object, insize, freelistp) {\
qh_memfree(qh, object, insize); }
#elif defined qh_TRACEshort
#define qh_memfree_(qh, object, insize, freelistp) {\
freelistp= NULL; /* Avoid warnings */ \
qh_memfree(qh, object, insize); }
#else /* !qh_NOmem */
#define qh_memfree_(qh, object, insize, freelistp) {\
if (object) { \
qh->qhmem.freeshort++;\
freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
qh->qhmem.totshort -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
qh->qhmem.totfree += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
*((void **)object)= *freelistp;\
*freelistp= object;}}
#endif
/*=============== prototypes in alphabetical order ============*/
#ifdef __cplusplus
extern "C" {
#endif
void *qh_memalloc(qhT *qh, int insize);
void qh_memcheck(qhT *qh);
void qh_memfree(qhT *qh, void *object, int insize);
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
void qh_meminit(qhT *qh, FILE *ferr);
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes,
int bufsize, int bufinit);
void qh_memsetup(qhT *qh);
void qh_memsize(qhT *qh, int size);
void qh_memstatistics(qhT *qh, FILE *fp);
void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFmem */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,186 @@
/*<html><pre> -<a href="qh-merge_r.htm"
>-------------------------------</a><a name="TOP">-</a>
merge_r.h
header file for merge_r.c
see qh-merge_r.htm and merge_r.c
Copyright (c) 1993-2015 C.B. Barber.
$Id: //main/2015/qhull/src/libqhull_r/merge_r.h#3 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFmerge
#define qhDEFmerge 1
#include "libqhull_r.h"
/*============ -constants- ==============*/
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEredundant">-</a>
qh_ANGLEredundant
indicates redundant merge in mergeT->angle
*/
#define qh_ANGLEredundant 6.0
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEdegen">-</a>
qh_ANGLEdegen
indicates degenerate facet in mergeT->angle
*/
#define qh_ANGLEdegen 5.0
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="qh_ANGLEconcave">-</a>
qh_ANGLEconcave
offset to indicate concave facets in mergeT->angle
notes:
concave facets are assigned the range of [2,4] in mergeT->angle
roundoff error may make the angle less than 2
*/
#define qh_ANGLEconcave 1.5
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="MRG">-</a>
MRG... (mergeType)
indicates the type of a merge (mergeT->type)
*/
typedef enum { /* in sort order for facet_mergeset */
MRGnone= 0,
MRGcoplanar, /* centrum coplanar */
MRGanglecoplanar, /* angle coplanar */
/* could detect half concave ridges */
MRGconcave, /* concave ridge */
MRGflip, /* flipped facet. facet1 == facet2 */
MRGridge, /* duplicate ridge (qh_MERGEridge) */
/* degen and redundant go onto degen_mergeset */
MRGdegen, /* degenerate facet (!enough neighbors) facet1 == facet2 */
MRGredundant, /* redundant facet (vertex subset) */
/* merge_degenredundant assumes degen < redundant */
MRGmirror, /* mirror facet from qh_triangulate */
ENDmrg
} mergeType;
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="qh_MERGEapex">-</a>
qh_MERGEapex
flag for qh_mergefacet() to indicate an apex merge
*/
#define qh_MERGEapex True
/*============ -structures- ====================*/
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="mergeT">-</a>
mergeT
structure used to merge facets
*/
typedef struct mergeT mergeT;
struct mergeT { /* initialize in qh_appendmergeset */
realT angle; /* angle between normals of facet1 and facet2 */
facetT *facet1; /* will merge facet1 into facet2 */
facetT *facet2;
mergeType type;
};
/*=========== -macros- =========================*/
/*-<a href="qh-merge_r.htm#TOC"
>--------------------------------</a><a name="FOREACHmerge_">-</a>
FOREACHmerge_( merges ) {...}
assign 'merge' to each merge in merges
notes:
uses 'mergeT *merge, **mergep;'
if qh_mergefacet(),
restart since qh.facet_mergeset may change
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
/*============ prototypes in alphabetical order after pre/postmerge =======*/
#ifdef __cplusplus
extern "C" {
#endif
void qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle);
void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
boolT vneighbors);
void qh_all_merges(qhT *qh, boolT othermerge, boolT vneighbors);
void qh_appendmergeset(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
setT *qh_basevertices(qhT *qh, facetT *samecycle);
void qh_checkconnect(qhT *qh /* qh.new_facets */);
boolT qh_checkzero(qhT *qh, boolT testall);
int qh_compareangle(const void *p1, const void *p2);
int qh_comparemerge(const void *p1, const void *p2);
int qh_comparevisit(const void *p1, const void *p2);
void qh_copynonconvex(qhT *qh, ridgeT *atridge);
void qh_degen_redundant_facet(qhT *qh, facetT *facet);
void qh_degen_redundant_neighbors(qhT *qh, facetT *facet, facetT *delfacet);
vertexT *qh_find_newvertex(qhT *qh, vertexT *oldvertex, setT *vertices, setT *ridges);
void qh_findbest_test(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
facetT *qh_findbestneighbor(qhT *qh, facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
void qh_flippedmerges(qhT *qh, facetT *facetlist, boolT *wasmerge);
void qh_forcedmerges(qhT *qh, boolT *wasmerge);
void qh_getmergeset(qhT *qh, facetT *facetlist);
void qh_getmergeset_initial(qhT *qh, facetT *facetlist);
void qh_hashridge(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
ridgeT *qh_hashridge_find(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
vertexT *vertex, vertexT *oldvertex, int *hashslot);
void qh_makeridges(qhT *qh, facetT *facet);
void qh_mark_dupridges(qhT *qh, facetT *facetlist);
void qh_maydropneighbor(qhT *qh, facetT *facet);
int qh_merge_degenredundant(qhT *qh);
void qh_merge_nonconvex(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype);
void qh_mergecycle(qhT *qh, facetT *samecycle, facetT *newfacet);
void qh_mergecycle_all(qhT *qh, facetT *facetlist, boolT *wasmerge);
void qh_mergecycle_facets(qhT *qh, facetT *samecycle, facetT *newfacet);
void qh_mergecycle_neighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
void qh_mergecycle_ridges(qhT *qh, facetT *samecycle, facetT *newfacet);
void qh_mergecycle_vneighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
void qh_mergefacet(qhT *qh, facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
void qh_mergefacet2d(qhT *qh, facetT *facet1, facetT *facet2);
void qh_mergeneighbors(qhT *qh, facetT *facet1, facetT *facet2);
void qh_mergeridges(qhT *qh, facetT *facet1, facetT *facet2);
void qh_mergesimplex(qhT *qh, facetT *facet1, facetT *facet2, boolT mergeapex);
void qh_mergevertex_del(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2);
void qh_mergevertex_neighbors(qhT *qh, facetT *facet1, facetT *facet2);
void qh_mergevertices(qhT *qh, setT *vertices1, setT **vertices);
setT *qh_neighbor_intersections(qhT *qh, vertexT *vertex);
void qh_newvertices(qhT *qh, setT *vertices);
boolT qh_reducevertices(qhT *qh);
vertexT *qh_redundant_vertex(qhT *qh, vertexT *vertex);
boolT qh_remove_extravertices(qhT *qh, facetT *facet);
vertexT *qh_rename_sharedvertex(qhT *qh, vertexT *vertex, facetT *facet);
void qh_renameridgevertex(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
void qh_renamevertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, setT *ridges,
facetT *oldfacet, facetT *neighborA);
boolT qh_test_appendmerge(qhT *qh, facetT *facet, facetT *neighbor);
boolT qh_test_vneighbors(qhT *qh /* qh.newfacet_list */);
void qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2);
void qh_tracemerging(qhT *qh);
void qh_updatetested(qhT *qh, facetT *facet1, facetT *facet2);
setT *qh_vertexridges(qhT *qh, vertexT *vertex);
void qh_vertexridges_facet(qhT *qh, vertexT *vertex, facetT *facet, setT **ridges);
void qh_willdelete(qhT *qh, facetT *facet, facetT *replace);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFmerge */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,303 @@
/*<html><pre> -<a href="qh-poly_r.htm"
>-------------------------------</a><a name="TOP">-</a>
poly_r.h
header file for poly_r.c and poly2_r.c
see qh-poly_r.htm, libqhull_r.h and poly_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/poly_r.h#5 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFpoly
#define qhDEFpoly 1
#include "libqhull_r.h"
/*=============== constants ========================== */
/*-<a href="qh-geom_r.htm#TOC"
>--------------------------------</a><a name="ALGORITHMfault">-</a>
ALGORITHMfault
use as argument to checkconvex() to report errors during buildhull
*/
#define qh_ALGORITHMfault 0
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="DATAfault">-</a>
DATAfault
use as argument to checkconvex() to report errors during initialhull
*/
#define qh_DATAfault 1
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="DUPLICATEridge">-</a>
DUPLICATEridge
special value for facet->neighbor to indicate a duplicate ridge
notes:
set by matchneighbor, used by matchmatch and mark_dupridge
*/
#define qh_DUPLICATEridge (facetT *)1L
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="MERGEridge">-</a>
MERGEridge flag in facet
special value for facet->neighbor to indicate a merged ridge
notes:
set by matchneighbor, used by matchmatch and mark_dupridge
*/
#define qh_MERGEridge (facetT *)2L
/*============ -structures- ====================*/
/*=========== -macros- =========================*/
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLfacet_">-</a>
FORALLfacet_( facetlist ) { ... }
assign 'facet' to each facet in facetlist
notes:
uses 'facetT *facet;'
assumes last facet is a sentinel
see:
FORALLfacets
*/
#define FORALLfacet_( facetlist ) if (facetlist ) for ( facet=( facetlist ); facet && facet->next; facet= facet->next )
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLnew_facets">-</a>
FORALLnew_facets { ... }
assign 'newfacet' to each facet in qh.newfacet_list
notes:
uses 'facetT *newfacet;'
at exit, newfacet==NULL
*/
#define FORALLnew_facets for ( newfacet=qh->newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLvertex_">-</a>
FORALLvertex_( vertexlist ) { ... }
assign 'vertex' to each vertex in vertexlist
notes:
uses 'vertexT *vertex;'
at exit, vertex==NULL
*/
#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLvisible_facets">-</a>
FORALLvisible_facets { ... }
assign 'visible' to each visible facet in qh.visible_list
notes:
uses 'vacetT *visible;'
at exit, visible==NULL
*/
#define FORALLvisible_facets for (visible=qh->visible_list; visible && visible->visible; visible= visible->next)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLsame_">-</a>
FORALLsame_( newfacet ) { ... }
assign 'same' to each facet in newfacet->f.samecycle
notes:
uses 'facetT *same;'
stops when it returns to newfacet
*/
#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FORALLsame_cycle_">-</a>
FORALLsame_cycle_( newfacet ) { ... }
assign 'same' to each facet in newfacet->f.samecycle
notes:
uses 'facetT *same;'
at exit, same == NULL
*/
#define FORALLsame_cycle_(newfacet) \
for (same= newfacet->f.samecycle; \
same; same= (same == newfacet ? NULL : same->f.samecycle))
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FOREACHneighborA_">-</a>
FOREACHneighborA_( facet ) { ... }
assign 'neighborA' to each neighbor in facet->neighbors
FOREACHneighborA_( vertex ) { ... }
assign 'neighborA' to each neighbor in vertex->neighbors
declare:
facetT *neighborA, **neighborAp;
see:
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FOREACHvisible_">-</a>
FOREACHvisible_( facets ) { ... }
assign 'visible' to each facet in facets
notes:
uses 'facetT *facet, *facetp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FOREACHnewfacet_">-</a>
FOREACHnewfacet_( facets ) { ... }
assign 'newfacet' to each facet in facets
notes:
uses 'facetT *newfacet, *newfacetp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexA_">-</a>
FOREACHvertexA_( vertices ) { ... }
assign 'vertexA' to each vertex in vertices
notes:
uses 'vertexT *vertexA, *vertexAp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
/*-<a href="qh-poly_r.htm#TOC"
>--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
FOREACHvertexreverse12_( vertices ) { ... }
assign 'vertex' to each vertex in vertices
reverse order of first two vertices
notes:
uses 'vertexT *vertex, *vertexp;'
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
*/
#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
/*=============== prototypes poly_r.c in alphabetical order ================*/
#ifdef __cplusplus
extern "C" {
#endif
void qh_appendfacet(qhT *qh, facetT *facet);
void qh_appendvertex(qhT *qh, vertexT *vertex);
void qh_attachnewfacets(qhT *qh /* qh.visible_list, qh.newfacet_list */);
boolT qh_checkflipped(qhT *qh, facetT *facet, realT *dist, boolT allerror);
void qh_delfacet(qhT *qh, facetT *facet);
void qh_deletevisible(qhT *qh /* qh.visible_list, qh.horizon_list */);
setT *qh_facetintersect(qhT *qh, facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
int qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem);
facetT *qh_makenewfacet(qhT *qh, setT *vertices, boolT toporient, facetT *facet);
void qh_makenewplanes(qhT *qh /* qh.newfacet_list */);
facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
facetT *qh_makenew_simplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
void qh_matchneighbor(qhT *qh, facetT *newfacet, int newskip, int hashsize,
int *hashcount);
void qh_matchnewfacets(qhT *qh);
boolT qh_matchvertices(qhT *qh, int firstindex, setT *verticesA, int skipA,
setT *verticesB, int *skipB, boolT *same);
facetT *qh_newfacet(qhT *qh);
ridgeT *qh_newridge(qhT *qh);
int qh_pointid(qhT *qh, pointT *point);
void qh_removefacet(qhT *qh, facetT *facet);
void qh_removevertex(qhT *qh, vertexT *vertex);
void qh_updatevertices(qhT *qh);
/*========== -prototypes poly2_r.c in alphabetical order ===========*/
void qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash);
void qh_check_bestdist(qhT *qh);
void qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2);
void qh_check_maxout(qhT *qh);
void qh_check_output(qhT *qh);
void qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
void qh_check_points(qhT *qh);
void qh_checkconvex(qhT *qh, facetT *facetlist, int fault);
void qh_checkfacet(qhT *qh, facetT *facet, boolT newmerge, boolT *waserrorp);
void qh_checkflipped_all(qhT *qh, facetT *facetlist);
void qh_checkpolygon(qhT *qh, facetT *facetlist);
void qh_checkvertex(qhT *qh, vertexT *vertex);
void qh_clearcenters(qhT *qh, qh_CENTER type);
void qh_createsimplex(qhT *qh, setT *vertices);
void qh_delridge(qhT *qh, ridgeT *ridge);
void qh_delvertex(qhT *qh, vertexT *vertex);
setT *qh_facet3vertex(qhT *qh, facetT *facet);
facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
realT *bestdist, boolT *isoutside);
facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
facetT *qh_findfacet_all(qhT *qh, pointT *point, realT *bestdist, boolT *isoutside,
int *numpart);
int qh_findgood(qhT *qh, facetT *facetlist, int goodhorizon);
void qh_findgood_all(qhT *qh, facetT *facetlist);
void qh_furthestnext(qhT *qh /* qh.facet_list */);
void qh_furthestout(qhT *qh, facetT *facet);
void qh_infiniteloop(qhT *qh, facetT *facet);
void qh_initbuild(qhT *qh);
void qh_initialhull(qhT *qh, setT *vertices);
setT *qh_initialvertices(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints);
vertexT *qh_isvertex(pointT *point, setT *vertices);
vertexT *qh_makenewfacets(qhT *qh, pointT *point /*horizon_list, visible_list*/);
void qh_matchduplicates(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount);
void qh_nearcoplanar(qhT *qh /* qh.facet_list */);
vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
int qh_newhashtable(qhT *qh, int newsize);
vertexT *qh_newvertex(qhT *qh, pointT *point);
ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
void qh_outcoplanar(qhT *qh /* qh.facet_list */);
pointT *qh_point(qhT *qh, int id);
void qh_point_add(qhT *qh, setT *set, pointT *point, void *elem);
setT *qh_pointfacet(qhT *qh /*qh.facet_list*/);
setT *qh_pointvertex(qhT *qh /*qh.facet_list*/);
void qh_prependfacet(qhT *qh, facetT *facet, facetT **facetlist);
void qh_printhashtable(qhT *qh, FILE *fp);
void qh_printlists(qhT *qh);
void qh_resetlists(qhT *qh, boolT stats, boolT resetVisible /*qh.newvertex_list qh.newfacet_list qh.visible_list*/);
void qh_setvoronoi_all(qhT *qh);
void qh_triangulate(qhT *qh /*qh.facet_list*/);
void qh_triangulate_facet(qhT *qh, facetT *facetA, vertexT **first_vertex);
void qh_triangulate_link(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
void qh_triangulate_mirror(qhT *qh, facetT *facetA, facetT *facetB);
void qh_triangulate_null(qhT *qh, facetT *facetA);
void qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB);
setT *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB);
void qh_vertexneighbors(qhT *qh /*qh.facet_list*/);
boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFpoly */

View File

@@ -0,0 +1,295 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>geom_r.c, geom2_r.c -- geometric and floating point routines</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm#TOC">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
<h2>geom_r.c, geom2_r.c, random_r.c -- geometric and floating point routines</h2>
<blockquote>
<p>Geometrically, a vertex is a point with <em>d</em> coordinates
and a facet is a halfspace. A <em>halfspace</em> is defined by an
oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
is defined by <em>d</em> normalized coefficients and an offset. A
point is <em>above</em> a facet if its distance to the facet is
positive.</p>
<p>Qhull uses floating point coordinates for input points,
vertices, halfspace equations, centrums, and an interior point.</p>
<p>Qhull may be configured for single precision or double
precision floating point arithmetic (see <a href="user_r.h#realT">realT</a>
). </p>
<p>Each floating point operation may incur round-off error (see
<a href="qh-merge_r.htm#TOC">Merge</a>). The maximum error for distance
computations is determined at initialization. The roundoff error
in halfspace computation is accounted for by computing the
distance from vertices to the halfspace. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <b>Geom</b>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
<h3>Index to <a href="geom_r.c">geom_r.c</a>,
<a href="geom2_r.c">geom2_r.c</a>, <a href="geom_r.h">geom_r.h</a>,
<a href="random_r.c">random_r.c</a>, <a href="random_r.h">random_r.h</a>
</h3>
<ul>
<li><a href="#gtype">geometric data types and constants</a> </li>
<li><a href="#gmacro">mathematical macros</a>
</li>
<li><a href="#gmath">mathematical functions</a> </li>
<li><a href="#gcomp">computational geometry functions</a> </li>
<li><a href="#gpoint">point array functions</a> </li>
<li><a href="#gfacet">geometric facet functions</a> </li>
<li><a href="#ground">geometric roundoff functions</a></li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gtype">geometric data types
and constants</a></h3>
<ul>
<li><a href="libqhull_r.h#coordT">coordT</a> coordinates and
coefficients are stored as realT</li>
<li><a href="libqhull_r.h#pointT">pointT</a> a point is an array
of <tt>DIM3</tt> coordinates </li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
<ul>
<li><a href="geom_r.h#fabs_">fabs_</a> returns the absolute
value of a </li>
<li><a href="geom_r.h#fmax_">fmax_</a> returns the maximum
value of a and b </li>
<li><a href="geom_r.h#fmin_">fmin_</a> returns the minimum
value of a and b </li>
<li><a href="geom_r.h#maximize_">maximize_</a> maximize a value
</li>
<li><a href="geom_r.h#minimize_">minimize_</a> minimize a value
</li>
<li><a href="geom_r.h#det2_">det2_</a> compute a 2-d
determinate </li>
<li><a href="geom_r.h#det3_">det3_</a> compute a 3-d
determinate </li>
<li><a href="geom_r.h#dX">dX, dY, dZ</a> compute the difference
between two coordinates </li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
<ul>
<li><a href="geom_r.c#backnormal">qh_backnormal</a> solve for
normal using back substitution </li>
<li><a href="geom2_r.c#crossproduct">qh_crossproduct</a>
compute the cross product of two 3-d vectors </li>
<li><a href="geom2_r.c#determinant">qh_determinant</a> compute
the determinant of a square matrix </li>
<li><a href="geom_r.c#gausselim">qh_gausselim</a> Gaussian
elimination with partial pivoting </li>
<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
implements Gram-Schmidt orthogonalization by rows </li>
<li><a href="geom2_r.c#maxabsval">qh_maxabsval</a> return max
absolute value of a vector </li>
<li><a href="geom2_r.c#minabsval">qh_minabsval</a> return min
absolute value of a dim vector </li>
<li><a href="geom2_r.c#mindiff">qh_mindiff</a> return index of
min absolute difference of two vectors </li>
<li><a href="geom_r.c#normalize">qh_normalize</a> normalize a
vector </li>
<li><a href="geom_r.c#normalize2">qh_normalize2</a> normalize a
vector and report if too small </li>
<li><a href="geom2_r.c#printmatrix">qh_printmatrix</a> print
matrix given by row vectors </li>
<li><a href="random_r.c#rand">qh_rand/srand</a> generate random
numbers </li>
<li><a href="random_r.c#randomfactor">qh_randomfactor</a> return
a random factor near 1.0 </li>
<li><a href="random_r.c#randommatrix">qh_randommatrix</a>
generate a random dimXdim matrix in range (-1,1) </li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
<ul>
<li><a href="geom2_r.c#detsimplex">qh_detsimplex</a> compute
determinate of a simplex of points </li>
<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
<li><a href="geom2_r.c#distnorm">qh_distnorm</a> compute
distance from point to hyperplane as defined by normal and offset</li>
<li><a href="geom2_r.c#facetarea_simplex">qh_facetarea_simplex</a>
return area of a simplex</li>
<li><a href="geom_r.c#getangle">qh_getangle</a> return cosine
of angle (i.e., dot product) </li>
<li><a href="geom_r.c#getcenter">qh_getcenter</a> return
arithmetic center for a set of vertices </li>
<li><a href="geom2_r.c#pointdist">qh_pointdist</a> return
distance between two points </li>
<li><a href="geom2_r.c#rotatepoints">qh_rotatepoints</a> rotate
numpoints points by a row matrix </li>
<li><a href="geom2_r.c#sethalfspace">qh_sethalfspace</a> set
coords to dual of halfspace relative to an interior point </li>
<li><a href="geom_r.c#sethyperplane_det">qh_sethyperplane_det</a>
return hyperplane for oriented simplex using determinates
</li>
<li><a href="geom_r.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
return hyperplane for oriented simplex using Gaussian
elimination </li>
<li><a href="geom2_r.c#voronoi_center">qh_voronoi_center</a>
return Voronoi center for a set of points </li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
<ul>
<li><a href="geom2_r.c#copypoints">qh_copypoints</a> return
malloc'd copy of points</li>
<li><a href="geom2_r.c#joggleinput">qh_joggleinput</a> joggle
input points by qh.JOGGLEmax </li>
<li><a href="geom2_r.c#maxmin">qh_maxmin</a> return max/min
points for each dimension</li>
<li><a href="geom2_r.c#maxsimplex">qh_maxsimplex</a> determines
maximum simplex for a set of points </li>
<li><a href="geom2_r.c#printpoints">qh_printpoints</a> print ids for a
set of points </li>
<li><a href="geom2_r.c#projectinput">qh_projectinput</a> project
input using qh DELAUNAY and qh low_bound/high_bound </li>
<li><a href="geom2_r.c#projectpoints">qh_projectpoints</a>
project points along one or more dimensions </li>
<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
input points using row matrix </li>
<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
input points using qh low_bound/high_bound </li>
<li><a href="geom2_r.c#scalelast">qh_scalelast</a> scale last
coordinate to [0,m] for Delaunay triangulations </li>
<li><a href="geom2_r.c#scalepoints">qh_scalepoints</a> scale
points to new lowbound and highbound </li>
<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
points to paraboloid for Delaunay triangulation </li>
<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
generate dual for halfspace intersection with interior
point </li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
<ul>
<li><a href="geom_r.c#distplane">qh_distplane</a> return
distance from point to facet </li>
<li><a href="geom2_r.c#facetarea">qh_facetarea</a> return area
of a facet </li>
<li><a href="geom2_r.c#facetcenter">qh_facetcenter</a> return
Voronoi center for a facet's vertices </li>
<li><a href="geom_r.c#findbest">qh_findbest</a> find visible
facet or best facet for a point </li>
<li><a href="geom_r.c#findbesthorizon">qh_findbesthorizon</a>
update best new facet with horizon facets</li>
<li><a href="geom_r.c#findbestnew">qh_findbestnew</a> find best
new facet for point </li>
<li><a href="geom2_r.c#getarea">qh_getarea</a> get area of all
facets in facetlist, collect statistics </li>
<li><a href="geom_r.c#getcentrum">qh_getcentrum</a> return
centrum for a facet </li>
<li><a href="geom_r.c#getdistance">qh_getdistance</a> returns
the max and min distance of a facet's vertices to a
neighboring facet</li>
<li><a href="geom2_r.c#findgooddist">qh_findgooddist</a> find
best good facet visible for point from facet </li>
<li><a href="geom2_r.c#inthresholds">qh_inthresholds</a> return
True if facet normal within 'Pdn' and 'PDn'</li>
<li><a href="geom2_r.c#orientoutside">qh_orientoutside</a>
orient facet so that <tt>qh.interior_point</tt> is inside</li>
<li><a href="geom_r.c#projectpoint">qh_projectpoint</a> project
point onto a facet </li>
<li><a href="geom_r.c#setfacetplane">qh_setfacetplane</a> sets
the hyperplane for a facet </li>
<li><a href="geom2_r.c#sharpnewfacets">qh_sharpnewfacets</a> true
if new facets contains a sharp corner</li>
</ul>
<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
<ul>
<li><a href="geom2_r.c#detjoggle">qh_detjoggle</a> determine
default joggle for points and distance roundoff error</li>
<li><a href="geom2_r.c#detroundoff">qh_detroundoff</a>
determine maximum roundoff error and other precision constants</li>
<li><a href="geom2_r.c#distround">qh_distround</a> compute
maximum roundoff error due to a distance computation to a
normalized hyperplane</li>
<li><a href="geom2_r.c#divzero">qh_divzero</a> divide by a
number that is nearly zero </li>
<li><a href="geom2_r.c#maxouter">qh_maxouter</a> return maximum outer
plane</li>
<li><a href="geom2_r.c#outerinner">qh_outerinner</a> return actual
outer and inner planes
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,163 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>global_r.c -- global variables and their functions</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<!-- Main text of document. -->
<h2>global_r.c -- global variables and their functions</h2>
<blockquote>
<p>Qhull uses a data structure, <tt>qhT</tt>, to store
globally defined constants, lists, sets, and variables. It is passed as the
first argument to most functions.
</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <b>Global</b> &#149;
<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
<h3>Index to <a href="global_r.c">global_r.c</a> and
<a href="libqhull_r.h">libqhull_r.h</a></h3>
<ul>
<li><a href="#ovar">Qhull's global variables</a> </li>
<li><a href="#ofunc">Global variable and initialization
routines</a> </li>
</ul>
<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ovar">Qhull's global
variables</a></h3>
<ul>
<li><a href=global_r.c#qh_version>qh_version</a> version string
<li><a href="libqhull_r.h#qh">qh</a> all global variables for
qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
<li><a href="libqhull_r.h#qh">QHULL_LIB_CHECK</a> Check for compatible library</li>
<li><a href="libqhull_r.h#qh-const">qh constants</a> configuration
flags and constants for Qhull </li>
<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
<li><a href="libqhull_r.h#qh-codetern">qh internal constants</a>
internal constants for Qhull </li>
<li><a href="libqhull_r.h#qh-lists">qh facet and vertex lists</a>
lists of facets and vertices </li>
<li><a href="libqhull_r.h#qh-var">qh global variables</a> minimum
and maximum distances, next visit ids, several flags, and
other global variables. </li>
<li><a href="libqhull_r.h#qh-set">qh global sets</a> global sets
for merging, hashing, input, etc. </li>
<li><a href="libqhull_r.h#qh-buf">qh global buffers</a> buffers
for matrix operations and input </li>
<li><a href="libqhull_r.h#qh-static">qh static variables</a>
static variables for individual functions </li>
</ul>
<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ofunc">Global variable and
initialization routines</a></h3>
<ul>
<li><a href="global_r.c#appendprint">qh_appendprint</a> append
output format to <tt>qh.PRINTout</tt> </li>
<li><a href="global_r.c#freebuffers">qh_freebuffers</a> free
global memory buffers </li>
<li><a href="global_r.c#freeqhull">qh_freeqhull</a> free memory
used by qhull </li>
<li><a href="global_r.c#init_A">qh_init_A</a> called before
error handling initialized </li>
<li><a href="global_r.c#init_B">qh_init_B</a> called after
points are defined </li>
<li><a href="global_r.c#init_qhull_command">qh_init_qhull_command</a>
build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
<li><a href="global_r.c#initflags">qh_initflags</a> set flags
and constants from command line </li>
<li><a href="global_r.c#initqhull_buffers">qh_initqhull_buffers</a>
initialize global memory buffers </li>
<li><a href="global_r.c#initqhull_globals">qh_initqhull_globals</a>
initialize global variables </li>
<li><a href="global_r.c#initqhull_mem">qh_initqhull_mem</a>
initialize Qhull memory management </li>
<li><a href="global_r.c#initqhull_start">qh_initqhull_start</a>
allocate qh_qh and call qh_initqhull_start2()
<li><a href="global_r.c#initqhull_start2">qh_initqhull_start2</a>
initialize default values at Qhull startup </li>
<li><a href="global_r.c#initthresholds">qh_initthresholds</a>
initialize 'Pdn' and 'PDn' thresholds </li>
<li><a href="global_r.c#lib_check">qh_lib_check</a> check for compatible Qhull library. Invoked by QHULL_LIB_CHECK at start of each program.</li>
<li><a href="global_r.c#option">qh_option</a> append option
description to <tt>qh.global_options</tt> </li>
<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
restores a previously saved qhull </li>
<li><a href="global_r.c#save_qhull">qh_save_qhull</a> saves
qhull for a later qh_restore_qhull() </li>
<li><a href="global_r.c#strtol">qh_strtol</a> duplicates
strtod() and strtol() </li>
<li><a href="global_r.c#zero">qh_zero</a> zeroes qhT before first use</li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,305 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>io_r.c -- input and output operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>io_r.c -- input and output operations</h2>
<blockquote>
<p>Qhull provides a wide range of input
and output options. To organize the code, most output formats use
the same driver: </p>
<pre>
qh_printbegin( fp, format, facetlist, facets, printall );
FORALLfacet_( facetlist )
qh_printafacet( fp, format, facet, printall );
FOREACHfacet_( facets )
qh_printafacet( fp, format, facet, printall );
qh_printend( fp, format );
</pre>
<p>Note the 'printall' flag. It selects whether or not
qh_skipfacet() is tested. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
<a href="qh-globa_r.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
<a href="qh-mem_r.htm#TOC">Mem</a> &#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149;
<a href="qh-poly_r.htm#TOC">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149;
<a href="qh-set_r.htm#TOC">Set</a> &#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149;
<a href="qh-user_r.htm#TOC">User</a> </p>
<h3>Index to <a href="io_r.c">io_r.c</a> and <a href="io_r.h">io_r.h</a></h3>
<ul>
<li><a href="#iconst">io_r.h constants and types</a> </li>
<li><a href="#ilevel">User level functions</a> </li>
<li><a href="#iprint">Print functions for all output formats</a></li>
<li><a href="#itext">Text output functions</a> </li>
<li><a href="#iutil">Text utility functions</a></li>
<li><a href="#igeom">Geomview output functions</a> </li>
<li><a href="#iview">Geomview utility functions</a></li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iconst">io_r.h constants and types</a></h3>
<ul>
<li><a href="io_r.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
of first two lines of stdin </li>
<li><a href="io_r.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
values of white space </li>
<li><a href="io_r.h#printvridgeT">printvridgeT</a> function to
print results of qh_printvdiagram or qh_eachvoronoi</li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
<ul>
<li><a href="io_r.c#copyfilename">qh_copyfilename</a>
copy filename identified by qh_skipfilename
<li><a href="io_r.c#eachvoronoi_all">qh_eachvoronoi_all</a>
visit each Voronoi ridge of the Voronoi diagram
<li><a href="io_r.c#prepare_output">qh_prepare_output</a>
prepare Qhull for output (called by qh_produce_output())
<li><a href="io_r.c#printhelp_degenerate">qh_printhelp_degenerate</a>
prints descriptive message for precision error </li>
<li><a href="io_r.c#printhelp_singular">qh_printhelp_singular</a>
print help message for singular data </li>
<li><a href="libqhull_r.c#printsummary">qh_printsummary</a> print
summary ('s')</li>
<li><a href="io_r.c#produce_output">qh_produce_output</a>
prints out the result of qhull()</li>
<li><a href="io_r.c#produce_output">qh_produce_output2</a>
prints out the result of qhull() without calling qh_prepare_output()</li>
<li><a href="io_r.c#readfeasible">qh_readfeasible</a> read
interior point from remainder and qh fin ('H')</li>
<li><a href="io_r.c#readpoints">qh_readpoints</a> read input
points </li>
<li><a href="io_r.c#setfeasible">qh_setfeasible</a> set
interior point from qh feasible_string ('Hn,n,n')</li>
<li><a href="io_r.c#skipfilename">qh_skipfilename</a>
skip filename in string
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iprint">Print functions for all
output formats</a></h3>
<ul>
<li><a href="io_r.c#countfacets">qh_countfacets</a> count good
facets for printing and set visitid </li>
<li><a href="io_r.c#markkeep">qh_markkeep</a> mark good facets
that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
<li><a href="io_r.c#order_vertexneighbors">qh_order_vertexneighbors</a>
order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
<li><a href="io_r.c#printafacet">qh_printafacet</a> print facet
in an output format </li>
<li><a href="io_r.c#printbegin">qh_printbegin</a> print header
for an output format </li>
<li><a href="io_r.c#printend">qh_printend</a> print trailer for
an output format </li>
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
print facets in a facetlist</li>
<li><a href="io_r.c#printfacets">qh_printfacets</a> print
facetlist and/or facet set in an output format </li>
<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
print neighborhood of one or two facets ('Po')</li>
<li><a href="io_r.c#produce_output">qh_produce_output</a>
print the results of qh_qhull() </li>
<li><a href="io_r.c#skipfacet">qh_skipfacet</a> True if not
printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
<li><a href="io_r.c#facetvertices">qh_facetvertices</a> return
vertices in a set of facets ('p')</li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
<ul>
<li><a href="io_r.c#eachvoronoi">qh_eachvoronoi</a>
print or visit each Voronoi ridge for an input site of the Voronoi diagram
<li><a href="io_r.c#printextremes">qh_printextremes</a> print
extreme points by point ID (vertices of convex hull) ('Fx')</li>
<li><a href="io_r.c#printextremes_2d">qh_printextremes_2d</a> print
2-d extreme points by point ID ('Fx')</li>
<li><a href="io_r.c#printextremes_d">qh_printextremes_d</a> print
extreme points of input sites for Delaunay triangulations ('Fx')</li>
<li><a href="io_r.c#printfacet">qh_printfacet</a> print all
fields of a facet ('f')</li>
<li><a href="io_r.c#printfacet2math">qh_printfacet2math</a> print
2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
<li><a href="io_r.c#printfacet3math">qh_printfacet3math</a>
print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
<li><a href="io_r.c#printfacet3vertex">qh_printfacet3vertex</a>
print vertices for a 3-d facet ('i', 'o')</li>
<li><a href="io_r.c#printfacetheader">qh_printfacetheader</a>
prints header fields of a facet ('f')</li>
<li><a href="io_r.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
<li><a href="io_r.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
<li><a href="io_r.c#printfacetridges">qh_printfacetridges</a>
prints ridges of a facet ('f')</li>
<li><a href="io_r.c#printpoints_out">qh_printpoints_out</a> prints
vertices for facets by their point coordinates ('p')</li>
<li><a href="io_r.c#printridge">qh_printridge</a> print all
fields for a ridge ('f')</li>
<li><a href="io_r.c#printvdiagram">qh_printvdiagram</a> print
voronoi diagram as Voronoi vertices for each input pair</li>
<li><a href="io_r.c#printvertex">qh_printvertex</a> print all
fields for a vertex ('f')</li>
<li><a href="io_r.c#printvertexlist">qh_printvertexlist</a>
print vertices used by a list or set of facets ('f')</li>
<li><a href="io_r.c#printvertices">qh_printvertices</a> print a
set of vertices ('f')</li>
<li><a href="io_r.c#printvneighbors">qh_printvneighbors</a>
print vertex neighbors of vertices ('FN')</li>
<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
voronoi diagram in 'o' or 'G' format</li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
<ul>
<li><a href="io_r.c#dfacet">dfacet</a> print facet by ID </li>
<li><a href="io_r.c#dvertex">dvertex</a> print vertex by ID </li>
<li><a href="io_r.c#compare_facetarea">qh_compare_facetarea</a>
used by qsort() to order facets by area </li>
<li><a href="io_r.c#compare_facetmerge">qh_compare_facetmerge</a>
used by qsort() to order facets by number of merges </li>
<li><a href="io_r.c#compare_facetvisit">qh_compare_facetvisit</a>
used by qsort() to order facets by visit ID or ID </li>
<li><a href="io_r.c#compare_vertexpoint">qh_compare_vertexpoint</a>
used by qsort() to order vertices by point ID </li>
<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
ridge for an input site
<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
ridge for an input site
<li><a href="io_r.c#facet2point">qh_facet2point</a> return two
projected temporary vertices for a 2-d facet ('m', 'G')</li>
<li><a href="io_r.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
vertices for printing
<li><a href="io_r.c#printcenter">qh_printcenter</a> print
facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
<li><a href="io_r.c#printpoint">qh_printpoint</a>, qh_printpointid, print
coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
<li><a href="io_r.c#printpoint3">qh_printpoint3</a> prints 2-d,
3-d, or 4-d point as 3-d coordinates ('G')</li>
<li><a href="io_r.c#printvdiagram2">qh_printvdiagram2</a> print
voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
<li><a href="io_r.c#printvnorm">qh_printvnorm</a> print
separating plane of the Voronoi diagram for a pair of input sites</li>
<li><a href="io_r.c#printvridge">qh_printvridge</a> print
ridge of the Voronoi diagram for a pair of input sites</li>
<li><a href="io_r.c#projectdim3">qh_projectdim3</a> project 2-d
3-d or 4-d point to a 3-d point ('G')</li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
<ul>
<li><a href="io_r.c#printfacet2geom">qh_printfacet2geom</a>
print facet as a 2-d VECT object </li>
<li><a href="io_r.c#printfacet2geom_points">qh_printfacet2geom_points</a>
print points as a 2-d VECT object with offset </li>
<li><a href="io_r.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
print Geomview OFF for a 3-d nonsimplicial facet. </li>
<li><a href="io_r.c#printfacet3geom_points">qh_printfacet3geom_points</a>
prints a 3-d facet as OFF Geomview object. </li>
<li><a href="io_r.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
print Geomview OFF for a 3-d simplicial facet. </li>
<li><a href="io_r.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
print Geomview 4OFF file for a 4d nonsimplicial facet </li>
<li><a href="io_r.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
print Geomview 4OFF file for a 4d simplicial facet </li>
<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
print hyperplane intersection as OFF or 4OFF </li>
<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
voronoi diagram in 'o' or 'G' format</li>
</ul>
<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
<ul>
<li><a href="io_r.c#geomplanes">qh_geomplanes</a>
return outer and inner planes for Geomview</li>
<li><a href="io_r.c#printcentrum">qh_printcentrum</a> print
centrum for a facet in OOGL format </li>
<li><a href="io_r.c#printend4geom">qh_printend4geom</a> helper
function for qh_printbegin/printend </li>
<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
print Geomview OFF or 4OFF for the intersection of two
hyperplanes in 3-d or 4-d </li>
<li><a href="io_r.c#printline3geom">qh_printline3geom</a> prints a
line as a VECT </li>
<li><a href="io_r.c#printpointvect">qh_printpointvect</a>
prints a 2-d or 3-d point as 3-d VECT's </li>
<li><a href="io_r.c#printpointvect2">qh_printpointvect2</a>
prints a 2-d or 3-d point as 2 3-d VECT's </li>
<li><a href="io_r.c#printspheres">qh_printspheres</a> prints 3-d
vertices as OFF spheres </li>
</ul>
<p>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,145 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>mem_r.c -- memory operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>mem_r.c -- memory operations</h2>
<blockquote>
<p>Qhull uses quick-fit memory allocation. It maintains a
set of free lists for a variety of small allocations. A
small request returns a block from the best fitting free
list. If the free list is empty, Qhull allocates a block
from a reserved buffer. </p>
<p>Use 'T5' to trace memory allocations.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
<a href="qh-io_r.htm#TOC">Io</a> &#149; <b>Mem</b>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="mem_r.c">mem_r.c</a> and
<a href="mem_r.h">mem_r.h</a></h3>
<ul>
<li><a href="#etype">mem_r.h data types</a> </li>
<li><a href="#emacro">mem_r.h macros</a> </li>
<li><a href="#efunc">User level functions</a> </li>
</ul>
<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="etype">mem_r.h data types and constants</a></h3>
<ul>
<li><a href="mem_r.h#ptr_intT">ptr_intT</a> for casting
a void* to an integer-type </li>
<li><a href="mem_r.h#qhmemT">qhmemT</a> global memory
structure for mem_r.c </li>
<li><a href="mem_r.h#NOmem">qh_NOmem</a> disable memory allocation</li>
</ul>
<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="emacro">mem_r.h macros</a></h3>
<ul>
<li><a href="mem_r.h#memalloc_">qh_memalloc_</a>
allocate memory</li>
<li><a href="mem_r.h#memfree_">qh_memfree_</a> free
memory</li>
</ul>
<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="efunc">User level
functions</a></h3>
<ul>
<li><a href="mem_r.c#memalloc">qh_memalloc</a> allocate
memory </li>
<li><a href="mem_r.c#memcheck">qh_memcheck</a>
quick check of memory for internal consistency</li>
<li><a href="mem_r.c#memfree">qh_memfree</a> free
memory </li>
<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
print memory statistics </li>
<li><a href="mem_r.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
<li><a href="mem_r.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
</ul>
<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="m">Initialization and
termination functions</a></h3>
<ul>
<li><a href="mem_r.c#intcompare">qh_intcompare</a> used by
qsort and bsearch to compare two integers </li>
<li><a href="mem_r.c#memfreeshort">qh_memfreeshort</a>
frees up all short and qhmem memory allocations </li>
<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
memory </li>
<li><a href="mem_r.c#meminitbuffers">qh_meminitbuffers</a>
initialize qhmem </li>
<li><a href="mem_r.c#memsetup">qh_memsetup</a> set up
memory after running memsize() </li>
<li><a href="mem_r.c#memsize">qh_memsize</a> define a free
list for this size </li>
<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
print out memory statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,366 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>merge_r.c -- facet merge operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>merge_r.c -- facet merge operations</h2>
<blockquote>
<p>Qhull handles precision problems by merged facets or joggled input.
Except for redundant vertices, it corrects a problem by
merging two facets. When done, all facets are clearly
convex. See <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
for further information. </p>
<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
instead of merging facets. </p>
<p>Qhull detects and corrects the following problems: </p>
<ul>
<li><b>More than two facets meeting at a ridge. </b>When
Qhull creates facets, it creates an even number
of facets for each ridge. A convex hull always
has two facets for each ridge. More than two
facets may be created if non-adjacent facets
share a vertex. This is called a <em>duplicate
ridge</em>. In 2-d, a duplicate ridge would
create a loop of facets. </li>
</ul>
<ul>
<li><b>A facet contained in another facet. </b>Facet
merging may leave all vertices of one facet as a
subset of the vertices of another facet. This is
called a <em>redundant facet</em>. </li>
</ul>
<ul>
<li><b>A facet with fewer than three neighbors. </b>Facet
merging may leave a facet with one or two
neighbors. This is called a <em>degenerate facet</em>.
</li>
</ul>
<ul>
<li><b>A facet with flipped orientation. </b>A
facet's hyperplane may define a halfspace that
does not include the interior point.This is
called a <em>flipped facet</em>. </li>
</ul>
<ul>
<li><strong>A coplanar horizon facet.</strong> A
newly processed point may be coplanar with an
horizon facet. Qhull creates a new facet without
a hyperplane. It links new facets for the same
horizon facet together. This is called a <em>samecycle</em>.
The new facet or samecycle is merged into the
horizon facet. </li>
</ul>
<ul>
<li><b>Concave facets. </b>A facet's centrum may be
above a neighboring facet. If so, the facets meet
at a concave angle. </li>
</ul>
<ul>
<li><b>Coplanar facets. </b>A facet's centrum may be
coplanar with a neighboring facet (i.e., it is
neither clearly below nor clearly above the
facet's hyperplane). Qhull removes coplanar
facets in independent sets sorted by angle.</li>
</ul>
<ul>
<li><b>Redundant vertex. </b>A vertex may have fewer
than three neighboring facets. If so, it is
redundant and may be renamed to an adjacent
vertex without changing the topological
structure.This is called a <em>redundant vertex</em>.
</li>
</ul>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <b>Merge</b> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="merge_r.c">merge_r.c</a> and
<a href="merge_r.h">merge_r.h</a></h3>
<ul>
<li><a href="#mtype">merge_r.h data types, macros, and
global sets</a> </li>
<li><a href="#mconst">merge_r.h constants</a> </li>
</ul>
<ul>
<li><a href="#mtop">top-level merge functions</a> </li>
<li><a href="#mset">functions for identifying merges</a></li>
<li><a href="#mbest">functions for determining the
best merge</a> </li>
<li><a href="#mmerge">functions for merging facets</a>
</li>
<li><a href="#mcycle">functions for merging a cycle
of facets</a> </li>
<li><a href="#mrename">functions for renaming a
vertex</a> </li>
<li><a href="#mvertex">functions for identifying
vertices for renaming</a> </li>
<li><a href="#mcheck">functions for check and trace</a> </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtype">merge_r.h data
types, macros, and global sets</a></h3>
<ul>
<li><a href="merge_r.h#mergeT">mergeT</a> structure to
identify a merge of two facets</li>
<li><a href="merge_r.h#FOREACHmerge_">FOREACHmerge_</a>
assign 'merge' to each merge in merges </li>
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
qh.facet_mergeset contains non-convex merges
while qh.degen_mergeset contains degenerate and
redundant facets</li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mconst">merge_r.h
constants</a></h3>
<ul>
<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
precision constants for Qhull </li>
<li><a href="merge_r.h#MRG">MRG...</a> indicates the
type of a merge (mergeT-&gt;type)</li>
<li><a href="merge_r.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
indicates redundant merge in mergeT-&gt;angle </li>
<li><a href="merge_r.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
indicates degenerate facet in mergeT-&gt;angle </li>
<li><a href="merge_r.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
offset to indicate concave facets in
mergeT-&gt;angle </li>
<li><a href="merge_r.h#qh_MERGEapex">qh_MERGEapex</a>
flag for qh_mergefacet() to indicate an apex
merge </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtop">top-level merge
functions</a></h3>
<ul>
<li><a href="merge_r.c#all_merges">qh_all_merges</a>
merge all non-convex facets </li>
<li><a href="merge_r.c#checkzero">qh_checkzero</a>
check that facets are clearly convex </li>
<li><a href="merge_r.c#flippedmerges">qh_flippedmerges</a>
merge flipped facets into best neighbor </li>
<li><a href="merge_r.c#forcedmerges">qh_forcedmerges</a>
merge all duplicate ridges </li>
<li><a href="merge_r.c#merge_degenredundant">qh_merge_degenredundant</a>
merge degenerate and redundant facets </li>
<li><a href="merge_r.c#merge_nonconvex">qh_merge_nonconvex</a>
merge a non-convex ridge </li>
<li><a href="merge_r.c#premerge">qh_premerge</a>
pre-merge non-convex facets </li>
<li><a href="merge_r.c#postmerge">qh_postmerge</a>
post-merge nonconvex facets as defined by
maxcentrum/maxangle </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mset">functions for
identifying merges</a></h3>
<ul>
<li><a href="merge_r.c#appendmergeset">qh_appendmergeset</a>
appends an entry to qh.facet_mergeset</li>
<li><a href="merge_r.c#compareangle">qh_compareangle</a>
used by qsort() to order merges </li>
<li><a href="merge_r.c#comparemerge">qh_comparemerge</a>
used by qsort() to order merges </li>
<li><a href="merge_r.c#degen_redundant_facet">qh_degen_redundant_facet</a>
check for a degenerate and redundant facet</li>
<li><a href="merge_r.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
append degenerate and redundant neighbors to
qh.degen_mergeset </li>
<li><a href="merge_r.c#getmergeset_initial">qh_getmergeset_initial</a>
build initial qh.facet_mergeset </li>
<li><a href="merge_r.c#getmergeset">qh_getmergeset</a>
update qh.facet_mergeset </li>
<li><a href="merge_r.c#mark_dupridges">qh_mark_dupridges</a>
add duplicated ridges to qh.facet_mergeset</li>
<li><a href="merge_r.c#maydropneighbor">qh_maydropneighbor</a>
drop neighbor relationship if no ridge between
facet and neighbor </li>
<li><a href="merge_r.c#test_appendmerge">qh_test_appendmerge</a>
test a pair of facets for convexity and append to
qh.facet_mergeset if non-convex </li>
<li><a href="merge_r.c#test_vneighbors">qh_test_vneighbors</a>
test vertex neighbors for convexity </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mbest">functions for
determining the best merge</a></h3>
<ul>
<li><a href="merge_r.c#findbest_test">qh_findbest_test</a>
test neighbor for best merge </li>
<li><a href="merge_r.c#findbestneighbor">qh_findbestneighbor</a>
finds best neighbor of a facet for merging (i.e.,
closest hyperplane) </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mmerge">functions for
merging facets</a></h3>
<ul>
<li><a href="merge_r.c#copynonconvex">qh_copynonconvex</a>
copy non-convex flag to another ridge for the
same neighbor </li>
<li><a href="merge_r.c#makeridges">qh_makeridges</a>
creates explicit ridges between simplicial facets
</li>
<li><a href="merge_r.c#mergefacet">qh_mergefacet</a>
merges one facet into another facet</li>
<li><a href="merge_r.c#mergeneighbors">qh_mergeneighbors</a>
merges the neighbors of two facets </li>
<li><a href="merge_r.c#mergeridges">qh_mergeridges</a>
merges the ridge sets of two facets </li>
<li><a href="merge_r.c#mergesimplex">qh_mergesimplex</a>
merge a simplicial facet into another simplicial
facet </li>
<li><a href="merge_r.c#mergevertex_del">qh_mergevertex_del</a>
delete a vertex due to merging one facet into
another facet </li>
<li><a href="merge_r.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
merge the vertex neighbors of two facets </li>
<li><a href="merge_r.c#mergevertices">qh_mergevertices</a>
merge the vertex sets of two facets </li>
<li><a href="merge_r.c#newvertices">qh_newvertices</a>
register all vertices as new vertices </li>
<li><a href="merge_r.c#updatetested">qh_updatetested</a>
clear tested flags and centrums involved in a
merge </li>
<li><a href="merge_r.c#willdelete">qh_willdelete</a>
moves facet to qh.visible_list; sets replacement
or NULL </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcycle">functions for
merging a cycle of facets</a></h3>
<p>If a point is coplanar with an horizon facet, the
corresponding new facets are linked together (a <em>samecycle</em>)
for merging.</p>
<ul>
<li><a href="merge_r.c#basevertices">qh_basevertices</a>
return temporary set of base vertices for a
samecycle </li>
<li><a href="merge_r.c#mergecycle">qh_mergecycle</a>
merge a samecycle into a horizon facet </li>
<li><a href="merge_r.c#mergecycle_all">qh_mergecycle_all</a>
merge all samecycles into horizon facets</li>
<li><a href="merge_r.c#mergecycle_facets">qh_mergecycle_facets</a>
finish merge of samecycle </li>
<li><a href="merge_r.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
merge neighbor sets for samecycle </li>
<li><a href="merge_r.c#mergecycle_ridges">qh_mergecycle_ridges</a>
merge ridge sets for samecycle </li>
<li><a href="merge_r.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
merge vertex neighbor sets for samecycle </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mrename">functions
for renaming a vertex</a></h3>
<ul>
<li><a href="merge_r.c#comparevisit">qh_comparevisit</a>
used by qsort() to order vertices by visitid</li>
<li><a href="merge_r.c#reducevertices">qh_reducevertices</a>
reduce vertex sets </li>
<li><a href="merge_r.c#redundant_vertex">qh_redundant_vertex</a>
returns true if detect and rename redundant
vertex </li>
<li><a href="merge_r.c#rename_sharedvertex">qh_rename_sharedvertex</a>
detect and rename a shared vertex </li>
<li><a href="merge_r.c#renameridgevertex">qh_renameridgevertex</a>
rename oldvertex to newvertex in a ridge </li>
<li><a href="merge_r.c#renamevertex">qh_renamevertex</a>
rename oldvertex to newvertex in ridges </li>
<li><a href="merge_r.c#remove_extravertices">qh_remove_extravertices</a>
remove extra vertices in non-simplicial facets </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mvertex">functions
for identifying vertices for renaming</a></h3>
<ul>
<li><a href="merge_r.c#find_newvertex">qh_find_newvertex</a>
locate new vertex for renaming old vertex </li>
<li><a href="merge_r.c#hashridge">qh_hashridge</a> add
ridge to hashtable </li>
<li><a href="merge_r.c#hashridge_find">qh_hashridge_find</a>
returns matching ridge in hashtable</li>
<li><a href="merge_r.c#neighbor_intersections">qh_neighbor_intersections</a>
return intersection of vertex sets for
neighboring facets </li>
<li><a href="merge_r.c#vertexridges">qh_vertexridges</a>
return temporary set of ridges adjacent to a
vertex </li>
<li><a href="merge_r.c#vertexridges_facet">qh_vertexridges_facet</a>
add adjacent ridges for a vertex in facet </li>
</ul>
<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcheck">functions for check and
trace</a></h3>
<ul>
<li><a href="merge_r.c#checkconnect">qh_checkconnect</a>
check that new facets are connected </li>
<li><a href="merge_r.c#tracemerge">qh_tracemerge</a>
print trace message after merge </li>
<li><a href="merge_r.c#tracemerging">qh_tracemerging</a>
print trace message during post-merging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,485 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>poly_r.c, poly2_r.c -- polyhedron operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>poly_r.c, poly2_r.c -- polyhedron operations</h2>
<blockquote>
<p>Qhull uses dimension-free terminology. Qhull builds a
polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
simplicial complex of faces with geometric information for the
top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
is a <em>vertex</em>. For example in 3-d, a facet is a polygon
and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
and a vertex (the <em>apex</em>). See
<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
<p>Qhull's primary data structure is a polyhedron. A
polyhedron is a list of facets. Each facet has a set of
neighboring facets and a set of vertices. Each facet has a
hyperplane. For example, a tetrahedron has four facets.
If its vertices are <em>a, b, c, d</em>, and its facets
are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
<blockquote>
<ul>
<li>facet 1 <ul>
<li>vertices: b c d </li>
<li>neighbors: 2 3 4 </li>
</ul>
</li>
<li>facet 2 <ul>
<li>vertices: a c d </li>
<li>neighbors: 1 3 4 </li>
</ul>
</li>
<li>facet 3 <ul>
<li>vertices: a b d </li>
<li>neighbors: 1 2 4 </li>
</ul>
</li>
<li>facet 4 <ul>
<li>vertices: a b c </li>
<li>neighbors: 1 2 3 </li>
</ul>
</li>
</ul>
</blockquote>
<p>A facet may be simplicial or non-simplicial. In 3-d, a
<i>simplicial facet</i> has three vertices and three
neighbors. A <i>nonsimplicial facet</i> has more than
three vertices and more than three neighbors. A
nonsimplicial facet has a set of ridges and a centrum. </p>
<p>
A simplicial facet has an orientation. An <i>orientation</i>
is either <i>top</i> or <i>bottom</i>.
The flag, <tt>facet-&gt;toporient,</tt>
defines the orientation of the facet's vertices. For example in 3-d,
'top' is left-handed orientation (i.e., the vertex order follows the direction
of the left-hand fingers when the thumb is pointing away from the center).
Except for axis-parallel facets in 5-d and higher, topological orientation
determines the geometric orientation of the facet's hyperplane.
<p>A nonsimplicial facet is due to merging two or more
facets. The facet's ridge set determine a simplicial
decomposition of the facet. Each ridge is a 1-face (i.e.,
it has two vertices and two neighboring facets). The
orientation of a ridge is determined by the order of the
neighboring facets. The flag, <tt>facet-&gt;toporient,</tt>is
ignored. </p>
<p>A nonsimplicial facet has a centrum for testing
convexity. A <i>centrum</i> is a point on the facet's
hyperplane that is near the center of the facet. Except
for large facets, it is the arithmetic average of the
facet's vertices. </p>
<p>A nonsimplicial facet is an approximation that is
defined by offsets from the facet's hyperplane. When
Qhull finishes, the <i>outer plane</i> is above all
points while the <i>inner plane</i> is below the facet's
vertices. This guarantees that any exact convex hull
passes between the inner and outer planes. The outer
plane is defined by <tt>facet-&gt;maxoutside</tt> while
the inner plane is computed from the facet's vertices.</p>
<p>Qhull 3.1 includes triangulation of non-simplicial facets
('<a href="../../html/qh-optq.htm#Qt">Qt</a>').
These facets,
called <i>tricoplanar</i>, share the same normal. centrum, and Voronoi center.
One facet (keepcentrum) owns these data structures.
While tricoplanar facets are more accurate than the simplicial facets from
joggled input, they
may have zero area or flipped orientation.
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <b>Poly</b>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="poly_r.c">poly_r.c</a>,
<a href="poly2_r.c">poly2_r.c</a>, <a href="poly_r.h">poly_r.h</a>,
and <a href="libqhull_r.h">libqhull_r.h</a></h3>
<ul>
<li><a href="#ptype">Data types and global
lists for polyhedrons</a> </li>
<li><a href="#pconst">poly_r.h constants</a> </li>
<li><a href="#pgall">Global FORALL macros</a> </li>
<li><a href="#pall">FORALL macros</a> </li>
<li><a href="#peach">FOREACH macros</a> </li>
<li><a href="#pieach">Indexed FOREACH macros</a> </li>
<li><a href="#pmacro">Other macros for polyhedrons</a><p>&nbsp;</li>
<li><a href="#plist">Facetlist functions</a> </li>
<li><a href="#pfacet">Facet functions</a> </li>
<li><a href="#pvertex">Vertex, ridge, and point
functions</a> </li>
<li><a href="#phash">Hashtable functions</a> </li>
<li><a href="#pnew">Allocation and deallocation
functions</a> </li>
<li><a href="#pcheck">Check functions</a> </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="ptype">Data
types and global lists for polyhedrons</a></h3>
<ul>
<li><a href="libqhull_r.h#facetT">facetT</a> defines a
facet </li>
<li><a href="libqhull_r.h#ridgeT">ridgeT</a> defines a
ridge </li>
<li><a href="libqhull_r.h#vertexT">vertexT</a> defines a
vertex </li>
<li><a href="libqhull_r.h#qh-lists">qh facet and vertex
lists</a> lists of facets and vertices </li>
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
global sets for merging, hashing, input, etc. </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pconst">poly_r.h constants</a></h3>
<ul>
<li><a href="poly_r.h#ALGORITHMfault">ALGORITHMfault</a>
flag to not report errors in qh_checkconvex() </li>
<li><a href="poly_r.h#DATAfault">DATAfault</a> flag to
report errors in qh_checkconvex() </li>
<li><a href="poly_r.h#DUPLICATEridge">DUPLICATEridge</a>
special value for facet-&gt;neighbor to indicate
a duplicate ridge </li>
<li><a href="poly_r.h#MERGEridge">MERGEridge</a>
special value for facet-&gt;neighbor to indicate
a merged ridge </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pgall">Global FORALL
macros</a></h3>
<ul>
<li><a href="libqhull_r.h#FORALLfacets">FORALLfacets</a>
assign 'facet' to each facet in qh.facet_list </li>
<li><a href="poly_r.h#FORALLnew_facets">FORALLnew_facets</a>
assign 'facet' to each facet in qh.newfacet_list </li>
<li><a href="poly_r.h#FORALLvisible_facets">FORALLvisible_facets</a>
assign 'visible' to each visible facet in
qh.visible_list </li>
<li><a href="libqhull_r.h#FORALLpoints">FORALLpoints</a>
assign 'point' to each point in qh.first_point,
qh.num_points </li>
<li><a href="libqhull_r.h#FORALLvertices">FORALLvertices</a>
assign 'vertex' to each vertex in qh.vertex_list </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
<ul>
<li><a href="poly_r.h#FORALLfacet_">FORALLfacet_</a>
assign 'facet' to each facet in facetlist </li>
<li><a href="libqhull_r.h#FORALLpoint_">FORALLpoint_</a>
assign 'point' to each point in points array</li>
<li><a href="poly_r.h#FORALLsame_">FORALLsame_</a>
assign 'same' to each facet in samecycle</li>
<li><a href="poly_r.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
assign 'same' to each facet in samecycle</li>
<li><a href="poly_r.h#FORALLvertex_">FORALLvertex_</a>
assign 'vertex' to each vertex in vertexlist </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
<ul>
<li><a href="libqhull_r.h#FOREACHfacet_">FOREACHfacet_</a>
assign 'facet' to each facet in facets </li>
<li><a href="libqhull_r.h#FOREACHneighbor_">FOREACHneighbor_</a>
assign 'neighbor' to each facet in
facet-&gt;neighbors or vertex-&gt;neighbors</li>
<li><a href="poly_r.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
assign 'newfacet' to each facet in facet set </li>
<li><a href="libqhull_r.h#FOREACHpoint_">FOREACHpoint_</a>
assign 'point' to each point in points set </li>
<li><a href="libqhull_r.h#FOREACHridge_">FOREACHridge_</a>
assign 'ridge' to each ridge in ridge set </li>
<li><a href="libqhull_r.h#FOREACHvertex_">FOREACHvertex_</a>
assign 'vertex' to each vertex in vertex set </li>
<li><a href="poly_r.h#FOREACHvertexA_">FOREACHvertexA_</a>
assign 'vertexA' to each vertex in vertex set</li>
<li><a href="poly_r.h#FOREACHvisible_">FOREACHvisible_</a>
assign 'visible' to each facet in facet set </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pieach">Indexed
FOREACH macros</a></h3>
<ul>
<li><a href="libqhull_r.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
assign 'facet' and 'facet_i' to each facet in
facet set </li>
<li><a href="libqhull_r.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
assign 'neighbor' and 'neighbor_i' to each facet
in facet-&gt;neighbors or vertex-&gt;neighbors</li>
<li><a href="libqhull_r.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
assign 'point' and 'point_i' to each point in
points set </li>
<li><a href="libqhull_r.h#FOREACHridge_i_">FOREACHridge_i_</a>
assign 'ridge' and 'ridge_i' to each ridge in
ridges set </li>
<li><a href="libqhull_r.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
assign 'vertex' and 'vertex_i' to each vertex in
vertices set </li>
<li><a href="poly_r.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
assign 'vertex' to each vertex in vertex set;
reverse the order of first two vertices </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
<ul>
<li><a href="libqhull_r.h#getid_">getid_</a> return ID for
a facet, ridge, or vertex </li>
<li><a href="libqhull_r.h#otherfacet_">otherfacet_</a>
return neighboring facet for a ridge in a facet </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="plist">Facetlist
functions</a></h3>
<ul>
<li><a href="poly_r.c#appendfacet">qh_appendfacet</a>
appends facet to end of qh.facet_list</li>
<li><a href="poly_r.c#attachnewfacets">qh_attachnewfacets</a>
attach new facets in qh.newfacet_list to the
horizon </li>
<li><a href="poly2_r.c#findgood">qh_findgood</a>
identify good facets for qh.PRINTgood </li>
<li><a href="poly2_r.c#findgood_all">qh_findgood_all</a>
identify more good facets for qh.PRINTgood </li>
<li><a href="poly2_r.c#furthestnext">qh_furthestnext</a>
move facet with furthest of furthest points to
facet_next </li>
<li><a href="poly2_r.c#initialhull">qh_initialhull</a>
construct the initial hull as a simplex of
vertices </li>
<li><a href="poly2_r.c#nearcoplanar">qh_nearcoplanar</a>
remove near-inside points from coplanar sets</li>
<li><a href="poly2_r.c#prependfacet">qh_prependfacet</a>
prepends facet to start of facetlist </li>
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
print facets in a facetlist</li>
<li><a href="poly2_r.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
<li><a href="poly_r.c#removefacet">qh_removefacet</a>
unlinks facet from qh.facet_list</li>
<li><a href="poly2_r.c#resetlists">qh_resetlists</a>
reset qh.newvertex_list, qh.newfacet_list, and
qh.visible_list </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pfacet">Facet
functions</a></h3>
<ul>
<li><a href="poly2_r.c#createsimplex">qh_createsimplex</a>
create a simplex of facets from a set of vertices
</li>
<li><a href="poly2_r.c#findbestlower">qh_findbestlower</a> find best
non-upper, non-flipped facet for point at upperfacet</li>
<li><a href="poly2_r.c#furthestout">qh_furthestout</a>
make furthest outside point the last point of a
facet's outside set </li>
<li><a href="poly_r.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
make new facets from ridges of visible facets </li>
<li><a href="poly_r.c#makenew_simplicial">qh_makenew_simplicial</a>
make new facets for horizon neighbors </li>
<li><a href="poly_r.c#makenewfacet">qh_makenewfacet</a>
create a facet from vertices and apex </li>
<li><a href="poly2_r.c#makenewfacets">qh_makenewfacets</a>
make new facets from vertex, horizon facets, and
visible facets </li>
<li><a href="poly_r.c#makenewplanes">qh_makenewplanes</a>
make new hyperplanes for facets </li>
<li><a href="poly2_r.c#outcoplanar">qh_outcoplanar</a>
move points from outside set to coplanar set </li>
<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
compute Voronoi centers for all facets </li>
<li><a href="poly2_r.c#triangulate">qh_triangulate</a>
triangulate non-simplicial facets</li>
<li><a href="poly2_r.c#triangulate_facet">qh_triangulate_facet</a>
triangulate a non-simplicial facet</li>
<li><a href="poly2_r.c#triangulate_link">qh_triangulate_link</a>
link facets together from qh_triangulate</li>
<li><a href="poly2_r.c#triangulate_mirror">qh_triangulate_mirror</a>
delete mirrored facets from qh_triangulate</li>
<li><a href="poly2_r.c#triangulate_null">qh_triangulate_null</a>
delete null facet from qh_triangulate</li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pvertex">Vertex,
ridge, and point functions</a></h3>
<ul>
<li><a href="poly_r.c#appendvertex">qh_appendvertex</a>
append vertex to end of qh.vertex_list, </li>
<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
ridge for an input site
<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
ridge for an input site
<li><a href="poly2_r.c#facet3vertex">qh_facet3vertex</a>
return an oriented vertex set for a 3-d facet </li>
<li><a href="poly_r.c#facetintersect">qh_facetintersect</a>
return intersection of simplicial facets </li>
<li><a href="poly2_r.c#initialvertices">qh_initialvertices</a>
return non-singular set of initial vertices </li>
<li><a href="poly2_r.c#isvertex">qh_isvertex</a> true
if point is in a vertex set </li>
<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
return nearest vertex to point </li>
<li><a href="poly2_r.c#nextridge3d">qh_nextridge3d</a>
iterate over each ridge and vertex for a 3-d
facet </li>
<li><a href="poly2_r.c#point">qh_point</a> return point
for a point ID </li>
<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
return temporary set of facets indexed by point
ID </li>
<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
for a point</li>
<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
return temporary set of vertices indexed by point
ID </li>
<li><a href="poly_r.c#removevertex">qh_removevertex</a>
unlink vertex from qh.vertex_list, </li>
<li><a href="poly_r.c#updatevertices">qh_updatevertices</a>
update vertex neighbors and delete interior
vertices </li>
<li><a href="poly2_r.c#vertexintersect">qh_vertexintersect</a>
intersect two vertex sets </li>
<li><a href="poly2_r.c#vertexintersect_new">qh_vertexintersect_new</a>
return intersection of two vertex sets </li>
<li><a href="poly2_r.c#vertexneighbors">qh_vertexneighbors</a>
for each vertex in hull, determine facet
neighbors </li>
<li><a href="poly2_r.c#vertexsubset">qh_vertexsubset</a>
returns True if vertexsetA is a subset of
vertexsetB </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
<ul>
<li><a href="poly2_r.c#addhash">qh_addhash</a> add hash
element to linear hash table</li>
<li><a href="poly_r.c#gethash">qh_gethash</a> return
hash value for a set</li>
<li><a href="poly2_r.c#matchduplicates">qh_matchduplicates</a>
match duplicate ridges in hash table </li>
<li><a href="poly_r.c#matchneighbor">qh_matchneighbor</a>
try to match subridge of new facet with a
neighbor </li>
<li><a href="poly_r.c#matchnewfacets">qh_matchnewfacets</a>
match new facets with their new facet neighbors </li>
<li><a href="poly_r.c#matchvertices">qh_matchvertices</a>
tests whether a facet and hash entry match at a
ridge </li>
<li><a href="poly2_r.c#newhashtable">qh_newhashtable</a>
allocate a new qh_r.hash_table </li>
<li><a href="poly2_r.c#printhashtable">qh_printhashtable</a>
print hash table </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pnew">Allocation and
deallocation functions</a></h3>
<ul>
<li><a href="poly2_r.c#clearcenters">qh_clearcenters</a>
clear old data from facet-&gt;center </li>
<li><a href="poly_r.c#deletevisible">qh_deletevisible</a>
delete visible facets and vertices </li>
<li><a href="poly_r.c#delfacet">qh_delfacet</a> free up
the memory occupied by a facet </li>
<li><a href="poly2_r.c#delridge">qh_delridge</a> delete
ridge</li>
<li><a href="poly2_r.c#delvertex">qh_delvertex</a>
delete vertex </li>
<li><a href="poly_r.c#newfacet">qh_newfacet</a> create
and allocate space for a facet </li>
<li><a href="poly_r.c#newridge">qh_newridge</a> create
and allocate space for a ridge </li>
<li><a href="poly2_r.c#newvertex">qh_newvertex</a>
create and allocate space for a vertex </li>
</ul>
<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pcheck">Check
functions</a></h3>
<ul>
<li><a href="poly2_r.c#check_bestdist">qh_check_bestdist</a>
check that points are not outside of facets </li>
<li><a href="poly2_r.c#check_dupridge">qh_check_dupridge</a>
check duplicate ridge between facet1 and facet2 for wide merge </li>
<li><a href="poly2_r.c#check_maxout">qh_check_maxout</a>
updates qh.max_outside and checks all points
against bestfacet </li>
<li><a href="poly2_r.c#check_output">qh_check_output</a>
check topological and geometric output</li>
<li><a href="poly2_r.c#check_point">qh_check_point</a>
check that point is not outside of facet </li>
<li><a href="poly2_r.c#check_points">qh_check_points</a>
check that all points are inside all facets </li>
<li><a href="poly2_r.c#checkconvex">qh_checkconvex</a>
check that each ridge in facetlist is convex </li>
<li><a href="poly2_r.c#checkfacet">qh_checkfacet</a>
check for consistency errors in facet </li>
<li><a href="poly_r.c#checkflipped">qh_checkflipped</a>
check facet orientation to the interior point </li>
<li><a href="poly2_r.c#checkflipped_all">qh_checkflipped_all</a>
check facet orientation for a facet list </li>
<li><a href="poly2_r.c#checkpolygon">qh_checkpolygon</a>
check topological structure </li>
<li><a href="poly2_r.c#checkvertex">qh_checkvertex</a>
check vertex for consistency </li>
<li><a href="poly2_r.c#infiniteloop">qh_infiniteloop</a>
report error for a loop of facets </li>
<li><a href="poly2_r.c#printlists">qh_printlists</a>
print out facet list for debugging </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,279 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>libqhull_r.c -- top-level functions and basic data types</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>libqhull_r.c -- top-level functions and basic data types</h2>
<blockquote>
<p>Qhull implements the Quickhull algorithm for computing
the convex hull. The Quickhull algorithm combines two
well-known algorithms: the 2-d quickhull algorithm and
the n-d beneath-beyond algorithm. See
<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
<p>This section provides an index to the top-level
functions and base data types. The top-level header file, <tt>libqhull_r.h</tt>,
contains prototypes for these functions.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <b>Qhull</b> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="libqhull_r.c">libqhull_r.c</a>,
<a href="libqhull_r.h">libqhull_r.h</a>, and
<a href="../qhull/unix_r.c">unix_r.c</a></h3>
<ul>
<li><a href="#qtype">libqhull_r.h and unix_r.c data types and
constants</a> </li>
<li><a href="#qmacro">libqhull_r.h other macros</a> </li>
<li><a href="#qfunc">Quickhull routines in call order</a> </li>
<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
<li><a href="#qout">Top-level routines for returning results</a></li>
<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtype">libqhull_r.h and unix_r.c
data types and constants</a></h3>
<ul>
<li><a href="libqhull_r.h#flagT">flagT</a> Boolean flag as
a bit </li>
<li><a href="libqhull_r.h#boolT">boolT</a> boolean value,
either True or False </li>
<li><a href="libqhull_r.h#CENTERtype">CENTERtype</a> to
distinguish facet-&gt;center </li>
<li><a href="libqhull_r.h#qh_PRINT">qh_PRINT</a> output
formats for printing (qh.PRINTout) </li>
<li><a href="libqhull_r.h#qh_ALL">qh_ALL</a> argument flag
for selecting everything </li>
<li><a href="libqhull_r.h#qh_ERR">qh_ERR</a> Qhull exit
codes for indicating errors </li>
<li><a href="libqhull_r.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
to distinguish error output from normal output [C++ only]</li>
<li><a href="../qhull/unix_r.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
<li><a href="../qhull/unix_r.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
<li><a href="../qhull/unix_r.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
<li><a href="global_r.c#qh_version">qh_version</a> version stamp</li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qmacro">libqhull_r.h other
macros</a></h3>
<ul>
<li><a href="qhull_ra.h#traceN">traceN</a> print trace
message if <em>qh.IStracing &gt;= N</em>. </li>
<li><a href="qhull_ra.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
unused variable to avoid warnings. </li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qfunc">Quickhull
routines in call order</a></h3>
<ul>
<li><a href="../qhull/unix_r.c#main">main</a> processes the
command line, calls qhull() to do the work, and
exits </li>
<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
the convex hull of a set of points </li>
<li><a href="libqhull_r.c#build_withrestart">qh_build_withrestart</a>
allow restarts while calling qh_buildhull</li>
<li><a href="poly2_r.c#initbuild">qh_initbuild</a>
initialize hull and outside sets with point array</li>
<li><a href="libqhull_r.c#partitionall">qh_partitionall</a>
partition all points into outside sets </li>
<li><a href="libqhull_r.c#buildhull">qh_buildhull</a>
construct a convex hull by adding points one at a
time </li>
<li><a href="libqhull_r.c#nextfurthest">qh_nextfurthest</a>
return next furthest point for processing </li>
<li><a href="libqhull_r.c#buildtracing">qh_buildtracing</a>
trace an iteration of buildhull </li>
<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add a
point to the convex hull </li>
<li><a href="libqhull_r.c#findhorizon">qh_findhorizon</a>
find the horizon and visible facets for a point </li>
<li><a href="libqhull_r.c#partitionvisible">qh_partitionvisible</a>
partition points from facets in qh.visible_list
to facets in qh.newfacet_list </li>
<li><a href="libqhull_r.c#partitionpoint">qh_partitionpoint</a>
partition a point as inside, coplanar with, or
outside a facet </li>
<li><a href="libqhull_r.c#partitioncoplanar">qh_partitioncoplanar</a>
partition coplanar point into a facet </li>
<li><a href="libqhull_r.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
<ul>
<li><a href="global_r.c#freebuild">qh_freebuild</a>
free memory used by qh_initbuild and qh_buildhull
</li>
<li><a href="global_r.c#checkflags">qh_checkflags</a>
check flags for multiple frontends to qhull
<li><a href="global_r.c#freeqhull">qh_freeqhull</a>
free memory used by qhull </li>
<li><a href="global_r.c#init_A">qh_init_A</a> called
before error handling initialized </li>
<li><a href="global_r.c#init_B">qh_init_B</a> called
after points are defined </li>
<li><a href="global_r.c#initflags">qh_initflags</a> set
flags and constants from command line </li>
<li><a href="rboxlib_r.c#rboxpoints">qh_rboxpoints</a>
generate points for qhull </li>
<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
restores a saved qhull </li>
<li><a href="global_r.c#save_qhull">qh_save_qhull</a>
saves qhull for later restoring </li>
<li><a href="user_r.c#user_memsizes">qh_user_memsizes</a>
define additional quick allocation sizes
</li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
<ul>
<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
implements Gram-Schmidt orthogonalization by rows </li>
<li><a href="geom2_r.c#projectinput">qh_projectinput</a>
project input along one or more dimensions +
Delaunay projection </li>
<li><a href="geom2_r.c#randommatrix">qh_randommatrix</a>
generate a random dimXdim matrix in range (-1,1) </li>
<li><a href="io_r.c#readpoints">qh_readpoints</a> read
points from input </li>
<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
input points using row matrix </li>
<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
input points using qh low_bound/high_bound </li>
<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
points to paraboloid for Delaunay triangulation </li>
<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
generate dual for halfspace intersection with interior
point </li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
<ul>
<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add
point to convex hull </li>
<li><a href="poly2_r.c#findbestfacet">qh_findbestfacet</a>
find facet that is furthest below a point </li>
<li><a href="poly2_r.c#findfacet_all">qh_findfacet_all</a>
exhaustive search for facet below a point </li>
<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
the convex hull of a set of points </li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
<ul>
<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
collect statistics for qh.facet_list </li>
<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
return nearest vertex to point </li>
<li><a href="poly2_r.c#point">qh_point</a> return point
for a point ID </li>
<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
return temporary set of facets indexed by point
ID </li>
<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
for a point</li>
<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
return vertices (if any) for all points</li>
<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
print all statistics </li>
<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
print neighborhood of one or two facets </li>
<li><a href="libqhull_r.c#printsummary">qh_printsummary</a>
print summary </li>
<li><a href="io_r.c#produce_output">qh_produce_output</a>
print the results of qh_qhull() </li>
<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
compute Voronoi centers for all facets </li>
</ul>
<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
<ul>
<li><a href="io_r.c#dfacet">dfacet</a> print facet by
ID from debugger </li>
<li><a href="io_r.c#dvertex">dvertex</a> print vertex
by ID from debugger </li>
<li><a href="poly2_r.c#check_output">qh_check_output</a>
check output </li>
<li><a href="poly2_r.c#check_points">qh_check_points</a>
verify that all points are inside the convex hull
</li>
<li><a href="user_r.c#errexit">qh_errexit</a> report
error with a facet and a ridge</li>
<li><a href="libqhull_r.c#errexit2">qh_errexit2</a> report
error with two facets </li>
<li><a href="user_r.c#errprint">qh_errprint</a> print
erroneous facets, ridge, and vertex </li>
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
print all fields for a list of facets </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,308 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>qset_r.c -- set data type and operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>qset_r.c -- set data type and operations</h2>
<blockquote>
<p>Qhull's data structures are constructed from sets. The
functions and macros in qset_r.c construct, iterate, and
modify these sets. They are the most frequently called
functions in Qhull. For this reason, efficiency is the
primary concern. </p>
<p>In Qhull, a <i>set</i> is represented by an unordered
array of pointers with a maximum size and a NULL
terminator (<a href="qset_r.h#setT">setT</a>).
Most sets correspond to mathematical sets
(i.e., the pointers are unique). Some sets are sorted to
enforce uniqueness. Some sets are ordered. For example,
the order of vertices in a ridge determine the ridge's
orientation. If you reverse the order of adjacent
vertices, the orientation reverses. Some sets are not
mathematical sets. They may be indexed as an array and
they may include NULL pointers. </p>
<p>The most common operation on a set is to iterate its
members. This is done with a 'FOREACH...' macro. Each set
has a custom macro. For example, 'FOREACHvertex_'
iterates over a set of vertices. Each vertex is assigned
to the variable 'vertex' from the pointer 'vertexp'. </p>
<p>Most sets are constructed by appending elements to the
set. The last element of a set is either NULL or the
index of the terminating NULL for a partially full set.
If a set is full, appending an element copies the set to
a larger array. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <b>Set</b>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="qset_r.c">qset_r.c</a> and
<a href="qset_r.h">qset_r.h</a></h3>
<ul>
<li><a href="#stype">Data types and constants</a> </li>
<li><a href="#seach">FOREACH macros</a> </li>
<li><a href="#saccess">access and size macros</a> </li>
<li><a href="#sint">internal macros</a> </li>
<li><a href="#saddr">address macros</a><p>&nbsp;</li>
<li><a href="#snew">Allocation and deallocation functions</a> </li>
<li><a href="#spred">Access and predicate functions</a>
</li>
<li><a href="#sadd">Add functions</a> </li>
<li><a href="#scheck">Check and print functions</a></li>
<li><a href="#scopy">Copy, compact, and zero functions</a></li>
<li><a href="#sdel">Delete functions</a> </li>
<li><a href="#stemp">Temporary set functions</a> </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stype">Data types and
constants</a></h3>
<ul>
<li><a href="qset_r.h#SETelemsize">SETelemsize</a> size
of a set element in bytes </li>
<li><a href="qset_r.h#setT">setT</a> a set with a
maximum size and a current size</li>
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
global sets for temporary sets, etc. </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
<ul>
<li><a href="qset_r.h#FOREACHelem_">FOREACHelem_</a>
assign 'elem' to each element in a set </li>
<li><a href="qset_r.h#FOREACHset_">FOREACHset_</a>
assign 'set' to each set in a set of sets </li>
<li><a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
define a FOREACH iterator </li>
<li><a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
define an indexed FOREACH iterator </li>
<li><a href="qset_r.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
define a reversed FOREACH iterator </li>
<li><a href="qset_r.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
define a FOREACH iterator with e[1] and e[0]
reversed </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saccess">Access and
size macros</a></h3>
<ul>
<li><a href="qset_r.h#SETelem_">SETelem_</a> return the
n'th element of set </li>
<li><a href="qset_r.h#SETelemt_">SETelemt_</a> return
the n'th element of set as a type</li>
<li><a href="qset_r.h#SETempty_">SETempty_</a> return
true (1) if set is empty </li>
<li><a href="qset_r.h#SETfirst_">SETfirst_</a> return
first element of set </li>
<li><a href="qset_r.h#SETfirstt_">SETfirstt_</a> return
first element of set as a type</li>
<li><a href="qset_r.h#SETindex_">SETindex_</a> return
index of elem in set </li>
<li><a href="qset_r.h#SETreturnsize_">SETreturnsize_</a>
return size of a set (normally use <a href="qset_r.c#setsize">qh_setsize</a>) </li>
<li><a href="qset_r.h#SETsecond_">SETsecond_</a> return
second element of set </li>
<li><a href="qset_r.h#SETsecondt_">SETsecondt_</a>
return second element of set as a type</li>
<li><a href="qset_r.h#SETtruncate_">SETtruncate_</a>
truncate set to size, i.e., qh_settruncate()</li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
<ul>
<li><a href="qset_r.c#SETsizeaddr_">SETsizeaddr_</a>
return pointer to end element of a set (indicates
current size) </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
<ul>
<li><a href="qset_r.h#SETaddr_">SETaddr_</a> return
address of a set's elements </li>
<li><a href="qset_r.h#SETelemaddr_">SETelemaddr_</a>
return address of the n'th element of a set </li>
<li><a href="qset_r.h#SETref_">SETref_</a> l_r.h.s. for
modifying the current element in a FOREACH
iteration </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="snew">Allocation and
deallocation functions</a></h3>
<ul>
<li><a href="qset_r.c#setfree">qh_setfree</a> free the
space occupied by a set </li>
<li><a href="qset_r.c#setfree2">qh_setfree2</a> free a
set and its elements </li>
<li><a href="qset_r.c#setfreelong">qh_setfreelong</a>
free a set only if it is in long memory </li>
<li><a href="qset_r.c#setnew">qh_setnew</a> create a new
set </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="spred">Access and
predicate functions </a></h3>
<ul>
<li><a href="qset_r.c#setendpointer">qh_setendpointer</a> return
pointer to NULL terminator of a set</li>
<li><a href="qset_r.c#setequal">qh_setequal</a> return 1
if two sorted sets are equal </li>
<li><a href="qset_r.c#setequal_except">qh_setequal_except</a>
return 1 if two sorted sets are equal except for
an element </li>
<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
return 1 if two sorted sets are equal except for
a pair of skipped elements </li>
<li><a href="qset_r.c#setin">qh_setin</a> return 1 if an
element is in a set </li>
<li><a href="qset_r.c#setindex">qh_setindex</a> return
the index of an element in a set </li>
<li><a href="qset_r.c#setlast">qh_setlast</a> return
last element of a set</li>
<li><a href="qset_r.c#setsize">qh_setsize</a> returns
the size of a set </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
<ul>
<li><a href="qset_r.c#setaddnth">qh_setaddnth</a> add a
element as n'th element of sorted or unsorted set
</li>
<li><a href="qset_r.c#setaddsorted">qh_setaddsorted</a>
add an element to a sorted set </li>
<li><a href="qset_r.c#setappend">qh_setappend</a> append
an element to a set </li>
<li><a href="qset_r.c#setappend_set">qh_setappend_set</a>
append a set of elements to a set </li>
<li><a href="qset_r.c#setappend2ndlast">qh_setappend2ndlast</a>
add an element as the next to the last element in
a set </li>
<li><a href="qset_r.c#setlarger">qh_setlarger</a> return
a larger set with the same elements</li>
<li><a href="qset_r.c#setreplace">qh_setreplace</a>
replace one element with another in a set</li>
<li><a href="qset_r.c#setunique">qh_setunique</a> add an
element if it is not already in a set </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
<ul>
<li><a href="qset_r.c#setcheck">qh_setcheck</a> check a
set for validity </li>
<li><a href="qset_r.c#setprint">qh_setprint</a> print a
set's elements to fp </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
<ul>
<li><a href="qset_r.c#setcompact">qh_setcompact</a>
compact NULLs from an unsorted set </li>
<li><a href="qset_r.c#setcopy">qh_setcopy</a> make a
copy of a sorted or unsorted set </li>
<li><a href="qset_r.c#setduplicate">qh_setduplicate</a>
duplicate a set and its elements </li>
<li><a href="qset_r.c#settruncate">qh_settruncate</a>
truncate a set to size elements </li>
<li><a href="qset_r.c#setzero">qh_setzero</a> zero the
remainder of a set </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
<ul>
<li><a href="qset_r.c#setdel">qh_setdel</a> delete an
element from an unsorted set. </li>
<li><a href="qset_r.c#setdellast">qh_setdellast</a>
delete and return last element from a set</li>
<li><a href="qset_r.c#setdelnth">qh_setdelnth</a> delete
and return nth element from an unsorted set </li>
<li><a href="qset_r.c#setdelnthsorted">qh_setdelnthsorted</a>
delete and return nth element from a sorted set </li>
<li><a href="qset_r.c#setdelsorted">qh_setdelsorted</a>
delete an element from a sorted set </li>
<li><a href="qset_r.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
create a sorted set not containing the nth
element </li>
</ul>
<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
<ul>
<li><a href="qset_r.c#settemp">qh_settemp</a> return a
temporary set and append it qhmem.tempstack</li>
<li><a href="qset_r.c#settempfree">qh_settempfree</a>
free and pop a set from qhmem.tempstack</li>
<li><a href="qset_r.c#settempfree_all">qh_settempfree_all</a>
free all sets in qhmem.tempstack </li>
<li><a href="qset_r.c#settemppop">qh_settemppop</a> pop
a set from qhmem.tempstack (makes it permanent) </li>
<li><a href="qset_r.c#settemppush">qh_settemppush</a>
push a set unto qhmem.tempstack (makes it
temporary) </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,161 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>stat_r.c -- statistical operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
</p>
<hr>
<h2>stat_r.c -- statistical operations</h2>
<blockquote>
<p>Qhull records many statistics. These functions and
macros make it inexpensive to add a statistic.
<p>As with Qhull's global variables, the statistics data structure is
accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro
is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'.
Statistics
may be turned off in user_r.h. If so, all but the 'zz'
statistics are ignored.</p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <b>Stat</b> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<h3>Index to <a href="stat_r.c">stat_r.c</a> and
<a href="stat_r.h">stat_r.h</a></h3>
<ul>
<li><a href="#ttype">stat_r.h types</a> </li>
<li><a href="#tconst">stat_r.h constants</a> </li>
<li><a href="#tmacro">stat_r.h macros</a> </li>
<li><a href="#tfunc">stat_r.c functions</a> </li>
</ul>
<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="ttype">stat_r.h types</a></h3>
<ul>
<li><a href="stat_r.h#intrealT">intrealT</a> union of
integer and real</li>
<li><a href="stat_r.h#qhstat">qhstat</a> global data
structure for statistics </li>
</ul>
<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tconst">stat_r.h
constants</a></h3>
<ul>
<li><a href="stat_r.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
<li><a href="stat_r.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
</li>
<li><a href="stat_r.h#ZZstat">ZZstat</a> Z.../W... statistics that
remain defined if qh_KEEPstatistics=0
</li>
<li><a href="stat_r.h#ztype">ztype</a> zdoc, zinc, etc.
for definining statistics </li>
</ul>
<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tmacro">stat_r.h macros</a></h3>
<ul>
<li><a href="stat_r.h#MAYdebugx">MAYdebugx</a> called
frequently for error trapping </li>
<li><a href="stat_r.h#zadd_">zadd_/wadd_</a> add value
to an integer or real statistic </li>
<li><a href="stat_r.h#zdef_">zdef_</a> define a
statistic </li>
<li><a href="stat_r.h#zinc_">zinc_</a> increment an
integer statistic </li>
<li><a href="stat_r.h#zmax_">zmax_/wmax_</a> update
integer or real maximum statistic </li>
<li><a href="stat_r.h#zmin_">zmin_/wmin_</a> update
integer or real minimum statistic </li>
<li><a href="stat_r.h#zval_">zval_/wval_</a> set or
return value of a statistic </li>
</ul>
<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tfunc">stat_r.c
functions</a></h3>
<ul>
<li><a href="stat_r.c#allstatA">qh_allstatA</a> define
statistics in groups of 20 </li>
<li><a href="stat_r.c#allstatistics">qh_allstatistics</a>
reset printed flag for all statistics </li>
<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
collect statistics for qh.facet_list </li>
<li><a href="stat_r.c#initstatistics">qh_initstatistics</a>
allocate and initialize statistics </li>
<li><a href="stat_r.c#newstats">qh_newstats</a> returns
True if statistics for zdoc </li>
<li><a href="stat_r.c#nostatistic">qh_nostatistic</a>
true if no statistic to print </li>
<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
print all statistics </li>
<li><a href="stat_r.c#printstatistics">qh_printstatistics</a>
print statistics to a file </li>
<li><a href="stat_r.c#printstatlevel">qh_printstatlevel</a>
print level information for a statistic </li>
<li><a href="stat_r.c#printstats">qh_printstats</a>
print statistics for a zdoc group </li>
<li><a href="stat_r.c#stddev">qh_stddev</a> compute the
standard deviation and average from statistics </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,271 @@
<!-- Do not edit with Front Page, it adds too many spaces -->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>user_r.c -- user-definable operations</title>
</head>
<body>
<!-- Navigation links -->
<p><a name="TOP"><b>Up:</b></a> <a
href="http://www.qhull.org">Home page</a> for Qhull<br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
</p>
<hr>
<h2>user_r.c -- user-definable operations</h2>
<blockquote>
<p>This section contains functions and constants that the
user may want to change. </p>
</blockquote>
<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
<hr>
<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <b>User</b>
</p>
<h3>Index to <a href="user_r.c">user_r.c</a>, <a href="usermem_r.c">usermem_r.c</a>, <a href="userprintf_r.c">userprintf_r.c</a>, <a href="userprintf_rbox_r.c">userprintf_rbox_r.c</a> and
<a href="user_r.h">user_r.h</a></h3>
<ul>
<li><a href="#qulllib">qhull library constants</a></li>
<li><a href="#utype">user_r.h data types and
configuration macros</a> </li>
<li><a href="#ujoggle">joggle constants</a></li>
<li><a href="#uperform">performance related constants</a></li>
<li><a href="#umemory">memory constants</a></li>
<li><a href="#ucond">conditional compilation</a></li>
<li><a href="#umerge">merge constants</a> </li>
<li><a href="#ufunc">user_r.c functions</a> </li>
<li><a href="#u2func">usermem_r.c functions</a> </li>
<li><a href="#u3func">userprintf_r.c functions</a> </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
<ul>
<li><a href="user_r.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
<li><a href="user_r.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
<li><a href="user_r.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="utype">user_r.h data
types and configuration macros</a></h3>
<ul>
<li><a href="user_r.h#realT">realT, qh_REAL...</a> size
of floating point numbers </li>
<li><a href="user_r.h#countT">countT, COUNTmax</a> size
of counts and identifiers, typically 'int' or 'long long' </li>
<li><a href="user_r.h#CPUclock">qh_CPUclock</a> clock()
function for reporting the total time spent by
Qhull </li>
<li><a href="user_r.h#RANDOM">qh_RANDOM...</a> random
number generator </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
<ul>
<li><a href="user_r.h#DEFAULTbox">qh_DEFAULTbox</a>
define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
<li><a href="user_r.h#INFINITE">qh_INFINITE</a> on
output, indicates Voronoi center at infinity </li>
<li><a href="user_r.h#ORIENTclock">qh_ORIENTclock</a>
define convention for orienting facets</li>
<li><a href="user_r.h#ZEROdelaunay">qh_ZEROdelaunay</a>
define facets that are ignored in Delaunay triangulations</li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
<ul>
<li><a href="user_r.h#JOGGLEagain">qh_JOGGLEagain</a>
how often to retry before using qh_JOGGLEmaxincrease
again </li>
<li><a href="user_r.h#JOGGLEdefault">qh_JOGGLEdefault</a>
default value for qh.JOGGLEmax for 'QP' </li>
<li><a href="user_r.h#JOGGLEincrease">qh_JOGGLEincrease</a>
factor to increase qh.JOGGLEmax on retrys for
'QPn' </li>
<li><a href="user_r.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
for increasing qh.JOGGLEmax relative to
qh.MAXwidth </li>
<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
report error if this many retries </li>
<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEretry</a>
how often to retry before using qh_JOGGLEmax </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="uperform">performance
related constants</a></h3>
<ul>
<li><a href="user_r.h#HASHfactor">qh_HASHfactor</a>
total/used hash slots </li>
<li><a href="user_r.h#INITIALmax">qh_INITIALmax</a> if
dim &gt;= qh_INITIALmax, use min/max coordinate
points for initial simplex </li>
<li><a href="user_r.h#INITIALsearch">qh_INITIALsearch</a>
if qh.INITIALmax, search points up to this
dimension </li>
<li><a href="user_r.h#NOtrace">qh_NOtrace</a> disallow
tracing </li>
<li><a href="user_r.h#VERIFYdirect">qh_VERIFYdirect</a>
'Tv' verifies all <em>points X facets</em> if op
count is smaller </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
<ul>
<li><a href="user_r.h#MEMalign">qh_MEMalign</a> memory
alignment for qh_meminitbuffers() in global_r.c </li>
<li><a href="user_r.h#MEMbufsize">qh_MEMbufsize</a>
size of additional memory buffers </li>
<li><a href="user_r.h#MEMinitbuf">qh_MEMinitbuf</a>
size of initial memory buffer </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
<ul>
<li><a href="user_r.h#compiler">compiler</a> defined symbols,
e.g., _STDC_ and _cplusplus
<li><a href="user_r.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
compute furthest distance to an outside point instead of storing it with the facet
<li><a href="user_r.h#KEEPstatistics">qh_KEEPstatistics</a>
enable statistic gathering and reporting with option 'Ts'
<li><a href="user_r.h#MAXoutside">qh_MAXoutside</a>
record outer plane for each facet
<li><a href="user_r.h#NOmerge">qh_NOmerge</a>
disable facet merging
<li><a href="user_r.h#NOtrace">qh_NOtrace</a>
disable tracing with option 'T4'
<li><a href="user_r.h#QHpointer">qh_QHpointer</a>
access global data with pointer or static structure
<li><a href="user_r.h#QUICKhelp">qh_QUICKhelp</a>
use abbreviated help messages, e.g., for degenerate inputs
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umerge">merge
constants</a></h3>
<ul>
<li><a href="user_r.h#BESTcentrum">qh_BESTcentrum</a>
when does qh_findbestneighbor() test centrums? </li>
<li><a href="user_r.h#BESTnonconvex">qh_BESTnonconvex</a>
when does qh_findbestneighbor() test nonconvex
ridges only? </li>
<li><a href="user_r.h#COPLANARratio">qh_COPLANARratio</a>
what is qh.MINvisible? </li>
<li><a href="user_r.h#DIMreduceBuild">qh_DIMreduceBuild</a>
max dimension for vertex reduction </li>
<li><a href="user_r.h#DIMmergeVertex">qh_DIMmergeVertex</a>
max dimension for vertex merging </li>
<li><a href="user_r.h#DISToutside">qh_DISToutside</a>
when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
<li><a href="user_r.h#MAXnarrow">qh_MAXnarrow</a> max.
cosine for qh.NARROWhull </li>
<li><a href="user_r.h#MAXnewcentrum">qh_MAXnewcentrum</a>
when does qh_reducevertices_centrum() reset the
centrum? </li>
<li><a href="user_r.h#MAXnewmerges">qh_MAXnewmerges</a>
when does qh_merge_nonconvex() call
qh_reducevertices_centrums? </li>
<li><a href="user_r.h#RATIOnearinside">qh_RATIOnearinside</a>
ratio for retaining inside points for
qh_check_maxout() </li>
<li><a href="user_r.h#SEARCHdist">qh_SEARCHdist</a>
when is facet coplanar with the best facet for qh_findbesthorizon</li>
<li><a href="user_r.h#USEfindbestnew">qh_USEfindbestnew</a>
when to use qh_findbestnew for qh_partitionpoint()</li>
<li><a href="user_r.h#WARNnarrow">qh_WARNnarrow</a>
max. cosine to warn about qh.NARROWhull </li>
<li><a href="user_r.h#WIDEcoplanar">qh_WIDEcoplanar</a>
what is a wide facet? </li>
<li><a href="user_r.h#WIDEduplicate">qh_WIDEduplicate</a>
what is a wide ratio on merging duplicate ridges? </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ufunc">user_r.c
functions</a></h3>
<ul>
<li><a href="user_r.c#qhull_template">Qhull template</a> for calling qh_new_qhull from your program</li>
<li><a href="user_r.c#errexit">qh_errexit</a> report
error and exit qhull()</li>
<li><a href="user_r.c#errprint">qh_errprint</a> print
information about facets and ridges </li>
<li><a href="user_r.c#new_qhull">qh_new_qhull</a> call qhull on an array
of points</li>
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
print all fields of all facets </li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u2func">usermem_r.c
functions</a></h3>
<ul>
<li><a href="usermem_r.c#qh_exit">qh_exit</a> exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp</li>
<li><a href="usermem_r.c#qh_fprintf_stderr">qh_fprintf_stderr</a> print to stderr when qh->ferr is not defined.</li>
<li><a href="usermem_r.c#qh_free">qh_free</a> free memory, same as free().</li>
<li><a href="usermem_r.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
</ul>
<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u3func">userprintf_r.c
and userprintf_rbox,c functions</a></h3>
<ul>
<li><a href="userprintf_r.c#qh_fprintf">qh_fprintf</a> print
information from Qhull, sames as fprintf(). </li>
<li><a href="userprintf_rbox_r.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
information from Rbox, sames as fprintf(). </li>
</ul>
<p><!-- Navigation links --> </p>
<hr>
<p><b>Up:</b>
<a href="http://www.qhull.org">Home page for
Qhull</a> <br>
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
&#149; <a href="../../html/qh-quick.htm#options">Options</a>
&#149; <a href="../../html/qh-opto.htm#output">Output</a>
&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
&#149; <a href="../../html/qh-optp.htm#print">Print</a>
&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
&#149; <a href="index.htm">Functions</a><br>
<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
&#149; <a href="qh-user_r.htm">User</a><br>
</p>
<p><!-- GC common information --> </p>
<hr>
<p><a href="http://www.geom.uiuc.edu/"><img
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
Geometry Center Home Page </i></p>
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
</a><br>
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
</body>
</html>

View File

@@ -0,0 +1,404 @@
; qhull_r-exports.def -- msvc module-definition file
;
; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
; [jan'14] 391 symbols
; Same as ../libqhullp/qhull-exports.def without DATA items (reentrant)
;
; $Id: //main/2015/qhull/src/libqhull_r/qhull_r-exports.def#3 $$Change: 2047 $
; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
;
; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
VERSION 7.0
EXPORTS
qh_addhash
qh_addpoint
qh_all_merges
qh_allstatA
qh_allstatB
qh_allstatC
qh_allstatD
qh_allstatE
qh_allstatE2
qh_allstatF
qh_allstatG
qh_allstatH
qh_allstatI
qh_allstatistics
qh_appendfacet
qh_appendmergeset
qh_appendprint
qh_appendvertex
qh_argv_to_command
qh_argv_to_command_size
qh_attachnewfacets
qh_backnormal
qh_basevertices
qh_build_withrestart
qh_buildhull
qh_buildtracing
qh_check_bestdist
qh_check_dupridge
qh_check_maxout
qh_check_output
qh_check_point
qh_check_points
qh_checkconnect
qh_checkconvex
qh_checkfacet
qh_checkflags
qh_checkflipped
qh_checkflipped_all
qh_checkpolygon
qh_checkvertex
qh_checkzero
qh_clear_outputflags
qh_clearcenters
qh_clock
qh_collectstatistics
qh_compare_facetarea
qh_compare_facetmerge
qh_compare_facetvisit
qh_compareangle
qh_comparemerge
qh_comparevisit
qh_copyfilename
qh_copynonconvex
qh_copypoints
qh_countfacets
qh_createsimplex
qh_crossproduct
qh_degen_redundant_facet
qh_degen_redundant_neighbors
qh_deletevisible
qh_delfacet
qh_delridge
qh_delvertex
qh_determinant
qh_detjoggle
qh_detroundoff
qh_detsimplex
qh_detvnorm
qh_detvridge
qh_detvridge3
qh_dfacet
qh_distnorm
qh_distplane
qh_distround
qh_divzero
qh_dvertex
qh_eachvoronoi
qh_eachvoronoi_all
qh_errexit
qh_errexit2
qh_errexit_rbox
qh_errprint
qh_exit
qh_facet2point
qh_facet3vertex
qh_facetarea
qh_facetarea_simplex
qh_facetcenter
qh_facetintersect
qh_facetvertices
qh_find_newvertex
qh_findbest
qh_findbest_test
qh_findbestfacet
qh_findbesthorizon
qh_findbestlower
qh_findbestneighbor
qh_findbestnew
qh_findfacet_all
qh_findgood
qh_findgood_all
qh_findgooddist
qh_findhorizon
qh_flippedmerges
qh_forcedmerges
qh_fprintf
qh_fprintf_rbox
qh_fprintf_stderr
qh_free
qh_freebuffers
qh_freebuild
qh_freeqhull
qh_furthestnext
qh_furthestout
qh_gausselim
qh_geomplanes
qh_getangle
qh_getarea
qh_getcenter
qh_getcentrum
qh_getdistance
qh_gethash
qh_getmergeset
qh_getmergeset_initial
qh_gram_schmidt
qh_hashridge
qh_hashridge_find
qh_infiniteloop
qh_init_A
qh_init_B
qh_init_qhull_command
qh_initbuild
qh_initflags
qh_initialhull
qh_initialvertices
qh_initqhull_buffers
qh_initqhull_globals
qh_initqhull_mem
qh_initqhull_outputflags
qh_initqhull_start
qh_initqhull_start2
qh_initstatistics
qh_initthresholds
qh_inthresholds
qh_isvertex
qh_joggleinput
qh_lib_check
qh_makenew_nonsimplicial
qh_makenew_simplicial
qh_makenewfacet
qh_makenewfacets
qh_makenewplanes
qh_makeridges
qh_malloc
qh_mark_dupridges
qh_markkeep
qh_markvoronoi
qh_matchduplicates
qh_matchneighbor
qh_matchnewfacets
qh_matchvertices
qh_maxabsval
qh_maxmin
qh_maxouter
qh_maxsimplex
qh_maydropneighbor
qh_memalloc
qh_memfree
qh_memfreeshort
qh_meminit
qh_meminitbuffers
qh_memsetup
qh_memsize
qh_memstatistics
qh_memtotal
qh_merge_degenredundant
qh_merge_nonconvex
qh_mergecycle
qh_mergecycle_all
qh_mergecycle_facets
qh_mergecycle_neighbors
qh_mergecycle_ridges
qh_mergecycle_vneighbors
qh_mergefacet
qh_mergefacet2d
qh_mergeneighbors
qh_mergeridges
qh_mergesimplex
qh_mergevertex_del
qh_mergevertex_neighbors
qh_mergevertices
qh_minabsval
qh_mindiff
qh_nearcoplanar
qh_nearvertex
qh_neighbor_intersections
qh_new_qhull
qh_newfacet
qh_newhashtable
qh_newridge
qh_newstats
qh_newvertex
qh_newvertices
qh_nextfurthest
qh_nextridge3d
qh_normalize
qh_normalize2
qh_nostatistic
qh_option
qh_order_vertexneighbors
qh_orientoutside
qh_out1
qh_out2n
qh_out3n
qh_outcoplanar
qh_outerinner
qh_partitionall
qh_partitioncoplanar
qh_partitionpoint
qh_partitionvisible
qh_point
qh_point_add
qh_pointdist
qh_pointfacet
qh_pointid
qh_pointvertex
qh_postmerge
qh_precision
qh_premerge
qh_prepare_output
qh_prependfacet
qh_printafacet
qh_printallstatistics
qh_printbegin
qh_printcenter
qh_printcentrum
qh_printend
qh_printend4geom
qh_printextremes
qh_printextremes_2d
qh_printextremes_d
qh_printfacet
qh_printfacet2geom
qh_printfacet2geom_points
qh_printfacet2math
qh_printfacet3geom_nonsimplicial
qh_printfacet3geom_points
qh_printfacet3geom_simplicial
qh_printfacet3math
qh_printfacet3vertex
qh_printfacet4geom_nonsimplicial
qh_printfacet4geom_simplicial
qh_printfacetNvertex_nonsimplicial
qh_printfacetNvertex_simplicial
qh_printfacetheader
qh_printfacetlist
qh_printfacetridges
qh_printfacets
qh_printhashtable
qh_printhelp_degenerate
qh_printhelp_narrowhull
qh_printhelp_singular
qh_printhyperplaneintersection
qh_printline3geom
qh_printlists
qh_printmatrix
qh_printneighborhood
qh_printpoint
qh_printpoint3
qh_printpointid
qh_printpoints
qh_printpoints_out
qh_printpointvect
qh_printpointvect2
qh_printridge
qh_printspheres
qh_printstatistics
qh_printstatlevel
qh_printstats
qh_printsummary
qh_printvdiagram
qh_printvdiagram2
qh_printvertex
qh_printvertexlist
qh_printvertices
qh_printvneighbors
qh_printvnorm
qh_printvoronoi
qh_printvridge
qh_produce_output
qh_produce_output2
qh_projectdim3
qh_projectinput
qh_projectpoint
qh_projectpoints
qh_qhull
qh_rand
qh_randomfactor
qh_randommatrix
qh_rboxpoints
qh_readfeasible
qh_readpoints
qh_reducevertices
qh_redundant_vertex
qh_remove_extravertices
qh_removefacet
qh_removevertex
qh_rename_sharedvertex
qh_renameridgevertex
qh_renamevertex
qh_resetlists
qh_rotateinput
qh_rotatepoints
qh_roundi
qh_scaleinput
qh_scalelast
qh_scalepoints
qh_setaddnth
qh_setaddsorted
qh_setappend
qh_setappend2ndlast
qh_setappend_set
qh_setcheck
qh_setcompact
qh_setcopy
qh_setdel
qh_setdelaunay
qh_setdellast
qh_setdelnth
qh_setdelnthsorted
qh_setdelsorted
qh_setduplicate
qh_setequal
qh_setequal_except
qh_setequal_skip
qh_setfacetplane
qh_setfeasible
qh_setfree
qh_setfree2
qh_setfreelong
qh_sethalfspace
qh_sethalfspace_all
qh_sethyperplane_det
qh_sethyperplane_gauss
qh_setin
qh_setindex
qh_setlarger
qh_setlast
qh_setnew
qh_setnew_delnthsorted
qh_setprint
qh_setreplace
qh_setsize
qh_settemp
qh_settempfree
qh_settempfree_all
qh_settemppop
qh_settemppush
qh_settruncate
qh_setunique
qh_setvoronoi_all
qh_setzero
qh_sharpnewfacets
qh_skipfacet
qh_skipfilename
qh_srand
qh_stddev
qh_strtod
qh_strtol
qh_test_appendmerge
qh_test_vneighbors
qh_tracemerge
qh_tracemerging
qh_triangulate
qh_triangulate_facet
qh_triangulate_link
qh_triangulate_mirror
qh_triangulate_null
qh_updatetested
qh_updatevertices
qh_user_memsizes
qh_version
qh_version2
qh_vertexintersect
qh_vertexintersect_new
qh_vertexneighbors
qh_vertexridges
qh_vertexridges_facet
qh_vertexsubset
qh_voronoi_center
qh_willdelete
qh_zero

View File

@@ -0,0 +1,158 @@
/*<html><pre> -<a href="qh-qhull_r.htm"
>-------------------------------</a><a name="TOP">-</a>
qhull_ra.h
all header files for compiling qhull with reentrant code
included before C++ headers for user_r.h:QHULL_CRTDBG
see qh-qhull.htm
see libqhull_r.h for user-level definitions
see user_r.h for user-definable constants
defines internal functions for libqhull_r.c global_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/qhull_ra.h#6 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
Notes: grep for ((" and (" to catch fprintf("lkasdjf");
full parens around (x?y:z)
use '#include "libqhull_r/qhull_ra.h"' to avoid name clashes
*/
#ifndef qhDEFqhulla
#define qhDEFqhulla 1
#include "libqhull_r.h" /* Includes user_r.h and data types */
#include "stat_r.h"
#include "random_r.h"
#include "mem_r.h"
#include "qset_r.h"
#include "geom_r.h"
#include "merge_r.h"
#include "poly_r.h"
#include "io_r.h"
#include <setjmp.h>
#include <string.h>
#include <math.h>
#include <float.h> /* some compilers will not need float.h */
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
/*** uncomment here and qset_r.c
if string.h does not define memcpy()
#include <memory.h>
*/
#if qh_CLOCKtype == 2 /* defined in user_r.h from libqhull_r.h */
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#endif
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4100) /* unreferenced formal parameter */
#pragma warning( disable : 4127) /* conditional expression is constant */
#pragma warning( disable : 4706) /* assignment within conditional function */
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
#endif
/* ======= -macros- =========== */
/*-<a href="qh-qhull_r.htm#TOC"
>--------------------------------</a><a name="traceN">-</a>
traceN((qh, qh->ferr, 0Nnnn, "format\n", vars));
calls qh_fprintf if qh.IStracing >= N
Add debugging traps to the end of qh_fprintf
notes:
removing tracing reduces code size but doesn't change execution speed
*/
#ifndef qh_NOtrace
#define trace0(args) {if (qh->IStracing) qh_fprintf args;}
#define trace1(args) {if (qh->IStracing >= 1) qh_fprintf args;}
#define trace2(args) {if (qh->IStracing >= 2) qh_fprintf args;}
#define trace3(args) {if (qh->IStracing >= 3) qh_fprintf args;}
#define trace4(args) {if (qh->IStracing >= 4) qh_fprintf args;}
#define trace5(args) {if (qh->IStracing >= 5) qh_fprintf args;}
#else /* qh_NOtrace */
#define trace0(args) {}
#define trace1(args) {}
#define trace2(args) {}
#define trace3(args) {}
#define trace4(args) {}
#define trace5(args) {}
#endif /* qh_NOtrace */
/*-<a href="qh-qhull_r.htm#TOC"
>--------------------------------</a><a name="QHULL_UNUSED">-</a>
Define an unused variable to avoid compiler warnings
Derived from Qt's corelib/global/qglobal.h
*/
#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
template <typename T>
inline void qhullUnused(T &x) { (void)x; }
# define QHULL_UNUSED(x) qhullUnused(x);
#else
# define QHULL_UNUSED(x) (void)x;
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***** -libqhull_r.c prototypes (alphabetical after qhull) ********************/
void qh_qhull(qhT *qh);
boolT qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
void qh_buildhull(qhT *qh);
void qh_buildtracing(qhT *qh, pointT *furthest, facetT *facet);
void qh_build_withrestart(qhT *qh);
void qh_errexit2(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet);
void qh_findhorizon(qhT *qh, pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
pointT *qh_nextfurthest(qhT *qh, facetT **visible);
void qh_partitionall(qhT *qh, setT *vertices, pointT *points,int npoints);
void qh_partitioncoplanar(qhT *qh, pointT *point, facetT *facet, realT *dist);
void qh_partitionpoint(qhT *qh, pointT *point, facetT *facet);
void qh_partitionvisible(qhT *qh, boolT allpoints, int *numpoints);
void qh_precision(qhT *qh, const char *reason);
void qh_printsummary(qhT *qh, FILE *fp);
/***** -global_r.c internal prototypes (alphabetical) ***********************/
void qh_appendprint(qhT *qh, qh_PRINT format);
void qh_freebuild(qhT *qh, boolT allmem);
void qh_freebuffers(qhT *qh);
void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
/***** -stat_r.c internal prototypes (alphabetical) ***********************/
void qh_allstatA(qhT *qh);
void qh_allstatB(qhT *qh);
void qh_allstatC(qhT *qh);
void qh_allstatD(qhT *qh);
void qh_allstatE(qhT *qh);
void qh_allstatE2(qhT *qh);
void qh_allstatF(qhT *qh);
void qh_allstatG(qhT *qh);
void qh_allstatH(qhT *qh);
void qh_freebuffers(qhT *qh);
void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFqhulla */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,502 @@
/*<html><pre> -<a href="qh-set_r.htm"
>-------------------------------</a><a name="TOP">-</a>
qset_r.h
header file for qset_r.c that implements set
see qh-set_r.htm and qset_r.c
only uses mem_r.c, malloc/free
for error handling, writes message and calls
qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL);
set operations satisfy the following properties:
- sets have a max size, the actual size (if different) is stored at the end
- every set is NULL terminated
- sets may be sorted or unsorted, the caller must distinguish this
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/qset_r.h#4 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFset
#define qhDEFset 1
#include <stdio.h>
/*================= -structures- ===============*/
#ifndef DEFsetT
#define DEFsetT 1
typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
#endif
#ifndef DEFqhT
#define DEFqhT 1
typedef struct qhT qhT; /* defined in libqhull_r.h */
#endif
/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
/*-<a href="qh-set_r.htm#TOC"
>----------------------------------------</a><a name="setT">-</a>
setT
a set or list of pointers with maximum size and actual size.
variations:
unsorted, unique -- a list of unique pointers with NULL terminator
user guarantees uniqueness
sorted -- a sorted list of unique pointers with NULL terminator
qset_r.c guarantees uniqueness
unsorted -- a list of pointers terminated with NULL
indexed -- an array of pointers with NULL elements
structure for set of n elements:
--------------
| maxsize
--------------
| e[0] - a pointer, may be NULL for indexed sets
--------------
| e[1]
--------------
| ...
--------------
| e[n-1]
--------------
| e[n] = NULL
--------------
| ...
--------------
| e[maxsize] - n+1 or NULL (determines actual size of set)
--------------
*/
/*-- setelemT -- internal type to allow both pointers and indices
*/
typedef union setelemT setelemT;
union setelemT {
void *p;
int i; /* integer used for e[maxSize] */
};
struct setT {
int maxsize; /* maximum number of elements (except NULL) */
setelemT e[1]; /* array of pointers, tail is NULL */
/* last slot (unless NULL) is actual size+1
e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
/* this may generate a warning since e[] contains
maxsize elements */
};
/*=========== -constants- =========================*/
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------</a><a name="SETelemsize">-</a>
SETelemsize
size of a set element in bytes
*/
#define SETelemsize ((int)sizeof(setelemT))
/*=========== -macros- =========================*/
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelement_">-</a>
FOREACHsetelement_(type, set, variable)
define FOREACH iterator
declare:
assumes *variable and **variablep are declared
no space in "variable)" [DEC Alpha cc compiler]
each iteration:
variable is set element
variablep is one beyond variable.
to repeat an element:
variablep--; / *repeat* /
at exit:
variable is NULL at end of loop
example:
#define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
notes:
use FOREACHsetelement_i_() if need index or include NULLs
WARNING:
nested loops can't use the same variable (define another FOREACH)
needs braces if nested inside another FOREACH
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
*/
#define FOREACHsetelement_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##p= (type **)&((set)->e[0].p); \
(variable= *variable##p++);)
/*-<a href="qh-set_r.htm#TOC"
>----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
FOREACHsetelement_i_(qh, type, set, variable)
define indexed FOREACH iterator
declare:
type *variable, variable_n, variable_i;
each iteration:
variable is set element, may be NULL
variable_i is index, variable_n is qh_setsize()
to repeat an element:
variable_i--; variable_n-- repeats for deleted element
at exit:
variable==NULL and variable_i==variable_n
example:
#define FOREACHfacet_i_( qh, facets ) FOREACHsetelement_i_( qh, facetT, facets, facet )
WARNING:
nested loops can't use the same variable (define another FOREACH)
needs braces if nested inside another FOREACH
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
*/
#define FOREACHsetelement_i_(qh, type, set, variable) \
if (((variable= NULL), set)) for (\
variable##_i= 0, variable= (type *)((set)->e[0].p), \
variable##_n= qh_setsize(qh, set);\
variable##_i < variable##_n;\
variable= (type *)((set)->e[++variable##_i].p) )
/*-<a href="qh-set_r.htm#TOC"
>--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
FOREACHsetelementreverse_(qh, type, set, variable)-
define FOREACH iterator in reverse order
declare:
assumes *variable and **variablep are declared
also declare 'int variabletemp'
each iteration:
variable is set element
to repeat an element:
variabletemp++; / *repeat* /
at exit:
variable is NULL
example:
#define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
notes:
use FOREACHsetelementreverse12_() to reverse first two elements
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHsetelementreverse_(qh, type, set, variable) \
if (((variable= NULL), set)) for (\
variable##temp= qh_setsize(qh, set)-1, variable= qh_setlast(qh, set);\
variable; variable= \
((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
FOREACHsetelementreverse12_(type, set, variable)-
define FOREACH iterator with e[1] and e[0] reversed
declare:
assumes *variable and **variablep are declared
each iteration:
variable is set element
variablep is one after variable.
to repeat an element:
variablep--; / *repeat* /
at exit:
variable is NULL at end of loop
example
#define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHsetelementreverse12_(type, set, variable) \
if (((variable= NULL), set)) for (\
variable##p= (type **)&((set)->e[1].p); \
(variable= *variable##p); \
variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
(variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------</a><a name="FOREACHelem_">-</a>
FOREACHelem_( set )-
iterate elements in a set
declare:
void *elem, *elemp;
each iteration:
elem is set element
elemp is one beyond
to repeat an element:
elemp--; / *repeat* /
at exit:
elem == NULL at end of loop
example:
FOREACHelem_(set) {
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------</a><a name="FOREACHset_">-</a>
FOREACHset_( set )-
iterate a set of sets
declare:
setT *set, **setp;
each iteration:
set is set element
setp is one beyond
to repeat an element:
setp--; / *repeat* /
at exit:
set == NULL at end of loop
example
FOREACHset_(sets) {
notes:
WARNING: needs braces if nested inside another FOREACH
*/
#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
/*-<a href="qh-set_r.htm#TOC"
>-----------------------------------------</a><a name="SETindex_">-</a>
SETindex_( set, elem )
return index of elem in set
notes:
for use with FOREACH iteration
WARN64 -- Maximum set size is 2G
example:
i= SETindex_(ridges, ridge)
*/
#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETref_">-</a>
SETref_( elem )
l.h.s. for modifying the current element in a FOREACH iteration
example:
SETref_(ridge)= anotherridge;
*/
#define SETref_(elem) (elem##p[-1])
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETelem_">-</a>
SETelem_(set, n)
return the n'th element of set
notes:
assumes that n is valid [0..size] and that set is defined
use SETelemt_() for type cast
*/
#define SETelem_(set, n) ((set)->e[n].p)
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETelemt_">-</a>
SETelemt_(set, n, type)
return the n'th element of set as a type
notes:
assumes that n is valid [0..size] and that set is defined
*/
#define SETelemt_(set, n, type) ((type*)((set)->e[n].p))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETelemaddr_">-</a>
SETelemaddr_(set, n, type)
return address of the n'th element of a set
notes:
assumes that n is valid [0..size] and set is defined
*/
#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETfirst_">-</a>
SETfirst_(set)
return first element of set
*/
#define SETfirst_(set) ((set)->e[0].p)
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETfirstt_">-</a>
SETfirstt_(set, type)
return first element of set as a type
*/
#define SETfirstt_(set, type) ((type*)((set)->e[0].p))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETsecond_">-</a>
SETsecond_(set)
return second element of set
*/
#define SETsecond_(set) ((set)->e[1].p)
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETsecondt_">-</a>
SETsecondt_(set, type)
return second element of set as a type
*/
#define SETsecondt_(set, type) ((type*)((set)->e[1].p))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETaddr_">-</a>
SETaddr_(set, type)
return address of set's elements
*/
#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETreturnsize_">-</a>
SETreturnsize_(set, size)
return size of a set
notes:
set must be defined
use qh_setsize(qhT *qh, set) unless speed is critical
*/
#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETempty_">-</a>
SETempty_(set)
return true(1) if set is empty
notes:
set may be NULL
*/
#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
/*-<a href="qh-set_r.htm#TOC"
>-------------------------------<a name="SETsizeaddr_">-</a>
SETsizeaddr_(set)
return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
Its type is setelemT* for strict aliasing
All SETelemaddr_ must be cast to setelemT
notes:
*SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
*/
#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
/*-<a href="qh-set_r.htm#TOC"
>---------------------------------------</a><a name="SETtruncate_">-</a>
SETtruncate_(set, size)
truncate set to size
see:
qh_settruncate()
*/
#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
set->e[size].p= NULL;}
/*======= prototypes in alphabetical order ============*/
#ifdef __cplusplus
extern "C" {
#endif
void qh_setaddsorted(qhT *qh, setT **setp, void *elem);
void qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem);
void qh_setappend(qhT *qh, setT **setp, void *elem);
void qh_setappend_set(qhT *qh, setT **setp, setT *setA);
void qh_setappend2ndlast(qhT *qh, setT **setp, void *elem);
void qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned id);
void qh_setcompact(qhT *qh, setT *set);
setT *qh_setcopy(qhT *qh, setT *set, int extra);
void *qh_setdel(setT *set, void *elem);
void *qh_setdellast(setT *set);
void *qh_setdelnth(qhT *qh, setT *set, int nth);
void *qh_setdelnthsorted(qhT *qh, setT *set, int nth);
void *qh_setdelsorted(setT *set, void *newelem);
setT *qh_setduplicate(qhT *qh, setT *set, int elemsize);
void **qh_setendpointer(setT *set);
int qh_setequal(setT *setA, setT *setB);
int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
void qh_setfree(qhT *qh, setT **set);
void qh_setfree2(qhT *qh, setT **setp, int elemsize);
void qh_setfreelong(qhT *qh, setT **set);
int qh_setin(setT *set, void *setelem);
int qh_setindex(setT *set, void *setelem);
void qh_setlarger(qhT *qh, setT **setp);
void *qh_setlast(setT *set);
setT *qh_setnew(qhT *qh, int size);
setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend);
void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
int qh_setsize(qhT *qh, setT *set);
setT *qh_settemp(qhT *qh, int setsize);
void qh_settempfree(qhT *qh, setT **set);
void qh_settempfree_all(qhT *qh);
setT *qh_settemppop(qhT *qh);
void qh_settemppush(qhT *qh, setT *set);
void qh_settruncate(qhT *qh, setT *set, int size);
int qh_setunique(qhT *qh, setT **set, void *elem);
void qh_setzero(qhT *qh, setT *set, int idx, int size);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFset */

View File

@@ -0,0 +1,247 @@
/*<html><pre> -<a href="index_r.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
random_r.c and utilities
Park & Miller's minimimal standard random number generator
argc/argv conversion
Used by rbox. Do not use 'qh'
*/
#include "libqhull_r.h"
#include "random_r.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4706) /* assignment within conditional function */
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
#endif
/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="argv_to_command">-</a>
qh_argv_to_command(argc, argv, command, max_size )
build command from argc/argv
max_size is at least
returns:
a space-delimited string of options (just as typed)
returns false if max_size is too short
notes:
silently removes
makes option string easy to input and output
matches qh_argv_to_command_size()
argc may be 0
*/
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
int i, remaining;
char *s;
*command= '\0'; /* max_size > 0 */
if (argc) {
if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
|| (s= strrchr( argv[0], '/')))
s++;
else
s= argv[0];
if ((int)strlen(s) < max_size) /* WARN64 */
strcpy(command, s);
else
goto error_argv;
if ((s= strstr(command, ".EXE"))
|| (s= strstr(command, ".exe")))
*s= '\0';
}
for (i=1; i < argc; i++) {
s= argv[i];
remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
if (!*s || strchr(s, ' ')) {
char *t= command + strlen(command);
remaining -= 2;
if (remaining < 0) {
goto error_argv;
}
*t++= ' ';
*t++= '"';
while (*s) {
if (*s == '"') {
if (--remaining < 0)
goto error_argv;
*t++= '\\';
}
*t++= *s++;
}
*t++= '"';
*t= '\0';
}else if (remaining < 0) {
goto error_argv;
}else
strcat(command, " ");
strcat(command, s);
}
return 1;
error_argv:
return 0;
} /* argv_to_command */
/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="argv_to_command_size">-</a>
qh_argv_to_command_size(argc, argv )
return size to allocate for qh_argv_to_command()
notes:
argc may be 0
actual size is usually shorter
*/
int qh_argv_to_command_size(int argc, char *argv[]) {
unsigned int count= 1; /* null-terminator if argc==0 */
int i;
char *s;
for (i=0; i<argc; i++){
count += (int)strlen(argv[i]) + 1; /* WARN64 */
if (i>0 && strchr(argv[i], ' ')) {
count += 2; /* quote delimiters */
for (s=argv[i]; *s; s++) {
if (*s == '"') {
count++;
}
}
}
}
return count;
} /* argv_to_command_size */
/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="rand">-</a>
qh_rand()
qh_srand(qh, seed )
generate pseudo-random number between 1 and 2^31 -2
notes:
For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
From Park & Miller's minimal standard random number generator
Communications of the ACM, 31:1192-1201, 1988.
Does not use 0 or 2^31 -1
this is silently enforced by qh_srand()
Can make 'Rn' much faster by moving qh_rand to qh_distplane
*/
/* Global variables and constants */
#define qh_rand_a 16807
#define qh_rand_m 2147483647
#define qh_rand_q 127773 /* m div a */
#define qh_rand_r 2836 /* m mod a */
int qh_rand(qhT *qh) {
int lo, hi, test;
int seed = qh->last_random;
hi = seed / qh_rand_q; /* seed div q */
lo = seed % qh_rand_q; /* seed mod q */
test = qh_rand_a * lo - qh_rand_r * hi;
if (test > 0)
seed= test;
else
seed= test + qh_rand_m;
qh->last_random= seed;
/* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
/* seed = qh_RANDOMmax; for testing */
return seed;
} /* rand */
void qh_srand(qhT *qh, int seed) {
if (seed < 1)
qh->last_random= 1;
else if (seed >= qh_rand_m)
qh->last_random= qh_rand_m - 1;
else
qh->last_random= seed;
} /* qh_srand */
/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randomfactor">-</a>
qh_randomfactor(qh, scale, offset )
return a random factor r * scale + offset
notes:
qh.RANDOMa/b are defined in global_r.c
qh_RANDOMint requires 'qh'
*/
realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
realT randr;
randr= qh_RANDOMint;
return randr * scale + offset;
} /* randomfactor */
/*-<a href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randommatrix">-</a>
qh_randommatrix(qh, buffer, dim, rows )
generate a random dim X dim matrix in range [-1,1]
assumes buffer is [dim+1, dim]
returns:
sets buffer to random numbers
sets rows to rows of buffer
sets row[dim] as scratch row
notes:
qh_RANDOMint requires 'qh'
*/
void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **rows) {
int i, k;
realT **rowi, *coord, realr;
coord= buffer;
rowi= rows;
for (i=0; i < dim; i++) {
*(rowi++)= coord;
for (k=0; k < dim; k++) {
realr= qh_RANDOMint;
*(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
}
}
*rowi= coord;
} /* randommatrix */
/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="strtol">-</a>
qh_strtol( s, endp) qh_strtod( s, endp)
internal versions of strtol() and strtod()
does not skip trailing spaces
notes:
some implementations of strtol()/strtod() skip trailing spaces
*/
double qh_strtod(const char *s, char **endp) {
double result;
result= strtod(s, endp);
if (s < (*endp) && (*endp)[-1] == ' ')
(*endp)--;
return result;
} /* strtod */
int qh_strtol(const char *s, char **endp) {
int result;
result= (int) strtol(s, endp, 10); /* WARN64 */
if (s< (*endp) && (*endp)[-1] == ' ')
(*endp)--;
return result;
} /* strtol */

View File

@@ -0,0 +1,41 @@
/*<html><pre> -<a href="qh-geom_r.htm"
>-------------------------------</a><a name="TOP">-</a>
random.h
header file for random and utility routines
see qh-geom_r.htm and random_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/random_r.h#4 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
*/
#ifndef qhDEFrandom
#define qhDEFrandom 1
#include "libqhull_r.h"
/*============= prototypes in alphabetical order ======= */
#ifdef __cplusplus
extern "C" {
#endif
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
int qh_argv_to_command_size(int argc, char *argv[]);
int qh_rand(qhT *qh);
void qh_srand(qhT *qh, int seed);
realT qh_randomfactor(qhT *qh, realT scale, realT offset);
void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
int qh_strtol(const char *s, char **endp);
double qh_strtod(const char *s, char **endp);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFrandom */

View File

@@ -0,0 +1,842 @@
/*<html><pre> -<a href="index_r.htm#TOC"
>-------------------------------</a><a name="TOP">-</a>
rboxlib_r.c
Generate input points
notes:
For documentation, see prompt[] of rbox_r.c
50 points generated for 'rbox D4'
WARNING:
incorrect range if qh_RANDOMmax is defined wrong (user_r.h)
*/
#include "libqhull_r.h" /* First for user_r.h */
#include "random_r.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER /* Microsoft Visual C++ */
#pragma warning( disable : 4706) /* assignment within conditional expression. */
#pragma warning( disable : 4996) /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
#endif
#define MAXdim 200
#define PI 3.1415926535897932384
/* ------------------------------ prototypes ----------------*/
int qh_roundi(qhT *qh, double a);
void qh_out1(qhT *qh, double a);
void qh_out2n(qhT *qh, double a, double b);
void qh_out3n(qhT *qh, double a, double b, double c);
void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim);
void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim);
void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
void qh_free(void *mem);
void *qh_malloc(size_t size);
int qh_rand(qhT *qh);
void qh_srand(qhT *qh, int seed);
/*-<a href="qh-qhull_r.htm#TOC"
>-------------------------------</a><a name="rboxpoints">-</a>
qh_rboxpoints(qh, rbox_command )
Generate points to qh->fout according to rbox options
Report errors on qh->ferr
returns:
0 (qh_ERRnone) on success
1 (qh_ERRinput) on input error
4 (qh_ERRmem) on memory error
5 (qh_ERRqhull) on internal error
notes:
To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user_r.c)
design:
Straight line code (consider defining a struct and functions):
Parse arguments into variables
Determine the number of points
Generate the points
*/
int qh_rboxpoints(qhT *qh, char* rbox_command) {
int i,j,k;
int gendim;
int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
int cubesize, diamondsize, seed=0, count, apex;
int dim=3 , numpoints= 0, totpoints, addpoints=0;
int issphere=0, isaxis=0, iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0;
int israndom=0, istime=0;
int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
double *coordp, *simplex= NULL, *simplexp;
int nthroot, mult[MAXdim];
double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
double box= qh_DEFAULTbox; /* scale all numbers before output */
double randmax= qh_RANDOMmax;
char command[200], seedbuf[200];
char *s= command, *t, *first_point= NULL;
time_t timedata;
int exitcode;
exitcode= setjmp(qh->rbox_errexit);
if (exitcode) {
/* same code for error exit and normal return, qh->NOerrexit is set */
if (simplex)
qh_free(simplex);
return exitcode;
}
*command= '\0';
strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
while (*s && !isspace(*s)) /* skip program name */
s++;
while (*s) {
while (*s && isspace(*s))
s++;
if (*s == '-')
s++;
if (!*s)
break;
if (isdigit(*s)) {
numpoints= qh_strtol(s, &s);
continue;
}
/* ============= read flags =============== */
switch (*s++) {
case 'c':
addcube= 1;
t= s;
while (isspace(*t))
t++;
if (*t == 'G')
cube= qh_strtod(++t, &s);
break;
case 'd':
adddiamond= 1;
t= s;
while (isspace(*t))
t++;
if (*t == 'G')
diamond= qh_strtod(++t, &s);
break;
case 'h':
iscdd= 1;
break;
case 'l':
isspiral= 1;
break;
case 'n':
NOcommand= 1;
break;
case 'r':
isregular= 1;
break;
case 's':
issphere= 1;
break;
case 't':
istime= 1;
if (isdigit(*s)) {
seed= qh_strtol(s, &s);
israndom= 0;
}else
israndom= 1;
break;
case 'x':
issimplex= 1;
break;
case 'y':
issimplex2= 1;
break;
case 'z':
qh->rbox_isinteger= 1;
break;
case 'B':
box= qh_strtod(s, &s);
isbox= 1;
break;
case 'C':
if (*s)
coincidentpoints= qh_strtol(s, &s);
if (*s == ',') {
++s;
coincidentradius= qh_strtod(s, &s);
}
if (*s == ',') {
++s;
coincidenttotal= qh_strtol(s, &s);
}
if (*s && !isspace(*s)) {
qh_fprintf_rbox(qh, qh->ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
qh_errexit_rbox(qh, qh_ERRinput);
}
if (coincidentpoints==0){
qh_fprintf_rbox(qh, qh->ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
qh_fprintf_rbox(qh, qh->ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
qh_errexit_rbox(qh, qh_ERRinput);
}
break;
case 'D':
dim= qh_strtol(s, &s);
if (dim < 1
|| dim > MAXdim) {
qh_fprintf_rbox(qh, qh->ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
qh_errexit_rbox(qh, qh_ERRinput);
}
break;
case 'G':
if (isdigit(*s))
gap= qh_strtod(s, &s);
else
gap= 0.5;
isgap= 1;
break;
case 'L':
if (isdigit(*s))
radius= qh_strtod(s, &s);
else
radius= 10;
islens= 1;
break;
case 'M':
ismesh= 1;
if (*s)
meshn= qh_strtod(s, &s);
if (*s == ',') {
++s;
meshm= qh_strtod(s, &s);
}else
meshm= 0.0;
if (*s == ',') {
++s;
meshr= qh_strtod(s, &s);
}else
meshr= sqrt(meshn*meshn + meshm*meshm);
if (*s && !isspace(*s)) {
qh_fprintf_rbox(qh, qh->ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
meshn= 3.0, meshm=4.0, meshr=5.0;
}
break;
case 'O':
qh->rbox_out_offset= qh_strtod(s, &s);
break;
case 'P':
if (!first_point)
first_point= s-1;
addpoints++;
while (*s && !isspace(*s)) /* read points later */
s++;
break;
case 'W':
width= qh_strtod(s, &s);
iswidth= 1;
break;
case 'Z':
if (isdigit(*s))
radius= qh_strtod(s, &s);
else
radius= 1.0;
isaxis= 1;
break;
default:
qh_fprintf_rbox(qh, qh->ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
qh_errexit_rbox(qh, qh_ERRinput);
}
if (*s && !isspace(*s)) {
qh_fprintf_rbox(qh, qh->ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
qh_errexit_rbox(qh, qh_ERRinput);
}
}
/* ============= defaults, constants, and sizes =============== */
if (qh->rbox_isinteger && !isbox)
box= qh_DEFAULTzbox;
if (addcube) {
cubesize= (int)floor(ldexp(1.0,dim)+0.5);
if (cube == 0.0)
cube= box;
}else
cubesize= 0;
if (adddiamond) {
diamondsize= 2*dim;
if (diamond == 0.0)
diamond= box;
}else
diamondsize= 0;
if (islens) {
if (isaxis) {
qh_fprintf_rbox(qh, qh->ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
if (radius <= 1.0) {
qh_fprintf_rbox(qh, qh->ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
radius);
qh_errexit_rbox(qh, qh_ERRinput);
}
lensangle= asin(1.0/radius);
lensbase= radius * cos(lensangle);
}
if (!numpoints) {
if (issimplex2)
; /* ok */
else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
qh_fprintf_rbox(qh, qh->ferr, 6192, "rbox error: missing count\n");
qh_errexit_rbox(qh, qh_ERRinput);
}else if (adddiamond + addcube + addpoints)
; /* ok */
else {
numpoints= 50; /* ./rbox D4 is the test case */
issphere= 1;
}
}
if ((issimplex + islens + isspiral + ismesh > 1)
|| (issimplex + issphere + isspiral + ismesh > 1)) {
qh_fprintf_rbox(qh, qh->ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
qh_fprintf_rbox(qh, qh->ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
qh_errexit_rbox(qh, qh_ERRinput);
}
if (coincidenttotal == 0)
coincidenttotal= numpoints;
/* ============= print header with total points =============== */
if (issimplex || ismesh)
totpoints= numpoints;
else if (issimplex2)
totpoints= numpoints+dim+1;
else if (isregular) {
totpoints= numpoints;
if (dim == 2) {
if (islens)
totpoints += numpoints - 2;
}else if (dim == 3) {
if (islens)
totpoints += 2 * numpoints;
else if (isgap)
totpoints += 1 + numpoints;
else
totpoints += 2;
}
}else
totpoints= numpoints + isaxis;
totpoints += cubesize + diamondsize + addpoints;
totpoints += coincidentpoints*coincidenttotal;
/* ============= seed randoms =============== */
if (istime == 0) {
for (s=command; *s; s++) {
if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
i= 'x';
else
i= *s;
seed= 11*seed + i;
}
}else if (israndom) {
seed= (int)time(&timedata);
sprintf(seedbuf, " t%d", seed); /* appends an extra t, not worth removing */
strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
t= strstr(command, " t ");
if (t)
strcpy(t+1, t+3); /* remove " t " */
} /* else, seed explicitly set to n */
qh_RANDOMseed_(qh, seed);
/* ============= print header =============== */
if (iscdd)
qh_fprintf_rbox(qh, qh->fout, 9391, "%s\nbegin\n %d %d %s\n",
NOcommand ? "" : command,
totpoints, dim+1,
qh->rbox_isinteger ? "integer" : "real");
else if (NOcommand)
qh_fprintf_rbox(qh, qh->fout, 9392, "%d\n%d\n", dim, totpoints);
else
/* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
qh_fprintf_rbox(qh, qh->fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
/* ============= explicit points =============== */
if ((s= first_point)) {
while (s && *s) { /* 'P' */
count= 0;
if (iscdd)
qh_out1(qh, 1.0);
while (*++s) {
qh_out1(qh, qh_strtod(s, &s));
count++;
if (isspace(*s) || !*s)
break;
if (*s != ',') {
qh_fprintf_rbox(qh, qh->ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
qh_errexit_rbox(qh, qh_ERRinput);
}
}
if (count < dim) {
for (k=dim-count; k--; )
qh_out1(qh, 0.0);
}else if (count > dim) {
qh_fprintf_rbox(qh, qh->ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
count, dim, s);
qh_errexit_rbox(qh, qh_ERRinput);
}
qh_fprintf_rbox(qh, qh->fout, 9394, "\n");
while ((s= strchr(s, 'P'))) {
if (isspace(s[-1]))
break;
}
}
}
/* ============= simplex distribution =============== */
if (issimplex+issimplex2) {
if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
qh_fprintf_rbox(qh, qh->ferr, 6196, "rbox error: insufficient memory for simplex\n");
qh_errexit_rbox(qh, qh_ERRmem); /* qh_ERRmem */
}
simplexp= simplex;
if (isregular) {
for (i=0; i<dim; i++) {
for (k=0; k<dim; k++)
*(simplexp++)= i==k ? 1.0 : 0.0;
}
for (k=0; k<dim; k++)
*(simplexp++)= -1.0;
}else {
for (i=0; i<dim+1; i++) {
for (k=0; k<dim; k++) {
randr= qh_RANDOMint;
*(simplexp++)= 2.0 * randr/randmax - 1.0;
}
}
}
if (issimplex2) {
simplexp= simplex;
for (i=0; i<dim+1; i++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k<dim; k++)
qh_out1(qh, *(simplexp++) * box);
qh_fprintf_rbox(qh, qh->fout, 9395, "\n");
}
}
for (j=0; j<numpoints; j++) {
if (iswidth)
apex= qh_RANDOMint % (dim+1);
else
apex= -1;
for (k=0; k<dim; k++)
coord[k]= 0.0;
norm= 0.0;
for (i=0; i<dim+1; i++) {
randr= qh_RANDOMint;
factor= randr/randmax;
if (i == apex)
factor *= width;
norm += factor;
for (k=0; k<dim; k++) {
simplexp= simplex + i*dim + k;
coord[k] += factor * (*simplexp);
}
}
for (k=0; k<dim; k++)
coord[k] *= box/norm;
qh_outcoord(qh, iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
}
isregular= 0; /* continue with isbox */
numpoints= 0;
}
/* ============= mesh distribution =============== */
if (ismesh) {
nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
for (k=dim; k--; )
mult[k]= 0;
for (i=0; i < numpoints; i++) {
coordp= coord;
for (k=0; k < dim; k++) {
if (k == 0)
*(coordp++)= mult[0] * meshn + mult[1] * (-meshm);
else if (k == 1)
*(coordp++)= mult[0] * meshm + mult[1] * meshn;
else
*(coordp++)= mult[k] * meshr;
}
qh_outcoord(qh, iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
for (k=0; k < dim; k++) {
if (++mult[k] < nthroot)
break;
mult[k]= 0;
}
}
}
/* ============= regular points for 's' =============== */
else if (isregular && !islens) {
if (dim != 2 && dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(qh, qh->ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
if (!isaxis || radius == 0.0) {
isaxis= 1;
radius= 1.0;
}
if (dim == 3) {
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, 0.0, 0.0, -box);
if (!isgap) {
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, 0.0, 0.0, box);
}
}
angle= 0.0;
anglediff= 2.0 * PI/numpoints;
for (i=0; i < numpoints; i++) {
angle += anglediff;
x= radius * cos(angle);
y= radius * sin(angle);
if (dim == 2) {
if (iscdd)
qh_out1(qh, 1.0);
qh_out2n(qh, x*box, y*box);
}else {
norm= sqrt(1.0 + x*x + y*y);
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
if (isgap) {
x *= 1-gap;
y *= 1-gap;
norm= sqrt(1.0 + x*x + y*y);
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
}
}
}
}
/* ============= regular points for 'r Ln D2' =============== */
else if (isregular && islens && dim == 2) {
double cos_0;
angle= lensangle;
anglediff= 2 * lensangle/(numpoints - 1);
cos_0= cos(lensangle);
for (i=0; i < numpoints; i++, angle -= anglediff) {
x= radius * sin(angle);
y= radius * (cos(angle) - cos_0);
if (iscdd)
qh_out1(qh, 1.0);
qh_out2n(qh, x*box, y*box);
if (i != 0 && i != numpoints - 1) {
if (iscdd)
qh_out1(qh, 1.0);
qh_out2n(qh, x*box, -y*box);
}
}
}
/* ============= regular points for 'r Ln D3' =============== */
else if (isregular && islens && dim != 2) {
if (dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(qh, qh->ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
angle= 0.0;
anglediff= 2* PI/numpoints;
if (!isgap) {
isgap= 1;
gap= 0.5;
}
offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
for (i=0; i < numpoints; i++, angle += anglediff) {
x= cos(angle);
y= sin(angle);
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, box*x, box*y, 0.0);
x *= 1-gap;
y *= 1-gap;
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, box*x, box*y, box * offset);
if (iscdd)
qh_out1(qh, 1.0);
qh_out3n(qh, box*x, box*y, -box * offset);
}
}
/* ============= apex of 'Zn' distribution + gendim =============== */
else {
if (isaxis) {
gendim= dim-1;
if (iscdd)
qh_out1(qh, 1.0);
for (j=0; j < gendim; j++)
qh_out1(qh, 0.0);
qh_out1(qh, -box);
qh_fprintf_rbox(qh, qh->fout, 9398, "\n");
}else if (islens)
gendim= dim-1;
else
gendim= dim;
/* ============= generate random point in unit cube =============== */
for (i=0; i < numpoints; i++) {
norm= 0.0;
for (j=0; j < gendim; j++) {
randr= qh_RANDOMint;
coord[j]= 2.0 * randr/randmax - 1.0;
norm += coord[j] * coord[j];
}
norm= sqrt(norm);
/* ============= dim-1 point of 'Zn' distribution ========== */
if (isaxis) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= radius * rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln s' distribution =========== */
}else if (islens && issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
randr= qh_RANDOMint;
rangap= 1.0 - gap * randr/randmax;
factor= rangap / norm;
for (j=0; j<gendim; j++)
coord[j]= factor * coord[j];
/* ============= dim-1 point of 'Ln' distribution ========== */
}else if (islens && !issphere) {
if (!isgap) {
isgap= 1;
gap= 1.0;
}
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * gap;
else
coord[j]= 1.0 - coord[j] * gap;
/* ============= point of 'l' distribution =============== */
}else if (isspiral) {
if (dim != 3) {
qh_free(simplex);
qh_fprintf_rbox(qh, qh->ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
qh_errexit_rbox(qh, qh_ERRinput);
}
coord[0]= cos(2*PI*i/(numpoints - 1));
coord[1]= sin(2*PI*i/(numpoints - 1));
coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
/* ============= point of 's' distribution =============== */
}else if (issphere) {
factor= 1.0/norm;
if (iswidth) {
randr= qh_RANDOMint;
factor *= 1.0 - width * randr/randmax;
}
for (j=0; j<dim; j++)
coord[j]= factor * coord[j];
}
/* ============= project 'Zn s' point in to sphere =============== */
if (isaxis && issphere) {
coord[dim-1]= 1.0;
norm= 1.0;
for (j=0; j<gendim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] / norm;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
/* ============= project 'Zn' point onto cube =============== */
}else if (isaxis && !issphere) { /* not very interesting */
randr= qh_RANDOMint;
coord[dim-1]= 2.0 * randr/randmax - 1.0;
/* ============= project 'Ln' point out to sphere =============== */
}else if (islens) {
coord[dim-1]= lensbase;
for (j=0, norm= 0; j<dim; j++)
norm += coord[j] * coord[j];
norm= sqrt(norm);
for (j=0; j<dim; j++)
coord[j]= coord[j] * radius/ norm;
coord[dim-1] -= lensbase;
if (iswidth) {
randr= qh_RANDOMint;
coord[dim-1] *= 1 - width * randr/randmax;
}
if (qh_RANDOMint > randmax/2)
coord[dim-1]= -coord[dim-1];
/* ============= project 'Wn' point toward boundary =============== */
}else if (iswidth && !issphere) {
j= qh_RANDOMint % gendim;
if (coord[j] < 0)
coord[j]= -1.0 - coord[j] * width;
else
coord[j]= 1.0 - coord[j] * width;
}
/* ============= scale point to box =============== */
for (k=0; k<dim; k++)
coord[k]= coord[k] * box;
/* ============= write output =============== */
qh_outcoord(qh, iscdd, coord, dim);
if(coincidentcount++ < coincidenttotal)
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
}
}
/* ============= write cube vertices =============== */
if (addcube) {
for (j=0; j<cubesize; j++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=dim-1; k>=0; k--) {
if (j & ( 1 << k))
qh_out1(qh, cube);
else
qh_out1(qh, -cube);
}
qh_fprintf_rbox(qh, qh->fout, 9400, "\n");
}
}
/* ============= write diamond vertices =============== */
if (adddiamond) {
for (j=0; j<diamondsize; j++) {
if (iscdd)
qh_out1(qh, 1.0);
for (k=dim-1; k>=0; k--) {
if (j/2 != k)
qh_out1(qh, 0.0);
else if (j & 0x1)
qh_out1(qh, diamond);
else
qh_out1(qh, -diamond);
}
qh_fprintf_rbox(qh, qh->fout, 9401, "\n");
}
}
if (iscdd)
qh_fprintf_rbox(qh, qh->fout, 9402, "end\nhull\n");
/* same code for error exit and normal return */
qh_free(simplex);
return qh_ERRnone;
} /* rboxpoints */
/*------------------------------------------------
outxxx - output functions for qh_rboxpoints
*/
int qh_roundi(qhT *qh, double a) {
if (a < 0.0) {
if (a - 0.5 < INT_MIN) {
qh_fprintf_rbox(qh, qh->ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
qh_errexit_rbox(qh, qh_ERRinput);
}
return (int)(a - 0.5);
}else {
if (a + 0.5 > INT_MAX) {
qh_fprintf_rbox(qh, qh->ferr, 6201, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a);
qh_errexit_rbox(qh, qh_ERRinput);
}
return (int)(a + 0.5);
}
} /* qh_roundi */
void qh_out1(qhT *qh, double a) {
if (qh->rbox_isinteger)
qh_fprintf_rbox(qh, qh->fout, 9403, "%d ", qh_roundi(qh, a+qh->rbox_out_offset));
else
qh_fprintf_rbox(qh, qh->fout, 9404, qh_REAL_1, a+qh->rbox_out_offset);
} /* qh_out1 */
void qh_out2n(qhT *qh, double a, double b) {
if (qh->rbox_isinteger)
qh_fprintf_rbox(qh, qh->fout, 9405, "%d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset));
else
qh_fprintf_rbox(qh, qh->fout, 9406, qh_REAL_2n, a+qh->rbox_out_offset, b+qh->rbox_out_offset);
} /* qh_out2n */
void qh_out3n(qhT *qh, double a, double b, double c) {
if (qh->rbox_isinteger)
qh_fprintf_rbox(qh, qh->fout, 9407, "%d %d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset), qh_roundi(qh, c+qh->rbox_out_offset));
else
qh_fprintf_rbox(qh, qh->fout, 9408, qh_REAL_3n, a+qh->rbox_out_offset, b+qh->rbox_out_offset, c+qh->rbox_out_offset);
} /* qh_out3n */
void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim) {
double *p= coord;
int k;
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k < dim; k++)
qh_out1(qh, *(p++));
qh_fprintf_rbox(qh, qh->fout, 9396, "\n");
} /* qh_outcoord */
void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
double *p;
double randr, delta;
int i,k;
double randmax= qh_RANDOMmax;
for (i= 0; i<coincidentpoints; i++) {
p= coord;
if (iscdd)
qh_out1(qh, 1.0);
for (k=0; k < dim; k++) {
randr= qh_RANDOMint;
delta= 2.0 * randr/randmax - 1.0; /* -1..+1 */
delta *= radius;
qh_out1(qh, *(p++) + delta);
}
qh_fprintf_rbox(qh, qh->fout, 9410, "\n");
}
} /* qh_outcoincident */
/*------------------------------------------------
Only called from qh_rboxpoints or qh_fprintf_rbox
qh_fprintf_rbox is only called from qh_rboxpoints
*/
void qh_errexit_rbox(qhT *qh, int exitcode)
{
longjmp(qh->rbox_errexit, exitcode);
} /* qh_errexit_rbox */

View File

@@ -0,0 +1,682 @@
/*<html><pre> -<a href="qh-stat_r.htm"
>-------------------------------</a><a name="TOP">-</a>
stat_r.c
contains all statistics that are collected for qhull
see qh-stat_r.htm and stat_r.h
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/stat_r.c#5 $$Change: 2062 $
$DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
*/
#include "qhull_ra.h"
/*========== functions in alphabetic order ================*/
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="allstatA">-</a>
qh_allstatA()
define statistics in groups of 20
notes:
(otherwise, 'gcc -O2' uses too much memory)
uses qhstat.next
*/
void qh_allstatA(qhT *qh) {
/* zdef_(type,name,doc,average) */
zzdef_(zdoc, Zdoc2, "precision statistics", -1);
zdef_(zinc, Znewvertex, NULL, -1);
zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet(!0s)", Znewvertex);
zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
qh->qhstat.precision= qh->qhstat.next; /* call qh_precision for each of these */
zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
}
void qh_allstatB(qhT *qh) {
zzdef_(zdoc, Zdoc1, "summary information", -1);
zdef_(zinc, Zvertices, "number of vertices in output", -1);
zdef_(zinc, Znumfacets, "number of facets in output", -1);
zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
zdef_(zinc, Znumridges, "number of ridges in output", -1);
zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
zzdef_(zinc, Zsetplane, "facets created altogether", -1);
zdef_(zinc, Ztotridges, "ridges created altogether", -1);
zdef_(zinc, Zpostfacets, "facets before post merge", -1);
zdef_(zadd, Znummergetot, "average merges per facet(at most 511)", Znumfacets);
zdef_(zmax, Znummergemax, " maximum merges for a facet(at most 511)", -1);
zdef_(zinc, Zangle, NULL, -1);
zdef_(wadd, Wangle, "average angle(cosine) of facet normals for all ridges", Zangle);
zdef_(wmax, Wanglemax, " maximum angle(cosine) of facet normals across a ridge", -1);
zdef_(wmin, Wanglemin, " minimum angle(cosine) of facet normals across a ridge", -1);
zdef_(wadd, Wareatot, "total area of facets", -1);
zdef_(wmax, Wareamax, " maximum facet area", -1);
zdef_(wmin, Wareamin, " minimum facet area", -1);
}
void qh_allstatC(qhT *qh) {
zdef_(zdoc, Zdoc9, "build hull statistics", -1);
zzdef_(zinc, Zprocessed, "points processed", -1);
zzdef_(zinc, Zretry, "retries due to precision problems", -1);
zdef_(wmax, Wretrymax, " max. random joggle", -1);
zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
zdef_(zinc, Zinsidevisible, " ave. visible facets without an horizon neighbor", Zprocessed);
zdef_(zadd, Zvisfacettot, " ave. facets deleted per iteration", Zprocessed);
zdef_(zmax, Zvisfacetmax, " maximum", -1);
zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
zdef_(zmax, Zvisvertexmax, " maximum", -1);
zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
zdef_(zadd, Znewfacettot, "ave. new or merged facets per iteration", Zprocessed);
zdef_(zmax, Znewfacetmax, " maximum(includes initial simplex)", -1);
zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
zdef_(wadd, Wnewbalance2, " standard deviation", -1);
zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
zdef_(wadd, Wpbalance2, " standard deviation", -1);
zdef_(zinc, Zpbalance, " number of trials", -1);
zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
zdef_(zinc, Zdetsimplex, "determinants computed(area & initial hull)", -1);
zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
zdef_(zinc, Znotmax, "points ignored(!above max_outside)", -1);
zdef_(zinc, Znotgood, "points ignored(!above a good facet)", -1);
zdef_(zinc, Znotgoodnew, "points ignored(didn't create a good new facet)", -1);
zdef_(zinc, Zgoodfacet, "good facets found", -1);
zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
zzdef_(zinc, Zcheckpart, " ave. distance tests per check", Ztotcheck);
}
void qh_allstatD(qhT *qh) {
zdef_(zinc, Zvisit, "resets of visit_id", -1);
zdef_(zinc, Zvvisit, " resets of vertex_visit", -1);
zdef_(zmax, Zvisit2max, " max visit_id/2", -1);
zdef_(zmax, Zvvisit2max, " max vertex_visit/2", -1);
zdef_(zdoc, Zdoc4, "partitioning statistics(see previous for outer planes)", -1);
zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
zdef_(zmax, Zdelvertexmax, " maximum vertices deleted per iteration", -1);
zdef_(zinc, Zfindbest, "calls to findbest", -1);
zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
zdef_(zinc, Zfindjump, " ave. clearly better", Zfindhorizon);
zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
zdef_(zinc, Zpartflip, " repartitioned coplanar points for flipped orientation", -1);
}
void qh_allstatE(qhT *qh) {
zdef_(zinc, Zpartinside, "inside points", -1);
zdef_(zinc, Zpartnear, " inside points kept with a facet", -1);
zdef_(zinc, Zcoplanarinside, " inside points that were coplanar with a facet", -1);
zdef_(zinc, Zbestlower, "calls to findbestlower", -1);
zdef_(zinc, Zbestlowerv, " with search of vertex neighbors", -1);
zdef_(zinc, Zbestlowerall, " with rare search of all facets", -1);
zdef_(zmax, Zbestloweralln, " facets per search of all facets", -1);
zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
zdef_(zinc, Ztotpartition, "partitions of a point", -1);
zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1);
zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1);
zdef_(zinc, Zdistgood, "distance tests for checking good point", -1);
zdef_(zinc, Zdistio, "distance tests for output", -1);
zdef_(zinc, Zdiststat, "distance tests for statistics", -1);
zdef_(zinc, Zdistplane, "total number of distance tests", -1);
zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
zzdef_(zinc, Zpartcoplanar, " distance tests for these partitions", -1);
zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
}
void qh_allstatE2(qhT *qh) {
zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
zdef_(zinc, Zhashridge, "total lookups of subridges(duplicates and boundary)", -1);
zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
}
void qh_allstatF(qhT *qh) {
zdef_(zdoc, Zdoc7, "statistics for merging", -1);
zdef_(zinc, Zpremergetot, "merge iterations", -1);
zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
zdef_(zadd, Zmergeinitmax, " maximum", -1);
zdef_(zadd, Zmergesettot, " ave. additional non-convex ridges per iteration", Zpremergetot);
zdef_(zadd, Zmergesetmax, " maximum additional in one pass", -1);
zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
zdef_(zadd, Zmergesettot2, " additional non-convex ridges", -1);
zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet(w/roundoff)", -1);
zdef_(wmin, Wminvertex, "max distance of merged vertex below facet(or roundoff)", -1);
zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
zzdef_(zadd, Zcyclefacettot, " ave. facets per cycle", Zcyclehorizon);
zdef_(zmax, Zcyclefacetmax, " max. facets", -1);
zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
zdef_(zinc, Zmergenew, "new facets merged", -1);
zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1);
}
void qh_allstatG(qhT *qh) {
zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
zdef_(wadd, Wacoplanartot, " average merge distance", Zacoplanar);
zdef_(wmax, Wacoplanarmax, " maximum merge distance", -1);
zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
zdef_(wadd, Wcoplanartot, " average merge distance", Zcoplanar);
zdef_(wmax, Wcoplanarmax, " maximum merge distance", -1);
zdef_(zinc, Zconcave, "merges due to concave facets", -1);
zdef_(wadd, Wconcavetot, " average merge distance", Zconcave);
zdef_(wmax, Wconcavemax, " maximum merge distance", -1);
zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
zdef_(wadd, Wavoidoldtot, " average merge distance", Zavoidold);
zdef_(wmax, Wavoidoldmax, " maximum merge distance", -1);
zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
zdef_(wadd, Wdegentot, " average merge distance", Zdegen);
zdef_(wmax, Wdegenmax, " maximum merge distance", -1);
zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
zdef_(wadd, Wflippedtot, " average merge distance", Zflipped);
zdef_(wmax, Wflippedmax, " maximum merge distance", -1);
zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
zdef_(wadd, Wduplicatetot, " average merge distance", Zduplicate);
zdef_(wmax, Wduplicatemax, " maximum merge distance", -1);
}
void qh_allstatH(qhT *qh) {
zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
zdef_(zinc, Zdupridge, " duplicate ridges detected", -1);
zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
zdef_(zinc, Zdelfacetdup, " facets deleted because of no neighbors", -1);
zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
zdef_(zinc, Zremvertexdel, " deleted", -1);
zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
zdef_(zadd, Zintersecttot, " ave. number found per vertex", Zintersect);
zdef_(zmax, Zintersectmax, " max. found for a vertex", -1);
zdef_(zinc, Zvertexridge, NULL, -1);
zdef_(zadd, Zvertexridgetot, " ave. number of ridges per tested vertex", Zvertexridge);
zdef_(zmax, Zvertexridgemax, " max. number of ridges per tested vertex", -1);
zdef_(zdoc, Zdoc10, "memory usage statistics(in bytes)", -1);
zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
zdef_(zadd, Zmempoints, "for input points, outside and coplanar sets, and qhT",-1);
zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
} /* allstat */
void qh_allstatI(qhT *qh) {
qh->qhstat.vridges= qh->qhstat.next;
zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
zzdef_(wadd, Wridge, " ave. distance to ridge", Zridge);
zzdef_(wmax, Wridgemax, " max. distance to ridge", -1);
zzdef_(zinc, Zridgemid, "bounded ridges", -1);
zzdef_(wadd, Wridgemid, " ave. distance of midpoint to ridge", Zridgemid);
zzdef_(wmax, Wridgemidmax, " max. distance of midpoint to ridge", -1);
zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
zzdef_(wadd, Wridgeok, " ave. angle to ridge", Zridgeok);
zzdef_(wmax, Wridgeokmax, " max. angle to ridge", -1);
zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0);
zzdef_(wmax, Wridge0max, " max. angle to ridge", -1);
zdef_(zdoc, Zdoc12, "Triangulation statistics(Qt)", -1);
zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
zdef_(zadd, Ztricoplanartot, " ave. new facets created(may be deleted)", Ztricoplanar);
zdef_(zmax, Ztricoplanarmax, " max. new facets created", -1);
zdef_(zinc, Ztrinull, "null new facets deleted(duplicated vertex)", -1);
zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted(same vertices)", -1);
zdef_(zinc, Ztridegen, "degenerate new facets in output(same ridge)", -1);
} /* allstat */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="allstatistics">-</a>
qh_allstatistics()
reset printed flag for all statistics
*/
void qh_allstatistics(qhT *qh) {
int i;
for(i=ZEND; i--; )
qh->qhstat.printed[i]= False;
} /* allstatistics */
#if qh_KEEPstatistics
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="collectstatistics">-</a>
qh_collectstatistics()
collect statistics for qh.facet_list
*/
void qh_collectstatistics(qhT *qh) {
facetT *facet, *neighbor, **neighborp;
vertexT *vertex, **vertexp;
realT dotproduct, dist;
int sizneighbors, sizridges, sizvertices, i;
qh->old_randomdist= qh->RANDOMdist;
qh->RANDOMdist= False;
zval_(Zmempoints)= qh->num_points * qh->normal_size + sizeof(qhT);
zval_(Zmemfacets)= 0;
zval_(Zmemridges)= 0;
zval_(Zmemvertices)= 0;
zval_(Zangle)= 0;
wval_(Wangle)= 0.0;
zval_(Znumridges)= 0;
zval_(Znumfacets)= 0;
zval_(Znumneighbors)= 0;
zval_(Znumvertices)= 0;
zval_(Znumvneighbors)= 0;
zval_(Znummergetot)= 0;
zval_(Znummergemax)= 0;
zval_(Zvertices)= qh->num_vertices - qh_setsize(qh, qh->del_vertices);
if (qh->MERGING || qh->APPROXhull || qh->JOGGLEmax < REALmax/2)
wmax_(Wmaxoutside, qh->max_outside);
if (qh->MERGING)
wmin_(Wminvertex, qh->min_vertex);
FORALLfacets
facet->seen= False;
if (qh->DELAUNAY) {
FORALLfacets {
if (facet->upperdelaunay != qh->UPPERdelaunay)
facet->seen= True; /* remove from angle statistics */
}
}
FORALLfacets {
if (facet->visible && qh->NEWfacets)
continue;
sizvertices= qh_setsize(qh, facet->vertices);
sizneighbors= qh_setsize(qh, facet->neighbors);
sizridges= qh_setsize(qh, facet->ridges);
zinc_(Znumfacets);
zadd_(Znumvertices, sizvertices);
zmax_(Zmaxvertices, sizvertices);
zadd_(Znumneighbors, sizneighbors);
zmax_(Zmaxneighbors, sizneighbors);
zadd_(Znummergetot, facet->nummerge);
i= facet->nummerge; /* avoid warnings */
zmax_(Znummergemax, i);
if (!facet->simplicial) {
if (sizvertices == qh->hull_dim) {
zinc_(Znowsimplicial);
}else {
zinc_(Znonsimplicial);
}
}
if (sizridges) {
zadd_(Znumridges, sizridges);
zmax_(Zmaxridges, sizridges);
}
zadd_(Zmemfacets, sizeof(facetT) + qh->normal_size + 2*sizeof(setT)
+ SETelemsize * (sizneighbors + sizvertices));
if (facet->ridges) {
zadd_(Zmemridges,
sizeof(setT) + SETelemsize * sizridges + sizridges *
(sizeof(ridgeT) + sizeof(setT) + SETelemsize * (qh->hull_dim-1))/2);
}
if (facet->outsideset)
zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(qh, facet->outsideset));
if (facet->coplanarset)
zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(qh, facet->coplanarset));
if (facet->seen) /* Delaunay upper envelope */
continue;
facet->seen= True;
FOREACHneighbor_(facet) {
if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
|| neighbor->seen || !facet->normal || !neighbor->normal)
continue;
dotproduct= qh_getangle(qh, facet->normal, neighbor->normal);
zinc_(Zangle);
wadd_(Wangle, dotproduct);
wmax_(Wanglemax, dotproduct)
wmin_(Wanglemin, dotproduct)
}
if (facet->normal) {
FOREACHvertex_(facet->vertices) {
zinc_(Zdiststat);
qh_distplane(qh, vertex->point, facet, &dist);
wmax_(Wvertexmax, dist);
wmin_(Wvertexmin, dist);
}
}
}
FORALLvertices {
if (vertex->deleted)
continue;
zadd_(Zmemvertices, sizeof(vertexT));
if (vertex->neighbors) {
sizneighbors= qh_setsize(qh, vertex->neighbors);
zadd_(Znumvneighbors, sizneighbors);
zmax_(Zmaxvneighbors, sizneighbors);
zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors);
}
}
qh->RANDOMdist= qh->old_randomdist;
} /* collectstatistics */
#endif /* qh_KEEPstatistics */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="initstatistics">-</a>
qh_initstatistics(qh)
initialize statistics
notes:
NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
On first call, only qhmem.ferr is defined. qh_memalloc is not setup.
Also invoked by QhullQh().
*/
void qh_initstatistics(qhT *qh) {
int i;
realT realx;
int intx;
qh->qhstat.next= 0;
qh_allstatA(qh);
qh_allstatB(qh);
qh_allstatC(qh);
qh_allstatD(qh);
qh_allstatE(qh);
qh_allstatE2(qh);
qh_allstatF(qh);
qh_allstatG(qh);
qh_allstatH(qh);
qh_allstatI(qh);
if (qh->qhstat.next > (int)sizeof(qh->qhstat.id)) {
qh_fprintf(qh, qh->qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
qhstat.next %d should be <= sizeof(qh->qhstat.id) %d\n", qh->qhstat.next, (int)sizeof(qh->qhstat.id));
#if 0 /* for locating error, Znumridges should be duplicated */
for(i=0; i < ZEND; i++) {
int j;
for(j=i+1; j < ZEND; j++) {
if (qh->qhstat.id[i] == qh->qhstat.id[j]) {
qh_fprintf(qh, qh->qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
qh->qhstat.id[i], i, j);
}
}
}
#endif
qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
}
qh->qhstat.init[zinc].i= 0;
qh->qhstat.init[zadd].i= 0;
qh->qhstat.init[zmin].i= INT_MAX;
qh->qhstat.init[zmax].i= INT_MIN;
qh->qhstat.init[wadd].r= 0;
qh->qhstat.init[wmin].r= REALmax;
qh->qhstat.init[wmax].r= -REALmax;
for(i=0; i < ZEND; i++) {
if (qh->qhstat.type[i] > ZTYPEreal) {
realx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r;
qh->qhstat.stats[i].r= realx;
}else if (qh->qhstat.type[i] != zdoc) {
intx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i;
qh->qhstat.stats[i].i= intx;
}
}
} /* initstatistics */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="newstats">-</a>
qh_newstats(qh, )
returns True if statistics for zdoc
returns:
next zdoc
*/
boolT qh_newstats(qhT *qh, int idx, int *nextindex) {
boolT isnew= False;
int start, i;
if (qh->qhstat.type[qh->qhstat.id[idx]] == zdoc)
start= idx+1;
else
start= idx;
for(i= start; i < qh->qhstat.next && qh->qhstat.type[qh->qhstat.id[i]] != zdoc; i++) {
if (!qh_nostatistic(qh, qh->qhstat.id[i]) && !qh->qhstat.printed[qh->qhstat.id[i]])
isnew= True;
}
*nextindex= i;
return isnew;
} /* newstats */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="nostatistic">-</a>
qh_nostatistic(qh, index )
true if no statistic to print
*/
boolT qh_nostatistic(qhT *qh, int i) {
if ((qh->qhstat.type[i] > ZTYPEreal
&&qh->qhstat.stats[i].r == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r)
|| (qh->qhstat.type[i] < ZTYPEreal
&&qh->qhstat.stats[i].i == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i))
return True;
return False;
} /* nostatistic */
#if qh_KEEPstatistics
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printallstatistics">-</a>
qh_printallstatistics(qh, fp, string )
print all statistics with header 'string'
*/
void qh_printallstatistics(qhT *qh, FILE *fp, const char *string) {
qh_allstatistics(qh);
qh_collectstatistics(qh);
qh_printstatistics(qh, fp, string);
qh_memstatistics(qh, fp);
}
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstatistics">-</a>
qh_printstatistics(qh, fp, string )
print statistics to a file with header 'string'
skips statistics with qhstat.printed[] (reset with qh_allstatistics)
see:
qh_printallstatistics()
*/
void qh_printstatistics(qhT *qh, FILE *fp, const char *string) {
int i, k;
realT ave;
if (qh->num_points != qh->num_vertices) {
wval_(Wpbalance)= 0;
wval_(Wpbalance2)= 0;
}else
wval_(Wpbalance2)= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
wval_(Wpbalance2), &ave);
wval_(Wnewbalance2)= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
wval_(Wnewbalance2), &ave);
qh_fprintf(qh, fp, 9350, "\n\
%s\n\
qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh->rbox_command,
qh->qhull_command, qh_version, qh->qhull_options);
qh_fprintf(qh, fp, 9351, "\nprecision constants:\n\
%6.2g max. abs. coordinate in the (transformed) input('Qbd:n')\n\
%6.2g max. roundoff error for distance computation('En')\n\
%6.2g max. roundoff error for angle computations\n\
%6.2g min. distance for outside points ('Wn')\n\
%6.2g min. distance for visible facets ('Vn')\n\
%6.2g max. distance for coplanar facets ('Un')\n\
%6.2g max. facet width for recomputing centrum and area\n\
",
qh->MAXabs_coord, qh->DISTround, qh->ANGLEround, qh->MINoutside,
qh->MINvisible, qh->MAXcoplanar, qh->WIDEfacet);
if (qh->KEEPnearinside)
qh_fprintf(qh, fp, 9352, "\
%6.2g max. distance for near-inside points\n", qh->NEARinside);
if (qh->premerge_cos < REALmax/2) qh_fprintf(qh, fp, 9353, "\
%6.2g max. cosine for pre-merge angle\n", qh->premerge_cos);
if (qh->PREmerge) qh_fprintf(qh, fp, 9354, "\
%6.2g radius of pre-merge centrum\n", qh->premerge_centrum);
if (qh->postmerge_cos < REALmax/2) qh_fprintf(qh, fp, 9355, "\
%6.2g max. cosine for post-merge angle\n", qh->postmerge_cos);
if (qh->POSTmerge) qh_fprintf(qh, fp, 9356, "\
%6.2g radius of post-merge centrum\n", qh->postmerge_centrum);
qh_fprintf(qh, fp, 9357, "\
%6.2g max. distance for merging two simplicial facets\n\
%6.2g max. roundoff error for arithmetic operations\n\
%6.2g min. denominator for divisions\n\
zero diagonal for Gauss: ", qh->ONEmerge, REALepsilon, qh->MINdenom);
for(k=0; k < qh->hull_dim; k++)
qh_fprintf(qh, fp, 9358, "%6.2e ", qh->NEARzero[k]);
qh_fprintf(qh, fp, 9359, "\n\n");
for(i=0 ; i < qh->qhstat.next; )
qh_printstats(qh, fp, i, &i);
} /* printstatistics */
#endif /* qh_KEEPstatistics */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstatlevel">-</a>
qh_printstatlevel(qh, fp, id )
print level information for a statistic
notes:
nop if id >= ZEND, printed, or same as initial value
*/
void qh_printstatlevel(qhT *qh, FILE *fp, int id) {
#define NULLfield " "
if (id >= ZEND || qh->qhstat.printed[id])
return;
if (qh->qhstat.type[id] == zdoc) {
qh_fprintf(qh, fp, 9360, "%s\n", qh->qhstat.doc[id]);
return;
}
if (qh_nostatistic(qh, id) || !qh->qhstat.doc[id])
return;
qh->qhstat.printed[id]= True;
if (qh->qhstat.count[id] != -1
&& qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i == 0)
qh_fprintf(qh, fp, 9361, " *0 cnt*");
else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] == -1)
qh_fprintf(qh, fp, 9362, "%7.2g", qh->qhstat.stats[id].r);
else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] != -1)
qh_fprintf(qh, fp, 9363, "%7.2g", qh->qhstat.stats[id].r/ qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] == -1)
qh_fprintf(qh, fp, 9364, "%7d", qh->qhstat.stats[id].i);
else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] != -1)
qh_fprintf(qh, fp, 9365, "%7.3g", (realT) qh->qhstat.stats[id].i / qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
qh_fprintf(qh, fp, 9366, " %s\n", qh->qhstat.doc[id]);
} /* printstatlevel */
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="printstats">-</a>
qh_printstats(qh, fp, index, nextindex )
print statistics for a zdoc group
returns:
next zdoc if non-null
*/
void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex) {
int j, nexti;
if (qh_newstats(qh, idx, &nexti)) {
qh_fprintf(qh, fp, 9367, "\n");
for (j=idx; j<nexti; j++)
qh_printstatlevel(qh, fp, qh->qhstat.id[j]);
}
if (nextindex)
*nextindex= nexti;
} /* printstats */
#if qh_KEEPstatistics
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="stddev">-</a>
qh_stddev(num, tot, tot2, ave )
compute the standard deviation and average from statistics
tot2 is the sum of the squares
notes:
computes r.m.s.:
(x-ave)^2
== x^2 - 2x tot/num + (tot/num)^2
== tot2 - 2 tot tot/num + tot tot/num
== tot2 - tot ave
*/
realT qh_stddev(int num, realT tot, realT tot2, realT *ave) {
realT stddev;
*ave= tot/num;
stddev= sqrt(tot2/num - *ave * *ave);
return stddev;
} /* stddev */
#endif /* qh_KEEPstatistics */
#if !qh_KEEPstatistics
void qh_collectstatistics(qhT *qh) {}
void qh_printallstatistics(qhT *qh, FILE *fp, char *string) {};
void qh_printstatistics(qhT *qh, FILE *fp, char *string) {}
#endif

View File

@@ -0,0 +1,533 @@
/*<html><pre> -<a href="qh-stat_r.htm"
>-------------------------------</a><a name="TOP">-</a>
stat_r.h
contains all statistics that are collected for qhull
see qh-stat_r.htm and stat_r.c
Copyright (c) 1993-2015 The Geometry Center.
$Id: //main/2015/qhull/src/libqhull_r/stat_r.h#5 $$Change: 2079 $
$DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
recompile qhull if you change this file
Integer statistics are Z* while real statistics are W*.
define MAYdebugx to call a routine at every statistic event
*/
#ifndef qhDEFstat
#define qhDEFstat 1
/* Depends on realT. Do not include libqhull_r to avoid circular dependency */
#ifndef DEFqhT
#define DEFqhT 1
typedef struct qhT qhT; /* Defined by libqhull_r.h */
#endif
#ifndef DEFqhstatT
#define DEFqhstatT 1
typedef struct qhstatT qhstatT; /* Defined here */
#endif
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
*/
#ifndef qh_KEEPstatistics
#define qh_KEEPstatistics 1
#endif
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="statistics">-</a>
Zxxx for integers, Wxxx for reals
notes:
be sure that all statistics are defined in stat_r.c
otherwise initialization may core dump
can pick up all statistics by:
grep '[zw].*_[(][ZW]' *.c >z.x
remove trailers with query">-</a>
remove leaders with query-replace-regexp [ ^I]+ (
*/
#if qh_KEEPstatistics
enum qh_statistics { /* alphabetical after Z/W */
Zacoplanar,
Wacoplanarmax,
Wacoplanartot,
Zangle,
Wangle,
Wanglemax,
Wanglemin,
Zangletests,
Wareatot,
Wareamax,
Wareamin,
Zavoidold,
Wavoidoldmax,
Wavoidoldtot,
Zback0,
Zbestcentrum,
Zbestdist,
Zbestlower,
Zbestlowerall,
Zbestloweralln,
Zbestlowerv,
Zcentrumtests,
Zcheckpart,
Zcomputefurthest,
Zconcave,
Wconcavemax,
Wconcavetot,
Zconcaveridges,
Zconcaveridge,
Zcoplanar,
Wcoplanarmax,
Wcoplanartot,
Zcoplanarangle,
Zcoplanarcentrum,
Zcoplanarhorizon,
Zcoplanarinside,
Zcoplanarpart,
Zcoplanarridges,
Wcpu,
Zcyclefacetmax,
Zcyclefacettot,
Zcyclehorizon,
Zcyclevertex,
Zdegen,
Wdegenmax,
Wdegentot,
Zdegenvertex,
Zdelfacetdup,
Zdelridge,
Zdelvertextot,
Zdelvertexmax,
Zdetsimplex,
Zdistcheck,
Zdistconvex,
Zdistgood,
Zdistio,
Zdistplane,
Zdiststat,
Zdistvertex,
Zdistzero,
Zdoc1,
Zdoc2,
Zdoc3,
Zdoc4,
Zdoc5,
Zdoc6,
Zdoc7,
Zdoc8,
Zdoc9,
Zdoc10,
Zdoc11,
Zdoc12,
Zdropdegen,
Zdropneighbor,
Zdupflip,
Zduplicate,
Wduplicatemax,
Wduplicatetot,
Zdupridge,
Zdupsame,
Zflipped,
Wflippedmax,
Wflippedtot,
Zflippedfacets,
Zfindbest,
Zfindbestmax,
Zfindbesttot,
Zfindcoplanar,
Zfindfail,
Zfindhorizon,
Zfindhorizonmax,
Zfindhorizontot,
Zfindjump,
Zfindnew,
Zfindnewmax,
Zfindnewtot,
Zfindnewjump,
Zfindnewsharp,
Zgauss0,
Zgoodfacet,
Zhashlookup,
Zhashridge,
Zhashridgetest,
Zhashtests,
Zinsidevisible,
Zintersect,
Zintersectfail,
Zintersectmax,
Zintersectnum,
Zintersecttot,
Zmaxneighbors,
Wmaxout,
Wmaxoutside,
Zmaxridges,
Zmaxvertex,
Zmaxvertices,
Zmaxvneighbors,
Zmemfacets,
Zmempoints,
Zmemridges,
Zmemvertices,
Zmergeflipdup,
Zmergehorizon,
Zmergeinittot,
Zmergeinitmax,
Zmergeinittot2,
Zmergeintohorizon,
Zmergenew,
Zmergesettot,
Zmergesetmax,
Zmergesettot2,
Zmergesimplex,
Zmergevertex,
Wmindenom,
Wminvertex,
Zminnorm,
Zmultiridge,
Znearlysingular,
Zneighbor,
Wnewbalance,
Wnewbalance2,
Znewfacettot,
Znewfacetmax,
Znewvertex,
Wnewvertex,
Wnewvertexmax,
Znoarea,
Znonsimplicial,
Znowsimplicial,
Znotgood,
Znotgoodnew,
Znotmax,
Znumfacets,
Znummergemax,
Znummergetot,
Znumneighbors,
Znumridges,
Znumvertices,
Znumvisibility,
Znumvneighbors,
Zonehorizon,
Zpartangle,
Zpartcoplanar,
Zpartflip,
Zparthorizon,
Zpartinside,
Zpartition,
Zpartitionall,
Zpartnear,
Zpbalance,
Wpbalance,
Wpbalance2,
Zpostfacets,
Zpremergetot,
Zprocessed,
Zremvertex,
Zremvertexdel,
Zrenameall,
Zrenamepinch,
Zrenameshare,
Zretry,
Wretrymax,
Zridge,
Wridge,
Wridgemax,
Zridge0,
Wridge0,
Wridge0max,
Zridgemid,
Wridgemid,
Wridgemidmax,
Zridgeok,
Wridgeok,
Wridgeokmax,
Zsearchpoints,
Zsetplane,
Ztestvneighbor,
Ztotcheck,
Ztothorizon,
Ztotmerge,
Ztotpartcoplanar,
Ztotpartition,
Ztotridges,
Ztotvertices,
Ztotvisible,
Ztricoplanar,
Ztricoplanarmax,
Ztricoplanartot,
Ztridegen,
Ztrimirror,
Ztrinull,
Wvertexmax,
Wvertexmin,
Zvertexridge,
Zvertexridgetot,
Zvertexridgemax,
Zvertices,
Zvisfacettot,
Zvisfacetmax,
Zvisit,
Zvisit2max,
Zvisvertextot,
Zvisvertexmax,
Zvvisit,
Zvvisit2max,
Zwidefacet,
Zwidevertices,
ZEND};
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="ZZstat">-</a>
Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
notes:
be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
*/
#else
enum qh_statistics { /* for zzdef etc. macros */
Zback0,
Zbestdist,
Zcentrumtests,
Zcheckpart,
Zconcaveridges,
Zcoplanarhorizon,
Zcoplanarpart,
Zcoplanarridges,
Zcyclefacettot,
Zcyclehorizon,
Zdelvertextot,
Zdistcheck,
Zdistconvex,
Zdistzero,
Zdoc1,
Zdoc2,
Zdoc3,
Zdoc11,
Zflippedfacets,
Zgauss0,
Zminnorm,
Zmultiridge,
Znearlysingular,
Wnewvertexmax,
Znumvisibility,
Zpartcoplanar,
Zpartition,
Zpartitionall,
Zprocessed,
Zretry,
Zridge,
Wridge,
Wridgemax,
Zridge0,
Wridge0,
Wridge0max,
Zridgemid,
Wridgemid,
Wridgemidmax,
Zridgeok,
Wridgeok,
Wridgeokmax,
Zsetplane,
Ztotcheck,
Ztotmerge,
ZEND};
#endif
/*-<a href="qh-stat_r.htm#TOC"
>-------------------------------</a><a name="ztype">-</a>
ztype
the type of a statistic sets its initial value.
notes:
The type should be the same as the macro for collecting the statistic
*/
enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
/*========== macros and constants =============*/
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="MAYdebugx">-</a>
MAYdebugx
define as maydebug() to be called frequently for error trapping
*/
#define MAYdebugx
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zdef_">-</a>
zzdef_, zdef_( type, name, doc, -1)
define a statistic (assumes 'qhstat.next= 0;')
zdef_( type, name, doc, count)
define an averaged statistic
printed as name/count
*/
#define zzdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
#if qh_KEEPstatistics
#define zdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
#else
#define zdef_(type,name,doc,count)
#endif
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zinc_">-</a>
zzinc_( name ), zinc_( name)
increment an integer statistic
*/
#define zzinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
#if qh_KEEPstatistics
#define zinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
#else
#define zinc_(id) {}
#endif
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zadd_">-</a>
zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
add value to an integer or real statistic
*/
#define zzadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
#define wwadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
#if qh_KEEPstatistics
#define zadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
#define wadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
#else
#define zadd_(id, val) {}
#define wadd_(id, val) {}
#endif
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zval_">-</a>
zzval_( name ), zval_( name ), wwval_( name )
set or return value of a statistic
*/
#define zzval_(id) ((qh->qhstat.stats[id]).i)
#define wwval_(id) ((qh->qhstat.stats[id]).r)
#if qh_KEEPstatistics
#define zval_(id) ((qh->qhstat.stats[id]).i)
#define wval_(id) ((qh->qhstat.stats[id]).r)
#else
#define zval_(id) qh->qhstat.tempi
#define wval_(id) qh->qhstat.tempr
#endif
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zmax_">-</a>
zmax_( id, val ), wmax_( id, value )
maximize id with val
*/
#define wwmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
#if qh_KEEPstatistics
#define zmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].i,(val));}
#define wmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
#else
#define zmax_(id, val) {}
#define wmax_(id, val) {}
#endif
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="zmin_">-</a>
zmin_( id, val ), wmin_( id, value )
minimize id with val
*/
#if qh_KEEPstatistics
#define zmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].i,(val));}
#define wmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].r,(val));}
#else
#define zmin_(id, val) {}
#define wmin_(id, val) {}
#endif
/*================== stat_r.h types ==============*/
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="intrealT">-</a>
intrealT
union of integer and real, used for statistics
*/
typedef union intrealT intrealT; /* union of int and realT */
union intrealT {
int i;
realT r;
};
/*-<a href="qh-stat_r.htm#TOC"
>--------------------------------</a><a name="qhstat">-</a>
qhstat
Data structure for statistics, similar to qh and qhrbox
Allocated as part of qhT (libqhull_r.h)
*/
struct qhstatT {
intrealT stats[ZEND]; /* integer and real statistics */
unsigned char id[ZEND+10]; /* id's in print order */
const char *doc[ZEND]; /* array of documentation strings */
short int count[ZEND]; /* -1 if none, else index of count to use */
char type[ZEND]; /* type, see ztypes above */
char printed[ZEND]; /* true, if statistic has been printed */
intrealT init[ZTYPEend]; /* initial values by types, set initstatistics */
int next; /* next index for zdef_ */
int precision; /* index for precision problems */
int vridges; /* index for Voronoi ridges */
int tempi;
realT tempr;
};
/*========== function prototypes ===========*/
#ifdef __cplusplus
extern "C" {
#endif
void qh_allstatA(qhT *qh);
void qh_allstatB(qhT *qh);
void qh_allstatC(qhT *qh);
void qh_allstatD(qhT *qh);
void qh_allstatE(qhT *qh);
void qh_allstatE2(qhT *qh);
void qh_allstatF(qhT *qh);
void qh_allstatG(qhT *qh);
void qh_allstatH(qhT *qh);
void qh_allstatI(qhT *qh);
void qh_allstatistics(qhT *qh);
void qh_collectstatistics(qhT *qh);
void qh_initstatistics(qhT *qh);
boolT qh_newstats(qhT *qh, int idx, int *nextindex);
boolT qh_nostatistic(qhT *qh, int i);
void qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
void qh_printstatistics(qhT *qh, FILE *fp, const char *string);
void qh_printstatlevel(qhT *qh, FILE *fp, int id);
void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex);
realT qh_stddev(int num, realT tot, realT tot2, realT *ave);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* qhDEFstat */

View File

@@ -0,0 +1,527 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
user.c
user redefinable functions
see user2_r.c for qh_fprintf, qh_malloc, qh_free
see README.txt see COPYING.txt for copyright information.
see libqhull_r.h for data structures, macros, and user-callable functions.
see user_eg.c, user_eg2.c, and unix.c for examples.
see user.h for user-definable constants
use qh_NOmem in mem_r.h to turn off memory management
use qh_NOmerge in user.h to turn off facet merging
set qh_KEEPstatistics in user.h to 0 to turn off statistics
This is unsupported software. You're welcome to make changes,
but you're on your own if something goes wrong. Use 'Tc' to
check frequently. Usually qhull will report an error if
a data structure becomes inconsistent. If so, it also reports
the last point added to the hull, e.g., 102. You can then trace
the execution of qhull with "T4P102".
Please report any errors that you fix to qhull@qhull.org
Qhull-template is a template for calling qhull from within your application
if you recompile and load this module, then user.o will not be loaded
from qhull.a
you can add additional quick allocation sizes in qh_user_memsizes
if the other functions here are redefined to not use qh_print...,
then io.o will not be loaded from qhull.a. See user_eg_r.c for an
example. We recommend keeping io.o for the extra debugging
information it supplies.
*/
#include "qhull_ra.h"
#include <stdarg.h>
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qhull_template">-</a>
Qhull-template
Template for calling qhull from inside your program
returns:
exit code(see qh_ERR... in libqhull_r.h)
all memory freed
notes:
This can be called any number of times.
*/
#if 0
{
int dim; /* dimension of points */
int numpoints; /* number of points */
coordT *points; /* array of coordinates for each point */
boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
FILE *outfile= stdout; /* output from qh_produce_output(qh)
use NULL to skip qh_produce_output(qh) */
FILE *errfile= stderr; /* error messages from qhull code */
int exitcode; /* 0 if no error from qhull */
facetT *facet; /* set by FORALLfacets */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
qhT qh_qh; /* Qhull's data structure. First argument of most calls */
qhT *qh= &qh_qh; /* Alternatively -- qhT *qh= (qhT*)malloc(sizeof(qhT)) */
QHULL_LIB_CHECK /* Check for compatible library */
qh_zero(qh, errfile);
/* initialize dim, numpoints, points[], ismalloc here */
exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
flags, outfile, errfile);
if (!exitcode) { /* if no error */
/* 'qh->facet_list' contains the convex hull */
FORALLfacets {
/* ... your code ... */
}
}
qh_freeqhull(qh, !qh_ALL);
qh_memfreeshort(qh, &curlong, &totlong);
if (curlong || totlong)
qh_fprintf(qh, errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
}
#endif
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="new_qhull">-</a>
qh_new_qhull(qh, dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
Run qhull and return results in qh.
Returns exitcode (0 if no errors).
Before first call, either call qh_zero(qh, errfile), or set qh to all zero.
notes:
do not modify points until finished with results.
The qhull data structure contains pointers into the points array.
do not call qhull functions before qh_new_qhull().
The qhull data structure is not initialized until qh_new_qhull().
do not call qh_init_A (global_r.c)
Default errfile is stderr, outfile may be null
qhull_cmd must start with "qhull "
projects points to a new point array for Delaunay triangulations ('d' and 'v')
transforms points into a new point array for halfspace intersection ('H')
see:
Qhull-template at the beginning of this file.
An example of using qh_new_qhull is user_eg_r.c
*/
int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
char *qhull_cmd, FILE *outfile, FILE *errfile) {
/* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
These parameters are not referenced after a longjmp() and hence not clobbered.
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
int exitcode, hulldim;
boolT new_ismalloc;
coordT *new_points;
if(!errfile){
errfile= stderr;
}
if (!qh->qhmem.ferr) {
qh_meminit(qh, errfile);
} else {
qh_memcheck(qh);
}
if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
qh_fprintf(qh, errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
return qh_ERRinput;
}
qh_initqhull_start(qh, NULL, outfile, errfile);
trace1((qh, qh->ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
exitcode = setjmp(qh->errexit);
if (!exitcode)
{
qh->NOerrexit = False;
qh_initflags(qh, qhull_cmd);
if (qh->DELAUNAY)
qh->PROJECTdelaunay= True;
if (qh->HALFspace) {
/* points is an array of halfspaces,
the last coordinate of each halfspace is its offset */
hulldim= dim-1;
qh_setfeasible(qh, hulldim);
new_points= qh_sethalfspace_all(qh, dim, numpoints, points, qh->feasible_point);
new_ismalloc= True;
if (ismalloc)
qh_free(points);
}else {
hulldim= dim;
new_points= points;
new_ismalloc= ismalloc;
}
qh_init_B(qh, new_points, numpoints, hulldim, new_ismalloc);
qh_qhull(qh);
qh_check_output(qh);
if (outfile) {
qh_produce_output(qh);
}else {
qh_prepare_output(qh);
}
if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
qh_check_points(qh);
}
qh->NOerrexit = True;
return exitcode;
} /* new_qhull */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="errexit">-</a>
qh_errexit(qh, exitcode, facet, ridge )
report and exit from an error
report facet and ridge if non-NULL
reports useful information such as last point processed
set qh.FORCEoutput to print neighborhood of facet
see:
qh_errexit2() in libqhull_r.c for printing 2 facets
design:
check for error within error processing
compute qh.hulltime
print facet and ridge (if any)
report commandString, options, qh.furthest_id
print summary and statistics (including precision statistics)
if qh_ERRsingular
print help text for singular data set
exit program via long jump (if defined) or exit()
*/
void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
if (qh->ERREXITcalled) {
qh_fprintf(qh, qh->ferr, 8126, "\nqhull error while processing previous error. Exit program\n");
qh_exit(qh_ERRqhull);
}
qh->ERREXITcalled= True;
if (!qh->QHULLfinished)
qh->hulltime= qh_CPUclock - qh->hulltime;
qh_errprint(qh, "ERRONEOUS", facet, NULL, ridge, NULL);
qh_fprintf(qh, qh->ferr, 8127, "\nWhile executing: %s | %s\n", qh->rbox_command, qh->qhull_command);
qh_fprintf(qh, qh->ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
if (qh->furthest_id >= 0) {
qh_fprintf(qh, qh->ferr, 8129, "Last point added to hull was p%d.", qh->furthest_id);
if (zzval_(Ztotmerge))
qh_fprintf(qh, qh->ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge));
if (qh->QHULLfinished)
qh_fprintf(qh, qh->ferr, 8131, "\nQhull has finished constructing the hull.");
else if (qh->POSTmerging)
qh_fprintf(qh, qh->ferr, 8132, "\nQhull has started post-merging.");
qh_fprintf(qh, qh->ferr, 8133, "\n");
}
if (qh->FORCEoutput && (qh->QHULLfinished || (!facet && !ridge)))
qh_produce_output(qh);
else if (exitcode != qh_ERRinput) {
if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh->hull_dim+1) {
qh_fprintf(qh, qh->ferr, 8134, "\nAt error exit:\n");
qh_printsummary(qh, qh->ferr);
if (qh->PRINTstatistics) {
qh_collectstatistics(qh);
qh_printstatistics(qh, qh->ferr, "at error exit");
qh_memstatistics(qh, qh->ferr);
}
}
if (qh->PRINTprecision)
qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
}
if (!exitcode)
exitcode= qh_ERRqhull;
else if (exitcode == qh_ERRsingular)
qh_printhelp_singular(qh, qh->ferr);
else if (exitcode == qh_ERRprec && !qh->PREmerge)
qh_printhelp_degenerate(qh, qh->ferr);
if (qh->NOerrexit) {
qh_fprintf(qh, qh->ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
qh_exit(qh_ERRqhull);
}
qh->ERREXITcalled= False;
qh->NOerrexit= True;
qh->ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
longjmp(qh->errexit, exitcode);
} /* errexit */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="errprint">-</a>
qh_errprint(qh, fp, string, atfacet, otherfacet, atridge, atvertex )
prints out the information of facets and ridges to fp
also prints neighbors and geomview output
notes:
except for string, any parameter may be NULL
*/
void qh_errprint(qhT *qh, const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
int i;
if (atfacet) {
qh_fprintf(qh, qh->ferr, 8135, "%s FACET:\n", string);
qh_printfacet(qh, qh->ferr, atfacet);
}
if (otherfacet) {
qh_fprintf(qh, qh->ferr, 8136, "%s OTHER FACET:\n", string);
qh_printfacet(qh, qh->ferr, otherfacet);
}
if (atridge) {
qh_fprintf(qh, qh->ferr, 8137, "%s RIDGE:\n", string);
qh_printridge(qh, qh->ferr, atridge);
if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
qh_printfacet(qh, qh->ferr, atridge->top);
if (atridge->bottom
&& atridge->bottom != atfacet && atridge->bottom != otherfacet)
qh_printfacet(qh, qh->ferr, atridge->bottom);
if (!atfacet)
atfacet= atridge->top;
if (!otherfacet)
otherfacet= otherfacet_(atridge, atfacet);
}
if (atvertex) {
qh_fprintf(qh, qh->ferr, 8138, "%s VERTEX:\n", string);
qh_printvertex(qh, qh->ferr, atvertex);
}
if (qh->fout && qh->FORCEoutput && atfacet && !qh->QHULLfinished && !qh->IStracing) {
qh_fprintf(qh, qh->ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
for (i=0; i < qh_PRINTEND; i++) /* use fout for geomview output */
qh_printneighborhood(qh, qh->fout, qh->PRINTout[i], atfacet, otherfacet,
!qh_ALL);
}
} /* errprint */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="printfacetlist">-</a>
qh_printfacetlist(qh, fp, facetlist, facets, printall )
print all fields for a facet list and/or set of facets to fp
if !printall,
only prints good facets
notes:
also prints all vertices
*/
void qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
facetT *facet, **facetp;
qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
FORALLfacet_(facetlist)
qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
FOREACHfacet_(facets)
qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
} /* printfacetlist */
/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printhelp_degenerate">-</a>
qh_printhelp_degenerate(qh, fp )
prints descriptive message for precision error
notes:
no message if qh_QUICKhelp
*/
void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
qh_fprintf(qh, fp, 9368, "\n\
A Qhull error has occurred. Qhull should have corrected the above\n\
precision error. Please send the input and all of the output to\n\
qhull_bug@qhull.org\n");
else if (!qh_QUICKhelp) {
qh_fprintf(qh, fp, 9369, "\n\
Precision problems were detected during construction of the convex hull.\n\
This occurs because convex hull algorithms assume that calculations are\n\
exact, but floating-point arithmetic has roundoff errors.\n\
\n\
To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
in Qhull\" (qh-impre.htm).\n\
\n\
If you use 'Q0', the output may include\n\
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
Qhull may produce a ridge with four neighbors or two facets with the same \n\
vertices. Qhull reports these events when they occur. It stops when a\n\
concave ridge, flipped facet, or duplicate facet occurs.\n");
#if REALfloat
qh_fprintf(qh, fp, 9370, "\
\n\
Qhull is currently using single precision arithmetic. The following\n\
will probably remove the precision problems:\n\
- recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
#endif
if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
qh_fprintf(qh, fp, 9371, "\
\n\
When computing the Delaunay triangulation of coordinates > 1.0,\n\
- use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
if (qh->DELAUNAY && !qh->ATinfinity)
qh_fprintf(qh, fp, 9372, "\
When computing the Delaunay triangulation:\n\
- use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
qh_fprintf(qh, fp, 9373, "\
\n\
If you need triangular output:\n\
- use option 'Qt' to triangulate the output\n\
- use option 'QJ' to joggle the input points and remove precision errors\n\
- use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
\n\
If you must use 'Q0',\n\
try one or more of the following options. They can not guarantee an output.\n\
- use 'QbB' to scale the input to a cube.\n\
- use 'Po' to produce output and prevent partitioning for flipped facets\n\
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
- options 'Qf', 'Qbb', and 'QR0' may also help\n",
qh->DISTround);
qh_fprintf(qh, fp, 9374, "\
\n\
To guarantee simplicial output:\n\
- use option 'Qt' to triangulate the output\n\
- use option 'QJ' to joggle the input points and remove precision errors\n\
- use option 'Ft' to triangulate the output by adding points\n\
- use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
");
}
} /* printhelp_degenerate */
/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="printhelp_narrowhull">-</a>
qh_printhelp_narrowhull(qh, minangle )
Warn about a narrow hull
notes:
Alternatively, reduce qh_WARNnarrow in user.h
*/
void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
qh_fprintf(qh, fp, 9375, "qhull precision warning: \n\
The initial hull is narrow (cosine of min. angle is %.16f).\n\
Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may\n\
produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
last coordinate) may remove this warning. Use 'Pp' to skip this warning.\n\
See 'Limitations' in qh-impre.htm.\n",
-minangle); /* convert from angle between normals to angle between facets */
} /* printhelp_narrowhull */
/*-<a href="qh-io_r.htm#TOC"
>-------------------------------</a><a name="printhelp_singular">-</a>
qh_printhelp_singular(qh, fp )
prints descriptive message for singular input
*/
void qh_printhelp_singular(qhT *qh, FILE *fp) {
facetT *facet;
vertexT *vertex, **vertexp;
realT min, max, *coord, dist;
int i,k;
qh_fprintf(qh, fp, 9376, "\n\
The input to qhull appears to be less than %d dimensional, or a\n\
computation has overflowed.\n\n\
Qhull could not construct a clearly convex simplex from points:\n",
qh->hull_dim);
qh_printvertexlist(qh, fp, "", qh->facet_list, NULL, qh_ALL);
if (!qh_QUICKhelp)
qh_fprintf(qh, fp, 9377, "\n\
The center point is coplanar with a facet, or a vertex is coplanar\n\
with a neighboring facet. The maximum round off error for\n\
computing distances is %2.2g. The center point, facets and distances\n\
to the center point are as follows:\n\n", qh->DISTround);
qh_printpointid(qh, fp, "center point", qh->hull_dim, qh->interior_point, qh_IDunknown);
qh_fprintf(qh, fp, 9378, "\n");
FORALLfacets {
qh_fprintf(qh, fp, 9379, "facet");
FOREACHvertex_(facet->vertices)
qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
zinc_(Zdistio);
qh_distplane(qh, qh->interior_point, facet, &dist);
qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
}
if (!qh_QUICKhelp) {
if (qh->HALFspace)
qh_fprintf(qh, fp, 9382, "\n\
These points are the dual of the given halfspaces. They indicate that\n\
the intersection is degenerate.\n");
qh_fprintf(qh, fp, 9383,"\n\
These points either have a maximum or minimum x-coordinate, or\n\
they maximize the determinant for k coordinates. Trial points\n\
are first selected from points that maximize a coordinate.\n");
if (qh->hull_dim >= qh_INITIALmax)
qh_fprintf(qh, fp, 9384, "\n\
Because of the high dimension, the min x-coordinate and max-coordinate\n\
points are used if the determinant is non-zero. Option 'Qs' will\n\
do a better, though much slower, job. Instead of 'Qs', you can change\n\
the points by randomly rotating the input with 'QR0'.\n");
}
qh_fprintf(qh, fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
for (k=0; k < qh->hull_dim; k++) {
min= REALmax;
max= -REALmin;
for (i=qh->num_points, coord= qh->first_point+k; i--; coord += qh->hull_dim) {
maximize_(max, *coord);
minimize_(min, *coord);
}
qh_fprintf(qh, fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
}
if (!qh_QUICKhelp) {
qh_fprintf(qh, fp, 9387, "\n\
If the input should be full dimensional, you have several options that\n\
may determine an initial simplex:\n\
- use 'QJ' to joggle the input and make it full dimensional\n\
- use 'QbB' to scale the points to the unit cube\n\
- use 'QR0' to randomly rotate the input for different maximum points\n\
- use 'Qs' to search all points for the initial simplex\n\
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
- trace execution with 'T3' to see the determinant for each point.\n",
qh->DISTround);
#if REALfloat
qh_fprintf(qh, fp, 9388, "\
- recompile qhull for realT precision(#define REALfloat 0 in libqhull_r.h).\n");
#endif
qh_fprintf(qh, fp, 9389, "\n\
If the input is lower dimensional:\n\
- use 'QJ' to joggle the input and make it full dimensional\n\
- use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
pick the coordinate with the least range. The hull will have the\n\
correct topology.\n\
- determine the flat containing the points, rotate the points\n\
into a coordinate plane, and delete the other coordinates.\n\
- add one or more points to make the input full dimensional.\n\
");
}
} /* printhelp_singular */
/*-<a href="qh-globa_r.htm#TOC"
>-------------------------------</a><a name="user_memsizes">-</a>
qh_user_memsizes(qh)
allocate up to 10 additional, quick allocation sizes
notes:
increase maximum number of allocations in qh_initqhull_mem()
*/
void qh_user_memsizes(qhT *qh) {
QHULL_UNUSED(qh)
/* qh_memsize(qh, size); */
} /* user_memsizes */

View File

@@ -0,0 +1,882 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
user.h
user redefinable constants
for each source file, user_r.h is included first
see qh-user_r.htm. see COPYING for copyright information.
See user_r.c for sample code.
before reading any code, review libqhull_r.h for data structure definitions
Sections:
============= qhull library constants ======================
============= data types and configuration macros ==========
============= performance related constants ================
============= memory constants =============================
============= joggle constants =============================
============= conditional compilation ======================
============= -merge constants- ============================
Code flags --
NOerrors -- the code does not call qh_errexit()
WARN64 -- the code may be incompatible with 64-bit pointers
*/
#include <time.h>
#ifndef qhDEFuser
#define qhDEFuser 1
/* Derived from Qt's corelib/global/qglobal.h */
#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
# define QHULL_OS_WIN
#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
# define QHULL_OS_WIN
#endif
/*============================================================*/
/*============= qhull library constants ======================*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="filenamelen">-</a>
FILENAMElen -- max length for TI and TO filenames
*/
#define qh_FILENAMElen 500
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="msgcode">-</a>
msgcode -- Unique message codes for qh_fprintf
If add new messages, assign these values and increment in user.h and user_r.h
See QhullError.h for 10000 errors.
def counters = [27, 1048, 2059, 3026, 4068, 5003,
6273, 7081, 8147, 9411, 10000, 11029]
See: qh_ERR* [libqhull_r.h]
*/
#define MSG_TRACE0 0
#define MSG_TRACE1 1000
#define MSG_TRACE2 2000
#define MSG_TRACE3 3000
#define MSG_TRACE4 4000
#define MSG_TRACE5 5000
#define MSG_ERROR 6000 /* errors written to qh.ferr */
#define MSG_WARNING 7000
#define MSG_STDERR 8000 /* log messages Written to qh.ferr */
#define MSG_OUTPUT 9000
#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
#define MSG_FIXUP 11000 /* FIXUP QH11... */
#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="qh_OPTIONline">-</a>
qh_OPTIONline -- max length of an option line 'FO'
*/
#define qh_OPTIONline 80
/*============================================================*/
/*============= data types and configuration macros ==========*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="realT">-</a>
realT
set the size of floating point numbers
qh_REALdigits
maximimum number of significant digits
qh_REAL_1, qh_REAL_2n, qh_REAL_3n
format strings for printf
qh_REALmax, qh_REALmin
maximum and minimum (near zero) values
qh_REALepsilon
machine roundoff. Maximum roundoff error for addition and multiplication.
notes:
Select whether to store floating point numbers in single precision (float)
or double precision (double).
Use 'float' to save about 8% in time and 25% in space. This is particularly
helpful if high-d where convex hulls are space limited. Using 'float' also
reduces the printed size of Qhull's output since numbers have 8 digits of
precision.
Use 'double' when greater arithmetic precision is needed. This is needed
for Delaunay triangulations and Voronoi diagrams when you are not merging
facets.
If 'double' gives insufficient precision, your data probably includes
degeneracies. If so you should use facet merging (done by default)
or exact arithmetic (see imprecision section of manual, qh-impre.htm).
You may also use option 'Po' to force output despite precision errors.
You may use 'long double', but many format statements need to be changed
and you may need a 'long double' square root routine. S. Grundmann
(sg@eeiwzb.et.tu-dresden.de) has done this. He reports that the code runs
much slower with little gain in precision.
WARNING: on some machines, int f(){realT a= REALmax;return (a == REALmax);}
returns False. Use (a > REALmax/2) instead of (a == REALmax).
REALfloat = 1 all numbers are 'float' type
= 0 all numbers are 'double' type
*/
#define REALfloat 0
#if (REALfloat == 1)
#define realT float
#define REALmax FLT_MAX
#define REALmin FLT_MIN
#define REALepsilon FLT_EPSILON
#define qh_REALdigits 8 /* maximum number of significant digits */
#define qh_REAL_1 "%6.8g "
#define qh_REAL_2n "%6.8g %6.8g\n"
#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
#elif (REALfloat == 0)
#define realT double
#define REALmax DBL_MAX
#define REALmin DBL_MIN
#define REALepsilon DBL_EPSILON
#define qh_REALdigits 16 /* maximum number of significant digits */
#define qh_REAL_1 "%6.16g "
#define qh_REAL_2n "%6.16g %6.16g\n"
#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
#else
#error unknown float option
#endif
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="countT">-</a>
countT
The type for counts and identifiers (e.g., the number of points, vertex identifiers)
Currently used by C++ code-only. Decided against using it for setT because most sets are small.
Defined as 'int' for C-code compatibility and QH11026
FIXUP QH11026 countT may be defined as a unsigned value, but several code issues need to be solved first. See countT in Changes.txt
*/
#ifndef DEFcountT
#define DEFcountT 1
typedef int countT;
#endif
#define COUNTmax 0x7fffffff
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="CPUclock">-</a>
qh_CPUclock
define the clock() function for reporting the total time spent by Qhull
returns CPU ticks as a 'long int'
qh_CPUclock is only used for reporting the total time spent by Qhull
qh_SECticks
the number of clock ticks per second
notes:
looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
to define a custom clock, set qh_CLOCKtype to 0
if your system does not use clock() to return CPU ticks, replace
qh_CPUclock with the corresponding function. It is converted
to 'unsigned long' to prevent wrap-around during long runs. By default,
<time.h> defines clock_t as 'long'
Set qh_CLOCKtype to
1 for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
Note: may fail if more than 1 hour elapsed time
2 use qh_clock() with POSIX times() (see global_r.c)
*/
#define qh_CLOCKtype 1 /* change to the desired number */
#if (qh_CLOCKtype == 1)
#if defined(CLOCKS_PER_SECOND)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLOCKS_PER_SECOND
#elif defined(CLOCKS_PER_SEC)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLOCKS_PER_SEC
#elif defined(CLK_TCK)
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks CLK_TCK
#else
#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
#define qh_SECticks 1E6
#endif
#elif (qh_CLOCKtype == 2)
#define qh_CPUclock qh_clock() /* return CPU clock */
#define qh_SECticks 100
#else /* qh_CLOCKtype == ? */
#error unknown clock option
#endif
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="RANDOM">-</a>
qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
define random number generator
qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.
qh_RANDOMseed sets the random number seed for qh_RANDOMint
Set qh_RANDOMtype (default 5) to:
1 for random() with 31 bits (UCB)
2 for rand() with RAND_MAX or 15 bits (system 5)
3 for rand() with 31 bits (Sun)
4 for lrand48() with 31 bits (Solaris)
5 for qh_rand(qh) with 31 bits (included with Qhull, requires 'qh')
notes:
Random numbers are used by rbox to generate point sets. Random
numbers are used by Qhull to rotate the input ('QRn' option),
simulate a randomized algorithm ('Qr' option), and to simulate
roundoff errors ('Rn' option).
Random number generators differ between systems. Most systems provide
rand() but the period varies. The period of rand() is not critical
since qhull does not normally use random numbers.
The default generator is Park & Miller's minimal standard random
number generator [CACM 31:1195 '88]. It is included with Qhull.
If qh_RANDOMmax is wrong, qhull will report a warning and Geomview
output will likely be invisible.
*/
#define qh_RANDOMtype 5 /* *** change to the desired number *** */
#if (qh_RANDOMtype == 1)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, random()/MAX */
#define qh_RANDOMint random()
#define qh_RANDOMseed_(qh, seed) srandom(seed);
#elif (qh_RANDOMtype == 2)
#ifdef RAND_MAX
#define qh_RANDOMmax ((realT)RAND_MAX)
#else
#define qh_RANDOMmax ((realT)32767) /* 15 bits (System 5) */
#endif
#define qh_RANDOMint rand()
#define qh_RANDOMseed_(qh, seed) srand((unsigned)seed);
#elif (qh_RANDOMtype == 3)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, Sun */
#define qh_RANDOMint rand()
#define qh_RANDOMseed_(qh, seed) srand((unsigned)seed);
#elif (qh_RANDOMtype == 4)
#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, lrand38()/MAX */
#define qh_RANDOMint lrand48()
#define qh_RANDOMseed_(qh, seed) srand48(seed);
#elif (qh_RANDOMtype == 5) /* 'qh' is an implicit parameter */
#define qh_RANDOMmax ((realT)2147483646UL) /* 31 bits, qh_rand/MAX */
#define qh_RANDOMint qh_rand(qh)
#define qh_RANDOMseed_(qh, seed) qh_srand(qh, seed);
/* unlike rand(), never returns 0 */
#else
#error: unknown random option
#endif
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="ORIENTclock">-</a>
qh_ORIENTclock
0 for inward pointing normals by Geomview convention
*/
#define qh_ORIENTclock 0
/*============================================================*/
/*============= joggle constants =============================*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEdefault">-</a>
qh_JOGGLEdefault
default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
notes:
rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
the later have about 20 points per facet, each of which may interfere
pick a value large enough to avoid retries on most inputs
*/
#define qh_JOGGLEdefault 30000.0
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEincrease">-</a>
qh_JOGGLEincrease
factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
*/
#define qh_JOGGLEincrease 10.0
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEretry">-</a>
qh_JOGGLEretry
if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
notes:
try twice at the original value in case of bad luck the first time
*/
#define qh_JOGGLEretry 2
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEagain">-</a>
qh_JOGGLEagain
every following qh_JOGGLEagain, increase qh.JOGGLEmax
notes:
1 is OK since it's already failed qh_JOGGLEretry times
*/
#define qh_JOGGLEagain 1
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
qh_JOGGLEmaxincrease
maximum qh.JOGGLEmax due to qh_JOGGLEincrease
relative to qh.MAXwidth
notes:
qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
*/
#define qh_JOGGLEmaxincrease 1e-2
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
qh_JOGGLEmaxretry
stop after qh_JOGGLEmaxretry attempts
*/
#define qh_JOGGLEmaxretry 100
/*============================================================*/
/*============= performance related constants ================*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="HASHfactor">-</a>
qh_HASHfactor
total hash slots / used hash slots. Must be at least 1.1.
notes:
=2 for at worst 50% occupancy for qh.hash_table and normally 25% occupancy
*/
#define qh_HASHfactor 2
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="VERIFYdirect">-</a>
qh_VERIFYdirect
with 'Tv' verify all points against all facets if op count is smaller
notes:
if greater, calls qh_check_bestdist() instead
*/
#define qh_VERIFYdirect 1000000
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="INITIALsearch">-</a>
qh_INITIALsearch
if qh_INITIALmax, search points up to this dimension
*/
#define qh_INITIALsearch 6
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="INITIALmax">-</a>
qh_INITIALmax
if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
notes:
from points with non-zero determinants
use option 'Qs' to override (much slower)
*/
#define qh_INITIALmax 8
/*============================================================*/
/*============= memory constants =============================*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MEMalign">-</a>
qh_MEMalign
memory alignment for qh_meminitbuffers() in global_r.c
notes:
to avoid bus errors, memory allocation must consider alignment requirements.
malloc() automatically takes care of alignment. Since mem_r.c manages
its own memory, we need to explicitly specify alignment in
qh_meminitbuffers().
A safe choice is sizeof(double). sizeof(float) may be used if doubles
do not occur in data structures and pointers are the same size. Be careful
of machines (e.g., DEC Alpha) with large pointers.
If using gcc, best alignment is [fmax_() is defined in geom_r.h]
#define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
*/
#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MEMbufsize">-</a>
qh_MEMbufsize
size of additional memory buffers
notes:
used for qh_meminitbuffers() in global_r.c
*/
#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MEMinitbuf">-</a>
qh_MEMinitbuf
size of initial memory buffer
notes:
use for qh_meminitbuffers() in global_r.c
*/
#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="INFINITE">-</a>
qh_INFINITE
on output, indicates Voronoi center at infinity
*/
#define qh_INFINITE -10.101
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="DEFAULTbox">-</a>
qh_DEFAULTbox
default box size (Geomview expects 0.5)
qh_DEFAULTbox
default box size for integer coorindate (rbox only)
*/
#define qh_DEFAULTbox 0.5
#define qh_DEFAULTzbox 1e6
/*============================================================*/
/*============= conditional compilation ======================*/
/*============================================================*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="compiler">-</a>
__cplusplus
defined by C++ compilers
__MSC_VER
defined by Microsoft Visual C++
__MWERKS__ && __INTEL__
defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
__MWERKS__ && __POWERPC__
defined by Metrowerks when compiling for PowerPC-based Macintosh
__STDC__
defined for strict ANSI C
*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="COMPUTEfurthest">-</a>
qh_COMPUTEfurthest
compute furthest distance to an outside point instead of storing it with the facet
=1 to compute furthest
notes:
computing furthest saves memory but costs time
about 40% more distance tests for partitioning
removes facet->furthestdist
*/
#define qh_COMPUTEfurthest 0
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="KEEPstatistics">-</a>
qh_KEEPstatistics
=0 removes most of statistic gathering and reporting
notes:
if 0, code size is reduced by about 4%.
*/
#define qh_KEEPstatistics 1
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MAXoutside">-</a>
qh_MAXoutside
record outer plane for each facet
=1 to record facet->maxoutside
notes:
this takes a realT per facet and slightly slows down qhull
it produces better outer planes for geomview output
*/
#define qh_MAXoutside 1
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="NOmerge">-</a>
qh_NOmerge
disables facet merging if defined
notes:
This saves about 10% space.
Unless 'Q0'
qh_NOmerge sets 'QJ' to avoid precision errors
#define qh_NOmerge
see:
<a href="mem_r.h#NOmem">qh_NOmem</a> in mem_r.c
see user_r.c/user_eg.c for removing io_r.o
*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="NOtrace">-</a>
qh_NOtrace
no tracing if defined
notes:
This saves about 5% space.
#define qh_NOtrace
*/
#if 0 /* sample code */
exitcode= qh_new_qhull(qhT *qh, dim, numpoints, points, ismalloc,
flags, outfile, errfile);
qh_freeqhull(qhT *qh, !qh_ALL); /* frees long memory used by second call */
qh_memfreeshort(qhT *qh, &curlong, &totlong); /* frees short memory and memory allocator */
#endif
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="QUICKhelp">-</a>
qh_QUICKhelp
=1 to use abbreviated help messages, e.g., for degenerate inputs
*/
#define qh_QUICKhelp 0
/*============================================================*/
/*============= -merge constants- ============================*/
/*============================================================*/
/*
These constants effect facet merging. You probably will not need
to modify them. They effect the performance of facet merging.
*/
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="DIMmergeVertex">-</a>
qh_DIMmergeVertex
max dimension for vertex merging (it is not effective in high-d)
*/
#define qh_DIMmergeVertex 6
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="DIMreduceBuild">-</a>
qh_DIMreduceBuild
max dimension for vertex reduction during build (slow in high-d)
*/
#define qh_DIMreduceBuild 5
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="BESTcentrum">-</a>
qh_BESTcentrum
if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
else, qh_findbestneighbor() tests all vertices (much better merges)
qh_BESTcentrum2
if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
*/
#define qh_BESTcentrum 20
#define qh_BESTcentrum2 2
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="BESTnonconvex">-</a>
qh_BESTnonconvex
if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
notes:
It is needed because qh_findbestneighbor is slow for large facets
*/
#define qh_BESTnonconvex 15
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MAXnewmerges">-</a>
qh_MAXnewmerges
if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
notes:
It is needed because postmerge can merge many facets at once
*/
#define qh_MAXnewmerges 2
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MAXnewcentrum">-</a>
qh_MAXnewcentrum
if <= dim+n vertices (n approximates the number of merges),
reset the centrum in qh_updatetested() and qh_mergecycle_facets()
notes:
needed to reduce cost and because centrums may move too much if
many vertices in high-d
*/
#define qh_MAXnewcentrum 5
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="COPLANARratio">-</a>
qh_COPLANARratio
for 3-d+ merging, qh.MINvisible is n*premerge_centrum
notes:
for non-merging, it's DISTround
*/
#define qh_COPLANARratio 3
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="DISToutside">-</a>
qh_DISToutside
When is a point clearly outside of a facet?
Stops search in qh_findbestnew or qh_partitionall
qh_findbest uses qh.MINoutside since since it is only called if no merges.
notes:
'Qf' always searches for best facet
if !qh.MERGING, same as qh.MINoutside.
if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
[Note: Zdelvertextot occurs normally with interior points]
RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
When there is a sharp edge, need to move points to a
clearly good facet; otherwise may be lost in another partitioning.
if too big then O(n^2) behavior for partitioning in cone
if very small then important points not processed
Needed in qh_partitionall for
RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
Needed in qh_findbestnew for many instances of
RBOX 1000 s Z1 G1e-13 t | QHULL Tv
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
fmax_((qh->MERGING ? 2 : 1)*qh->MINoutside, qh->max_outside))
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="RATIOnearinside">-</a>
qh_RATIOnearinside
ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
qh_check_maxout().
notes:
This is overkill since do not know the correct value.
It effects whether 'Qc' reports all coplanar points
Not used for 'd' since non-extreme points are coplanar
*/
#define qh_RATIOnearinside 5
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="SEARCHdist">-</a>
qh_SEARCHdist
When is a facet coplanar with the best facet?
qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
(qh->max_outside + 2 * qh->DISTround + fmax_( qh->MINvisible, qh->MAXcoplanar)));
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="USEfindbestnew">-</a>
qh_USEfindbestnew
Always use qh_findbestnew for qh_partitionpoint, otherwise use
qh_findbestnew if merged new facet or sharpnewfacets.
See:
qh_DISToutside -- when is a point clearly outside of a facet
qh_SEARCHdist -- when is facet coplanar with the best facet?
qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
*/
#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="WIDEcoplanar">-</a>
qh_WIDEcoplanar
n*MAXcoplanar or n*MINvisible for a WIDEfacet
if vertex is further than qh.WIDEfacet from the hyperplane
then its ridges are not counted in computing the area, and
the facet's centrum is frozen.
notes:
qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
qh_WIDEcoplanar * qh.MINvisible);
*/
#define qh_WIDEcoplanar 6
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="WIDEduplicate">-</a>
qh_WIDEduplicate
Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
Override with option Q12 no-wide-duplicate
Notes:
Merging a duplicate ridge can lead to very wide facets.
A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
*/
#define qh_WIDEduplicate 100
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="MAXnarrow">-</a>
qh_MAXnarrow
max. cosine in initial hull that sets qh.NARROWhull
notes:
If qh.NARROWhull, the initial partition does not make
coplanar points. If narrow, a coplanar point can be
coplanar to two facets of opposite orientations and
distant from the exact convex hull.
Conservative estimate. Don't actually see problems until it is -1.0
*/
#define qh_MAXnarrow -0.99999999
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="WARNnarrow">-</a>
qh_WARNnarrow
max. cosine in initial hull to warn about qh.NARROWhull
notes:
this is a conservative estimate.
Don't actually see problems until it is -1.0. See qh-impre.htm
*/
#define qh_WARNnarrow -0.999999999999999
/*-<a href="qh-user_r.htm#TOC"
>--------------------------------</a><a name="ZEROdelaunay">-</a>
qh_ZEROdelaunay
a zero Delaunay facet occurs for input sites coplanar with their convex hull
the last normal coefficient of a zero Delaunay facet is within
qh_ZEROdelaunay * qh.ANGLEround of 0
notes:
qh_ZEROdelaunay does not allow for joggled input ('QJ').
You can avoid zero Delaunay facets by surrounding the input with a box.
Use option 'PDk:-n' to explicitly define zero Delaunay facets
k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
*/
#define qh_ZEROdelaunay 2
/*============================================================*/
/*============= Microsoft DevStudio ==========================*/
/*============================================================*/
/*
Finding Memory Leaks Using the CRT Library
https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
Reports enabled in qh_lib_check for Debug window and stderr
From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
Watch: {,,msvcr80d.dll}_crtBreakAlloc Value from {n} in the leak report
_CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
Examples
http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
*/
#if 0 /* off (0) by default for QHULL_CRTDBG */
#define QHULL_CRTDBG
#endif
#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#endif /* qh_DEFuser */

View File

@@ -0,0 +1,94 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
usermem_r.c
qh_exit(), qh_free(), and qh_malloc()
See README.txt.
If you redefine one of these functions you must redefine all of them.
If you recompile and load this file, then usermem.o will not be loaded
from qhull.a or qhull.lib
See libqhull_r.h for data structures, macros, and user-callable functions.
See user_r.c for qhull-related, redefinable functions
see user_r.h for user-definable constants
See userprintf_r.c for qh_fprintf and userprintf_rbox_r.c for qh_fprintf_rbox
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull_r.h"
#include <stdarg.h>
#include <stdlib.h>
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_exit">-</a>
qh_exit( exitcode )
exit program
notes:
qh_exit() is called when qh_errexit() and longjmp() are not available.
This is the only use of exit() in Qhull
To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
*/
void qh_exit(int exitcode) {
exit(exitcode);
} /* exit */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_stderr">-</a>
qh_fprintf_stderr( msgcode, format, list of args )
fprintf to stderr with msgcode (non-zero)
notes:
qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
It is typically followed by qh_errexit().
Redefine this function to avoid using stderr
Use qh_fprintf [userprintf_r.c] for normal printing
*/
void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
va_list args;
va_start(args, fmt);
if(msgcode)
fprintf(stderr, "QH%.4d ", msgcode);
vfprintf(stderr, fmt, args);
va_end(args);
} /* fprintf_stderr */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_free">-</a>
qh_free(qhT *qh, mem )
free memory
notes:
same as free()
No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
} /* free */
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_malloc">-</a>
qh_malloc( mem )
allocate memory
notes:
same as malloc()
*/
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */

View File

@@ -0,0 +1,65 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
userprintf_r.c
qh_fprintf()
see README.txt see COPYING.txt for copyright information.
If you recompile and load this file, then userprintf_r.o will not be loaded
from qhull.a or qhull.lib
See libqhull_r.h for data structures, macros, and user-callable functions.
See user_r.c for qhull-related, redefinable functions
see user_r.h for user-definable constants
See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
see Qhull.cpp and RboxPoints.cpp for examples.
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull_r.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf">-</a>
qh_fprintf(qh, fp, msgcode, format, list of args )
print arguments to *fp according to format
Use qh_fprintf_rbox() for rboxlib_r.c
notes:
same as fprintf()
fgets() is not trapped like fprintf()
exit qh_fprintf via qh_errexit()
may be called for errors in qh_initstatistics and qh_meminit
*/
void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
if(!qh){
qh_fprintf_stderr(6241, "userprintf_r.c: fp and qh not defined for qh_fprintf '%s'", fmt);
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
}
/* could use qh->qhmem.ferr, but probably better to be cautious */
qh_fprintf_stderr(6232, "Qhull internal error (userprintf_r.c): fp is 0. Wrong qh_fprintf called.\n");
qh_errexit(qh, 6232, NULL, NULL);
}
va_start(args, fmt);
if (qh && qh->ANNOTATEoutput) {
fprintf(fp, "[QH%.4d]", msgcode);
}else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
fprintf(fp, "QH%.4d ", msgcode);
}
vfprintf(fp, fmt, args);
va_end(args);
/* Place debugging traps here. Use with option 'Tn' */
} /* qh_fprintf */

View File

@@ -0,0 +1,53 @@
/*<html><pre> -<a href="qh-user_r.htm"
>-------------------------------</a><a name="TOP">-</a>
userprintf_rbox_r.c
qh_fprintf_rbox()
see README.txt see COPYING.txt for copyright information.
If you recompile and load this file, then userprintf_rbox_r.o will not be loaded
from qhull.a or qhull.lib
See libqhull_r.h for data structures, macros, and user-callable functions.
See user_r.c for qhull-related, redefinable functions
see user_r.h for user-definable constants
See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
see Qhull.cpp and RboxPoints.cpp for examples.
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull_r.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/*-<a href="qh-user_r.htm#TOC"
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
print arguments to *fp according to format
Use qh_fprintf_rbox() for rboxlib_r.c
notes:
same as fprintf()
fgets() is not trapped like fprintf()
exit qh_fprintf_rbox via qh_errexit_rbox()
*/
void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox_r.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
qh_errexit_rbox(qh, 6231);
}
if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
fprintf(fp, "QH%.4d ", msgcode);
va_start(args, fmt);
vfprintf(fp, fmt, args);
va_end(args);
} /* qh_fprintf_rbox */

View File

@@ -0,0 +1,198 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.cpp#4 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/Coordinates.h"
#include "libqhullcpp/functionObjects.h"
#include "libqhullcpp/QhullError.h"
#include <iostream>
#include <iterator>
#include <algorithm>
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#endif
namespace orgQhull {
#//! Coordinates -- vector of coordT (normally double)
#//!\name Constructor
#//!\name Element access
// Inefficient without result-value-optimization or implicitly shared object
Coordinates Coordinates::
mid(countT idx, countT length) const
{
countT newLength= length;
if(length<0 || idx+length > count()){
newLength= count()-idx;
}
Coordinates result;
if(newLength>0){
std::copy(begin()+idx, begin()+(idx+newLength), std::back_inserter(result));
}
return result;
}//mid
coordT Coordinates::
value(countT idx, const coordT &defaultValue) const
{
return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
}//value
#//!\name GetSet
Coordinates Coordinates::
operator+(const Coordinates &other) const
{
Coordinates result(*this);
std::copy(other.begin(), other.end(), std::back_inserter(result));
return result;
}//operator+
Coordinates & Coordinates::
operator+=(const Coordinates &other)
{
if(&other==this){
Coordinates clone(other);
std::copy(clone.begin(), clone.end(), std::back_inserter(*this));
}else{
std::copy(other.begin(), other.end(), std::back_inserter(*this));
}
return *this;
}//operator+=
#//!\name Read-write
void Coordinates::
append(int pointDimension, coordT *c)
{
if(c){
coordT *p= c;
for(int i= 0; i<pointDimension; ++i){
coordinate_array.push_back(*p++);
}
}
}//append dim coordT
coordT Coordinates::
takeAt(countT idx)
{
coordT c= at(idx);
erase(begin()+idx);
return c;
}//takeAt
coordT Coordinates::
takeLast()
{
coordT c= last();
removeLast();
return c;
}//takeLast
void Coordinates::
swap(countT idx, countT other)
{
coordT c= at(idx);
at(idx)= at(other);
at(other)= c;
}//swap
#//!\name Search
bool Coordinates::
contains(const coordT &t) const
{
CoordinatesIterator i(*this);
return i.findNext(t);
}//contains
countT Coordinates::
count(const coordT &t) const
{
CoordinatesIterator i(*this);
countT result= 0;
while(i.findNext(t)){
++result;
}
return result;
}//count
countT Coordinates::
indexOf(const coordT &t, countT from) const
{
if(from<0){
from += count();
if(from<0){
from= 0;
}
}
if(from<count()){
const_iterator i= begin()+from;
while(i!=constEnd()){
if(*i==t){
return (static_cast<countT>(i-begin())); // WARN64 coordinate index
}
++i;
}
}
return -1;
}//indexOf
countT Coordinates::
lastIndexOf(const coordT &t, countT from) const
{
if(from<0){
from += count();
}else if(from>=count()){
from= count()-1;
}
if(from>=0){
const_iterator i= begin()+from+1;
while(i-- != constBegin()){
if(*i==t){
return (static_cast<countT>(i-begin())); // WARN64 coordinate index
}
}
}
return -1;
}//lastIndexOf
void Coordinates::
removeAll(const coordT &t)
{
MutableCoordinatesIterator i(*this);
while(i.findNext(t)){
i.remove();
}
}//removeAll
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::istream;
using std::ostream;
using std::string;
using std::ws;
using orgQhull::Coordinates;
ostream &
operator<<(ostream &os, const Coordinates &cs)
{
Coordinates::const_iterator c= cs.begin();
for(countT i=cs.count(); i--; ){
os << *c++ << " ";
}
return os;
}//operator<<

View File

@@ -0,0 +1,303 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.h#6 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHCOORDINATES_H
#define QHCOORDINATES_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullIterator.h"
#include <cstddef> // ptrdiff_t, size_t
#include <ostream>
// Requires STL vector class. Can use with another vector class such as QList.
#include <vector>
namespace orgQhull {
#//!\name Defined here
//! An std::vector of point coordinates independent of dimension
//! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint
//! A QhullPoint refers to previously allocated coordinates
class Coordinates;
class MutableCoordinatesIterator;
class Coordinates {
private:
#//!\name Fields
std::vector<coordT> coordinate_array;
public:
#//!\name Subtypes
class const_iterator;
class iterator;
typedef iterator Iterator;
typedef const_iterator ConstIterator;
typedef coordT value_type;
typedef const value_type *const_pointer;
typedef const value_type & const_reference;
typedef value_type * pointer;
typedef value_type & reference;
typedef ptrdiff_t difference_type;
typedef countT size_type;
#//!\name Construct
Coordinates() {};
explicit Coordinates(const std::vector<coordT> &other) : coordinate_array(other) {}
Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {}
Coordinates & operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; }
Coordinates & operator=(const std::vector<coordT> &other) { coordinate_array= other; return *this; }
~Coordinates() {}
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<coordT> toStdVector() const { return coordinate_array; }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<coordT> toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
countT count() const { return static_cast<countT>(size()); }
coordT * data() { return isEmpty() ? 0 : &at(0); }
const coordT * data() const { return const_cast<const pointT*>(isEmpty() ? 0 : &at(0)); }
bool isEmpty() const { return coordinate_array.empty(); }
bool operator==(const Coordinates &other) const { return coordinate_array==other.coordinate_array; }
bool operator!=(const Coordinates &other) const { return coordinate_array!=other.coordinate_array; }
size_t size() const { return coordinate_array.size(); }
#//!\name Element access
coordT & at(countT idx) { return coordinate_array.at(idx); }
const coordT & at(countT idx) const { return coordinate_array.at(idx); }
coordT & back() { return coordinate_array.back(); }
const coordT & back() const { return coordinate_array.back(); }
coordT & first() { return front(); }
const coordT & first() const { return front(); }
coordT & front() { return coordinate_array.front(); }
const coordT & front() const { return coordinate_array.front(); }
coordT & last() { return back(); }
const coordT & last() const { return back(); }
Coordinates mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates
coordT & operator[](countT idx) { return coordinate_array.operator[](idx); }
const coordT & operator[](countT idx) const { return coordinate_array.operator[](idx); }
coordT value(countT idx, const coordT &defaultValue) const;
#//!\name Iterator
iterator begin() { return iterator(coordinate_array.begin()); }
const_iterator begin() const { return const_iterator(coordinate_array.begin()); }
const_iterator constBegin() const { return begin(); }
const_iterator constEnd() const { return end(); }
iterator end() { return iterator(coordinate_array.end()); }
const_iterator end() const { return const_iterator(coordinate_array.end()); }
#//!\name GetSet
Coordinates operator+(const Coordinates &other) const;
#//!\name Modify
void append(int pointDimension, coordT *c);
void append(const coordT &c) { push_back(c); }
void clear() { coordinate_array.clear(); }
iterator erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); }
iterator erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); }
void insert(countT before, const coordT &c) { insert(begin()+before, c); }
iterator insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); }
void move(countT from, countT to) { insert(to, takeAt(from)); }
Coordinates & operator+=(const Coordinates &other);
Coordinates & operator+=(const coordT &c) { append(c); return *this; }
Coordinates & operator<<(const Coordinates &other) { return *this += other; }
Coordinates & operator<<(const coordT &c) { return *this += c; }
void pop_back() { coordinate_array.pop_back(); }
void pop_front() { removeFirst(); }
void prepend(const coordT &c) { insert(begin(), c); }
void push_back(const coordT &c) { coordinate_array.push_back(c); }
void push_front(const coordT &c) { insert(begin(), c); }
//removeAll below
void removeAt(countT idx) { erase(begin()+idx); }
void removeFirst() { erase(begin()); }
void removeLast() { erase(--end()); }
void replace(countT idx, const coordT &c) { (*this)[idx]= c; }
void reserve(countT i) { coordinate_array.reserve(i); }
void swap(countT idx, countT other);
coordT takeAt(countT idx);
coordT takeFirst() { return takeAt(0); }
coordT takeLast();
#//!\name Search
bool contains(const coordT &t) const;
countT count(const coordT &t) const;
countT indexOf(const coordT &t, countT from = 0) const;
countT lastIndexOf(const coordT &t, countT from = -1) const;
void removeAll(const coordT &t);
#//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array
// before const_iterator for conversion with comparison operators
// Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS
class iterator {
private:
std::vector<coordT>::iterator i;
friend class const_iterator;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef coordT value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef ptrdiff_t difference_type;
iterator() {}
iterator(const iterator &other) { i= other.i; }
explicit iterator(const std::vector<coordT>::iterator &vi) { i= vi; }
iterator & operator=(const iterator &other) { i= other.i; return *this; }
std::vector<coordT>::iterator &base() { return i; }
coordT & operator*() const { return *i; }
// No operator->() when the base type is double
coordT & operator[](countT idx) const { return i[idx]; }
bool operator==(const iterator &other) const { return i==other.i; }
bool operator!=(const iterator &other) const { return i!=other.i; }
bool operator<(const iterator &other) const { return i<other.i; }
bool operator<=(const iterator &other) const { return i<=other.i; }
bool operator>(const iterator &other) const { return i>other.i; }
bool operator>=(const iterator &other) const { return i>=other.i; }
// reinterpret_cast to break circular dependency
bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
iterator & operator++() { ++i; return *this; }
iterator operator++(int) { return iterator(i++); }
iterator & operator--() { --i; return *this; }
iterator operator--(int) { return iterator(i--); }
iterator & operator+=(countT idx) { i += idx; return *this; }
iterator & operator-=(countT idx) { i -= idx; return *this; }
iterator operator+(countT idx) const { return iterator(i+idx); }
iterator operator-(countT idx) const { return iterator(i-idx); }
difference_type operator-(iterator other) const { return i-other.i; }
};//Coordinates::iterator
#//!\name Coordinates::const_iterator
class const_iterator {
private:
std::vector<coordT>::const_iterator i;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef coordT value_type;
typedef const value_type *pointer;
typedef const value_type &reference;
typedef ptrdiff_t difference_type;
const_iterator() {}
const_iterator(const const_iterator &other) { i= other.i; }
const_iterator(const iterator &o) : i(o.i) {}
explicit const_iterator(const std::vector<coordT>::const_iterator &vi) { i= vi; }
const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
const coordT & operator*() const { return *i; }
// No operator->() when the base type is double
const coordT & operator[](countT idx) const { return i[idx]; }
bool operator==(const const_iterator &other) const { return i==other.i; }
bool operator!=(const const_iterator &other) const { return i!=other.i; }
bool operator<(const const_iterator &other) const { return i<other.i; }
bool operator<=(const const_iterator &other) const { return i<=other.i; }
bool operator>(const const_iterator &other) const { return i>other.i; }
bool operator>=(const const_iterator &other) const { return i>=other.i; }
const_iterator & operator++() { ++i; return *this; }
const_iterator operator++(int) { return const_iterator(i++); }
const_iterator & operator--() { --i; return *this; }
const_iterator operator--(int) { return const_iterator(i--); }
const_iterator & operator+=(countT idx) { i += idx; return *this; }
const_iterator & operator-=(countT idx) { i -= idx; return *this; }
const_iterator operator+(countT idx) const { return const_iterator(i+idx); }
const_iterator operator-(countT idx) const { return const_iterator(i-idx); }
difference_type operator-(const_iterator other) const { return i-other.i; }
};//Coordinates::const_iterator
};//Coordinates
//class CoordinatesIterator
//QHULL_DECLARE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
class CoordinatesIterator
{
typedef Coordinates::const_iterator const_iterator;
private:
const Coordinates * c;
const_iterator i;
public:
CoordinatesIterator(const Coordinates &container): c(&container), i(c->constBegin()) {}
CoordinatesIterator &operator=(const Coordinates &container) { c= &container; i= c->constBegin(); return *this; }
~CoordinatesIterator() {}
bool findNext(const coordT &t) { while (i != c->constEnd()) if(*i++ == t){ return true;} return false; }
bool findPrevious(const coordT &t) { while (i != c->constBegin())if (*(--i) == t){ return true;} return false; }
bool hasNext() const { return i != c->constEnd(); }
bool hasPrevious() const { return i != c->constBegin(); }
const coordT & next() { return *i++; }
const coordT & previous() { return *--i; }
const coordT & peekNext() const { return *i; }
const coordT & peekPrevious() const { const_iterator p= i; return *--p; }
void toFront() { i= c->constBegin(); }
void toBack() { i= c->constEnd(); }
};//CoordinatesIterator
//class MutableCoordinatesIterator
//QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
class MutableCoordinatesIterator
{
typedef Coordinates::iterator iterator;
typedef Coordinates::const_iterator const_iterator;
private:
Coordinates * c;
iterator i;
iterator n;
bool item_exists() const { return const_iterator(n) != c->constEnd(); }
public:
MutableCoordinatesIterator(Coordinates &container) : c(&container) { i= c->begin(); n= c->end(); }
MutableCoordinatesIterator &operator=(Coordinates &container) { c= &container; i= c->begin(); n= c->end(); return *this; }
~MutableCoordinatesIterator() {}
bool findNext(const coordT &t) { while(c->constEnd()!=const_iterator(n= i)){ if(*i++==t){ return true;}} return false; }
bool findPrevious(const coordT &t) { while(c->constBegin()!=const_iterator(i)){ if(*(n= --i)== t){ return true;}} n= c->end(); return false; }
bool hasNext() const { return (c->constEnd()!=const_iterator(i)); }
bool hasPrevious() const { return (c->constBegin()!=const_iterator(i)); }
void insert(const coordT &t) { n= i= c->insert(i, t); ++i; }
coordT & next() { n= i++; return *n; }
coordT & peekNext() const { return *i; }
coordT & peekPrevious() const { iterator p= i; return *--p; }
coordT & previous() { n= --i; return *n; }
void remove() { if(c->constEnd()!=const_iterator(n)){ i= c->erase(n); n= c->end();} }
void setValue(const coordT &t) const { if(c->constEnd()!=const_iterator(n)){ *n= t;} }
void toFront() { i= c->begin(); n= c->end(); }
void toBack() { i= c->end(); n= i; }
coordT & value() { QHULL_ASSERT(item_exists()); return *n; }
const coordT & value() const { QHULL_ASSERT(item_exists()); return *n; }
};//MutableCoordinatesIterator
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
#endif // QHCOORDINATES_H

View File

@@ -0,0 +1,348 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#include "libqhullcpp/PointCoordinates.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/QhullPoint.h"
#include <iterator>
#include <iostream>
using std::istream;
using std::string;
using std::ws;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//! PointCoordinates -- vector of PointCoordinates
#//!\name Constructors
PointCoordinates::
PointCoordinates()
: QhullPoints()
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(const std::string &aComment)
: QhullPoints()
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(int pointDimension, const std::string &aComment)
: QhullPoints()
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
//! Qhull and QhullQh constructors are the same
PointCoordinates::
PointCoordinates(const Qhull &q)
: QhullPoints(q)
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(const Qhull &q, const std::string &aComment)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
PointCoordinates::
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
: QhullPoints(q)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
append(coordinatesCount, c);
}
PointCoordinates::
PointCoordinates(QhullQh *qqh)
: QhullPoints(qqh)
, point_coordinates()
, describe_points()
{
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, const std::string &aComment)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
}
PointCoordinates::
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
: QhullPoints(qqh)
, point_coordinates()
, describe_points(aComment)
{
setDimension(pointDimension);
append(coordinatesCount, c);
}
PointCoordinates::
PointCoordinates(const PointCoordinates &other)
: QhullPoints(other)
, point_coordinates(other.point_coordinates)
, describe_points(other.describe_points)
{
makeValid(); // Update point_first and point_end
}
PointCoordinates & PointCoordinates::
operator=(const PointCoordinates &other)
{
QhullPoints::operator=(other);
point_coordinates= other.point_coordinates;
describe_points= other.describe_points;
makeValid(); // Update point_first and point_end
return *this;
}//operator=
PointCoordinates::
~PointCoordinates()
{ }
#//!\name GetSet
void PointCoordinates::
checkValid() const
{
if(getCoordinates().data()!=data()
|| getCoordinates().count()!=coordinateCount()){
throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
}
}//checkValid
void PointCoordinates::
setDimension(int i)
{
if(i<0){
throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
}
int currentDimension=QhullPoints::dimension();
if(currentDimension!=0 && i!=currentDimension){
throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
}
QhullPoints::setDimension(i);
}//setDimension
#//!\name Foreach
Coordinates::ConstIterator PointCoordinates::
beginCoordinates(countT pointIndex) const
{
return point_coordinates.begin()+indexOffset(pointIndex);
}
Coordinates::Iterator PointCoordinates::
beginCoordinates(countT pointIndex)
{
return point_coordinates.begin()+indexOffset(pointIndex);
}
#//!\name Methods
void PointCoordinates::
append(countT coordinatesCount, const coordT *c)
{
if(coordinatesCount<=0){
return;
}
if(includesCoordinates(c)){
throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself. The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
}
reserveCoordinates(coordinatesCount);
std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
makeValid();
}//append coordT
void PointCoordinates::
append(const PointCoordinates &other)
{
setDimension(other.dimension());
append(other.coordinateCount(), other.data());
}//append PointCoordinates
void PointCoordinates::
append(const QhullPoint &p)
{
setDimension(p.dimension());
append(p.dimension(), p.coordinates());
}//append QhullPoint
void PointCoordinates::
appendComment(const std::string &s){
if(char c= s[0] && describe_points.empty()){
if(c=='-' || isdigit(c)){
throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
}
}
describe_points += s;
}//appendComment
//! Read PointCoordinates from istream. First two numbers are dimension and count. A non-digit starts a rboxCommand.
//! Overwrites describe_points. See qh_readpoints [io.c]
void PointCoordinates::
appendPoints(istream &in)
{
int inDimension;
countT inCount;
in >> ws >> inDimension >> ws;
if(!in.good()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
}
char c= (char)in.peek();
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
getline(in, describe_points);
in >> ws;
}
in >> inCount >> ws;
if(!in.good()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
}
c= (char)in.peek();
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
getline(in, describe_points);
in >> ws;
}
if(inCount<inDimension){ // Count may precede dimension
std::swap(inCount, inDimension);
}
setDimension(inDimension);
reserveCoordinates(inCount*inDimension);
countT coordinatesCount= 0;
while(!in.eof()){
realT p;
in >> p >> ws;
if(in.fail()){
in.clear();
string remainder;
getline(in, remainder);
throw QhullError(10008, "Qhull error: failed to read coordinate %d of point %d\n %s", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
}else{
point_coordinates.push_back(p);
coordinatesCount++;
}
}
if(coordinatesCount != inCount*inDimension){
if(coordinatesCount%inDimension==0){
throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
}else{
throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
}
}
makeValid();
}//appendPoints istream
PointCoordinates PointCoordinates::
operator+(const PointCoordinates &other) const
{
PointCoordinates pc= *this;
pc << other;
return pc;
}//operator+
void PointCoordinates::
reserveCoordinates(countT newCoordinates)
{
// vector::reserve is not const
point_coordinates.reserve((countT)point_coordinates.size()+newCoordinates); // WARN64
makeValid();
}//reserveCoordinates
#//!\name Helpers
countT PointCoordinates::
indexOffset(countT i) const {
countT n= i*dimension();
countT coordinatesCount= point_coordinates.count();
if(i<0 || n>coordinatesCount){
throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
}
return n;
}
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::Coordinates;
using orgQhull::PointCoordinates;
ostream&
operator<<(ostream &os, const PointCoordinates &p)
{
p.checkValid();
countT count= p.count();
int dimension= p.dimension();
string comment= p.comment();
if(comment.empty()){
os << dimension << endl;
}else{
os << dimension << " " << comment << endl;
}
os << count << endl;
Coordinates::ConstIterator c= p.beginCoordinates();
for(countT i=0; i<count; i++){
for(int j=0; j<dimension; j++){
os << *c++ << " ";
}
os << endl;
}
return os;
}//operator<<

View File

@@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHPOINTCOORDINATES_H
#define QHPOINTCOORDINATES_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullPoints.h"
#include "libqhullcpp/Coordinates.h"
#include <ostream>
#include <string>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullPoints with Coordinates and description
//! Inherited by RboxPoints
class PointCoordinates;
class PointCoordinates : public QhullPoints {
private:
#//!\name Fields
Coordinates point_coordinates; //! std::vector of point coordinates
//! may have extraCoordinates()
std::string describe_points; //! Comment describing PointCoordinates
public:
#//!\name Construct
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
//! If Qhull/QhullQh is not initialized, then dimension()==0 PointCoordinates();
PointCoordinates();
explicit PointCoordinates(const std::string &aComment);
PointCoordinates(int pointDimension, const std::string &aComment);
//! Qhull/QhullQh used for dimension() and QhullPoint equality
explicit PointCoordinates(const Qhull &q);
PointCoordinates(const Qhull &q, const std::string &aComment);
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment);
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
//! Use append() and appendPoints() for Coordinates and vector<coordT>
explicit PointCoordinates(QhullQh *qqh);
PointCoordinates(QhullQh *qqh, const std::string &aComment);
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment);
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
//! Use append() and appendPoints() for Coordinates and vector<coordT>
PointCoordinates(const PointCoordinates &other);
PointCoordinates & operator=(const PointCoordinates &other);
~PointCoordinates();
#//!\name Convert
//! QhullPoints coordinates, constData, data, count, size
#ifndef QHULL_NO_STL
void append(const std::vector<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
QList<coordT> toQList() const { return point_coordinates.toQList(); }
#endif //QHULL_USES_QT
#//!\name GetSet
//! See QhullPoints for coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
void checkValid() const;
std::string comment() const { return describe_points; }
void makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
const Coordinates & getCoordinates() const { return point_coordinates; }
void setComment(const std::string &s) { describe_points= s; }
void setDimension(int i);
private:
//! disable QhullPoints.defineAs()
void defineAs(countT coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
public:
#//!\name ElementAccess
//! See QhullPoints for at, back, first, front, last, mid, [], value
#//!\name Foreach
//! See QhullPoints for begin, constBegin, end
Coordinates::ConstIterator beginCoordinates() const { return point_coordinates.begin(); }
Coordinates::Iterator beginCoordinates() { return point_coordinates.begin(); }
Coordinates::ConstIterator beginCoordinates(countT pointIndex) const;
Coordinates::Iterator beginCoordinates(countT pointIndex);
Coordinates::ConstIterator endCoordinates() const { return point_coordinates.end(); }
Coordinates::Iterator endCoordinates() { return point_coordinates.end(); }
#//!\name Search
//! See QhullPoints for contains, count, indexOf, lastIndexOf
#//!\name GetSet
PointCoordinates operator+(const PointCoordinates &other) const;
#//!\name Modify
//FIXUP QH11001: Add clear() and other modify operators from Coordinates.h. Include QhullPoint::operator=()
void append(countT coordinatesCount, const coordT *c); //! Dimension previously defined
void append(const coordT &c) { append(1, &c); } //! Dimension previously defined
void append(const QhullPoint &p);
//! See convert for std::vector and QList
void append(const Coordinates &c) { append(c.count(), c.data()); }
void append(const PointCoordinates &other);
void appendComment(const std::string &s);
void appendPoints(std::istream &in);
PointCoordinates & operator+=(const PointCoordinates &other) { append(other); return *this; }
PointCoordinates & operator+=(const coordT &c) { append(c); return *this; }
PointCoordinates & operator+=(const QhullPoint &p) { append(p); return *this; }
PointCoordinates & operator<<(const PointCoordinates &other) { return *this += other; }
PointCoordinates & operator<<(const coordT &c) { return *this += c; }
PointCoordinates & operator<<(const QhullPoint &p) { return *this += p; }
// reserve() is non-const
void reserveCoordinates(countT newCoordinates);
#//!\name Helpers
private:
int indexOffset(int i) const;
};//PointCoordinates
// No references to QhullPoint. Prevents use of QHULL_DECLARE_SEQUENTIAL_ITERATOR(PointCoordinates, QhullPoint)
class PointCoordinatesIterator
{
typedef PointCoordinates::const_iterator const_iterator;
private:
const PointCoordinates *c;
const_iterator i;
public:
PointCoordinatesIterator(const PointCoordinates &container) : c(&container), i(c->constBegin()) {}
PointCoordinatesIterator &operator=(const PointCoordinates &container) { c = &container; i = c->constBegin(); return *this; }
void toFront() { i = c->constBegin(); }
void toBack() { i = c->constEnd(); }
bool hasNext() const { return i != c->constEnd(); }
const QhullPoint next() { return *i++; }
const QhullPoint peekNext() const { return *i; }
bool hasPrevious() const { return i != c->constBegin(); }
const QhullPoint previous() { return *--i; }
const QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
bool findNext(const QhullPoint &t) { while(i != c->constEnd()){ if (*i++ == t) return true;} return false; }
bool findPrevious(const QhullPoint &t) { while(i != c->constBegin()){ if (*(--i) == t) return true;} return false; }
};//CoordinatesIterator
// FIXUP QH11002: Add MutablePointCoordinatesIterator after adding modify operators
\
}//namespace orgQhull
#//!\name Global
std::ostream & operator<<(std::ostream &os, const orgQhull::PointCoordinates &p);
#endif // QHPOINTCOORDINATES_H

View File

@@ -0,0 +1,358 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.cpp#4 $$Change: 2078 $
** $DateTime: 2016/02/07 16:53:56 $$Author: bbarber $
**
****************************************************************************/
#//! Qhull -- invoke qhull from C++
#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/RboxPoints.h"
#include "libqhullcpp/QhullQh.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullFacetList.h"
#include <iostream>
using std::cerr;
using std::string;
using std::vector;
using std::ostream;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//!\name Global variables
const char s_unsupported_options[]=" Fd TI ";
const char s_not_output_options[]= " Fd TI A C d E H P Qb QbB Qbb Qc Qf Qg Qi Qm QJ Qr QR Qs Qt Qv Qx Qz Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 R Tc TC TM TP TR Tv TV TW U v V W ";
#//!\name Constructor, destructor, etc.
Qhull::
Qhull()
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
}//Qhull
//! Invokes Qhull on rboxPoints
//! Same as runQhull()
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
Qhull::
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
runQhull(rboxPoints, qhullCommand2);
}//Qhull rbox
//! Invokes Qhull on a set of input points
//! Same as runQhull()
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
Qhull::
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
: qh_qh(0)
, origin_point()
, run_called(false)
, feasible_point()
{
allocateQhullQh();
runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
}//Qhull points
void Qhull::
allocateQhullQh()
{
QHULL_LIB_CHECK /* Check for compatible library */
qh_qh= new QhullQh;
void *p= qh_qh;
void *p2= static_cast<qhT *>(qh_qh);
char *s= static_cast<char *>(p);
char *s2= static_cast<char *>(p2);
if(s!=s2){
throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes). Please report compiler to qhull.org", int(s2-s));
}
}//allocateQhullQh
Qhull::
~Qhull() throw()
{
// Except for cerr, does not throw errors
if(qh_qh->hasQhullMessage()){
cerr<< "\nQhull output at end\n"; //FIXUP QH11005: where should error and log messages go on ~Qhull?
cerr<< qh_qh->qhullMessage();
qh_qh->clearQhullMessage();
}
delete qh_qh;
qh_qh= 0;
}//~Qhull
#//!\name GetSet
void Qhull::
checkIfQhullInitialized()
{
if(!initialized()){ // qh_initqhull_buffers() not called
throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed. Call runQhull() first.");
}
}//checkIfQhullInitialized
//! Return feasiblePoint for halfspace intersection
//! If called before runQhull(), then it returns the value from setFeasiblePoint. qh.feasible_string overrides this value if it is defined.
Coordinates Qhull::
feasiblePoint() const
{
Coordinates result;
if(qh_qh->feasible_point){
result.append(qh_qh->hull_dim, qh_qh->feasible_point);
}else{
result= feasible_point;
}
return result;
}//feasiblePoint
//! Return origin point for qh.input_dim
QhullPoint Qhull::
inputOrigin()
{
QhullPoint result= origin();
result.setDimension(qh_qh->input_dim);
return result;
}//inputOrigin
#//!\name GetValue
double Qhull::
area(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_getarea(qh_qh, qh_qh->facet_list);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_qh->totarea;
}//area
double Qhull::
volume(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_getarea(qh_qh, qh_qh->facet_list);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_qh->totvol;
}//volume
#//!\name Foreach
//! Define QhullVertex::neighborFacets().
//! Automatically called if merging facets or computing the Voronoi diagram.
//! Noop if called multiple times.
void Qhull::
defineVertexNeighborFacets(){
checkIfQhullInitialized();
if(!qh_qh->hasAreaVolume){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_vertexneighbors(qh_qh);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
}//defineVertexNeighborFacets
QhullFacetList Qhull::
facetList() const{
return QhullFacetList(beginFacet(), endFacet());
}//facetList
QhullPoints Qhull::
points() const
{
return QhullPoints(qh_qh, qh_qh->hull_dim, qh_qh->num_points*qh_qh->hull_dim, qh_qh->first_point);
}//points
QhullPointSet Qhull::
otherPoints() const
{
return QhullPointSet(qh_qh, qh_qh->other_points);
}//otherPoints
//! Return vertices of the convex hull.
QhullVertexList Qhull::
vertexList() const{
return QhullVertexList(beginVertex(), endVertex());
}//vertexList
#//!\name Methods
void Qhull::
outputQhull()
{
checkIfQhullInitialized();
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_produce_output2(qh_qh);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}//outputQhull
void Qhull::
outputQhull(const char *outputflags)
{
checkIfQhullInitialized();
string cmd(" "); // qh_checkflags skips first word
cmd += outputflags;
char *command= const_cast<char*>(cmd.c_str());
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_clear_outputflags(qh_qh);
char *s = qh_qh->qhull_command + strlen(qh_qh->qhull_command) + 1; //space
strncat(qh_qh->qhull_command, command, sizeof(qh_qh->qhull_command)-strlen(qh_qh->qhull_command)-1);
qh_checkflags(qh_qh, command, const_cast<char *>(s_not_output_options));
qh_initflags(qh_qh, s);
qh_initqhull_outputflags(qh_qh);
if(qh_qh->KEEPminArea < REALmax/2
|| (0 != qh_qh->KEEParea + qh_qh->KEEPmerge + qh_qh->GOODvertex
+ qh_qh->GOODthreshold + qh_qh->GOODpoint + qh_qh->SPLITthresholds)){
facetT *facet;
qh_qh->ONLYgood= False;
FORALLfacet_(qh_qh->facet_list) {
facet->good= True;
}
qh_prepare_output(qh_qh);
}
qh_produce_output2(qh_qh);
if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
qh_check_points(qh_qh);
}
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}//outputQhull
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
void Qhull::
runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
{
runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
}//runQhull, RboxPoints
//! pointCoordinates is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
//! Derived from qh_new_qhull [user.c]
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
void Qhull::
runQhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand)
{
/* gcc may issue a "might be clobbered" warning for pointDimension and pointCoordinates [-Wclobbered].
These parameters are not referenced after a longjmp() and hence not clobbered.
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
if(run_called){
throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
}
run_called= true;
string s("qhull ");
s += qhullCommand;
char *command= const_cast<char*>(s.c_str());
/************* Expansion of QH_TRY_ for debugging
int QH_TRY_status;
if(qh_qh->NOerrexit){
qh_qh->NOerrexit= False;
QH_TRY_status= setjmp(qh_qh->errexit);
}else{
QH_TRY_status= QH_TRY_ERROR;
}
if(!QH_TRY_status){
*************/
QH_TRY_(qh_qh){ // no object creation -- destructors are skipped on longjmp()
qh_checkflags(qh_qh, command, const_cast<char *>(s_unsupported_options));
qh_initflags(qh_qh, command);
*qh_qh->rbox_command= '\0';
strncat( qh_qh->rbox_command, inputComment, sizeof(qh_qh->rbox_command)-1);
if(qh_qh->DELAUNAY){
qh_qh->PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
}
pointT *newPoints= const_cast<pointT*>(pointCoordinates);
int newDimension= pointDimension;
int newIsMalloc= False;
if(qh_qh->HALFspace){
--newDimension;
initializeFeasiblePoint(newDimension);
newPoints= qh_sethalfspace_all(qh_qh, pointDimension, pointCount, newPoints, qh_qh->feasible_point);
newIsMalloc= True;
}
qh_init_B(qh_qh, newPoints, pointCount, newDimension, newIsMalloc);
qh_qhull(qh_qh);
qh_check_output(qh_qh);
qh_prepare_output(qh_qh);
if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
qh_check_points(qh_qh);
}
}
qh_qh->NOerrexit= true;
for(int k= qh_qh->hull_dim; k--; ){ // Do not move into QH_TRY block. It may throw an error
origin_point << 0.0;
}
// BBS: throw up the error to prevent crash
try {
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
catch (QhullError& e) {
throw e;
}
}//runQhull
#//!\name Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
//! initialize qh.feasible_point for half-space intersection
//! Sets from qh.feasible_string if available, otherwise from Qhull::feasible_point
//! called only once from runQhull(), otherwise it leaks memory (the same as qh_setFeasible)
void Qhull::
initializeFeasiblePoint(int hulldim)
{
if(qh_qh->feasible_string){
qh_setfeasible(qh_qh, hulldim);
}else{
if(feasible_point.isEmpty()){
qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or Qhull::setFeasiblePoint before runQhull()\n");
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
if(feasible_point.size()!=(size_t)hulldim){
qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u", hulldim, feasible_point.size());
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
if (!(qh_qh->feasible_point= (coordT*)qh_malloc(hulldim * sizeof(coordT)))) {
qh_fprintf(qh_qh, qh_qh->ferr, 6202, "qhull error: insufficient memory for feasible point\n");
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
}
coordT *t= qh_qh->feasible_point;
// No qh_... routines after here -- longjmp() ignores destructor
for(Coordinates::ConstIterator p=feasible_point.begin(); p<feasible_point.end(); p++){
*t++= *p;
}
}
}//initializeFeasiblePoint
}//namespace orgQhull

View File

@@ -0,0 +1,132 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.h#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLCPP_H
#define QHULLCPP_H
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullVertex.h"
#include "libqhullcpp/QhullFacet.h"
namespace orgQhull {
/***
Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
#define QHULL_NO_STL
Do not supply conversions to STL
Coordinates.h requires <vector>. It could be rewritten for another vector class such as QList
#define QHULL_USES_QT
Supply conversions to QT
qhulltest requires QT. It is defined in RoadTest.h
#define QHULL_ASSERT
Defined by QhullError.h
It invokes assert()
*/
#//!\name Used here
class QhullFacetList;
class QhullPoints;
class QhullQh;
class RboxPoints;
#//!\name Defined here
class Qhull;
//! Interface to Qhull from C++
class Qhull {
private:
#//!\name Members and friends
QhullQh * qh_qh; //! qhT for this instance
Coordinates origin_point; //! origin for qh_qh->hull_dim. Set by runQhull()
bool run_called; //! True at start of runQhull. Errors if call again.
Coordinates feasible_point; //! feasible point for half-space intersection (alternative to qh.feasible_string for qh.feasible_point)
public:
#//!\name Constructors
Qhull(); //!< call runQhull() next
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
~Qhull() throw();
private: //! Disable copy constructor and assignment. Qhull owns QhullQh.
Qhull(const Qhull &);
Qhull & operator=(const Qhull &);
private:
void allocateQhullQh();
public:
#//!\name GetSet
void checkIfQhullInitialized();
int dimension() const { return qh_qh->input_dim; } //!< Dimension of input and result
void disableOutputStream() { qh_qh->disableOutputStream(); }
void enableOutputStream() { qh_qh->enableOutputStream(); }
countT facetCount() const { return qh_qh->num_facets; }
Coordinates feasiblePoint() const;
int hullDimension() const { return qh_qh->hull_dim; } //!< Dimension of the computed hull
bool hasOutputStream() const { return qh_qh->hasOutputStream(); }
bool initialized() const { return (qh_qh->hull_dim>0); }
const char * inputComment() const { return qh_qh->rbox_command; }
QhullPoint inputOrigin();
//! non-const due to QhullPoint
QhullPoint origin() { QHULL_ASSERT(initialized()); return QhullPoint(qh_qh, origin_point.data()); }
QhullQh * qh() const { return qh_qh; };
const char * qhullCommand() const { return qh_qh->qhull_command; }
const char * rboxCommand() const { return qh_qh->rbox_command; }
int rotateRandom() const { return qh_qh->ROTATErandom; } //!< Return QRn for repeating QR0 runs
void setFeasiblePoint(const Coordinates &c) { feasible_point= c; } //!< Sets qh.feasible_point via initializeFeasiblePoint
countT vertexCount() const { return qh_qh->num_vertices; }
#//!\name Delegated to QhullQh
double angleEpsilon() const { return qh_qh->angleEpsilon(); } //!< Epsilon for hyperplane angle equality
void appendQhullMessage(const std::string &s) { qh_qh->appendQhullMessage(s); }
void clearQhullMessage() { qh_qh->clearQhullMessage(); }
double distanceEpsilon() const { return qh_qh->distanceEpsilon(); } //!< Epsilon for distance to hyperplane
double factorEpsilon() const { return qh_qh->factorEpsilon(); } //!< Factor for angleEpsilon and distanceEpsilon
std::string qhullMessage() const { return qh_qh->qhullMessage(); }
bool hasQhullMessage() const { return qh_qh->hasQhullMessage(); }
int qhullStatus() const { return qh_qh->qhullStatus(); }
void setErrorStream(std::ostream *os) { qh_qh->setErrorStream(os); }
void setFactorEpsilon(double a) { qh_qh->setFactorEpsilon(a); }
void setOutputStream(std::ostream *os) { qh_qh->setOutputStream(os); }
#//!\name ForEach
QhullFacet beginFacet() const { return QhullFacet(qh_qh, qh_qh->facet_list); }
QhullVertex beginVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_list); }
void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
QhullFacet endFacet() const { return QhullFacet(qh_qh, qh_qh->facet_tail); }
QhullVertex endVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_tail); }
QhullFacetList facetList() const;
QhullFacet firstFacet() const { return beginFacet(); }
QhullVertex firstVertex() const { return beginVertex(); }
QhullPoints points() const;
QhullPointSet otherPoints() const;
//! Same as points().coordinates()
coordT * pointCoordinateBegin() const { return qh_qh->first_point; }
coordT * pointCoordinateEnd() const { return qh_qh->first_point + qh_qh->num_points*qh_qh->hull_dim; }
QhullVertexList vertexList() const;
#//!\name Methods
double area();
void outputQhull();
void outputQhull(const char * outputflags);
void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
void runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
double volume();
#//!\name Helpers
private:
void initializeFeasiblePoint(int hulldim);
};//Qhull
}//namespace orgQhull
#endif // QHULLCPP_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullError.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLERROR_H
#define QHULLERROR_H
#include "libqhullcpp/RoadError.h"
// No dependencies on libqhull
#ifndef QHULL_ASSERT
#define QHULL_ASSERT assert
#include <assert.h>
#endif
namespace orgQhull {
#//!\name Defined here
//! QhullError -- std::exception class for Qhull
class QhullError;
class QhullError : public RoadError {
public:
#//!\name Constants
enum {
QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
QHULLlastError= 10078,
NOthrow= 1 //! For flag to indexOf()
};
#//!\name Constructors
// default constructors
QhullError() : RoadError() {};
QhullError(const QhullError &other) : RoadError(other) {}
QhullError(int code, const std::string &message) : RoadError(code, message) {};
QhullError(int code, const char *fmt) : RoadError(code, fmt) {};
QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {};
QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {};
QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {};
QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {};
QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {};
QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {};
QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {};
QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {};
QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
~QhullError() throw() {}
};//class QhullError
}//namespace orgQhull
#//!\name Global
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
#endif // QHULLERROR_H

View File

@@ -0,0 +1,519 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullError.h"
#include "libqhullcpp/Qhull.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullPointSet.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullFacetSet.h"
#include "libqhullcpp/QhullVertex.h"
#include <ostream>
using std::endl;
using std::ostream;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//!\name Class objects
facetT QhullFacet::
s_empty_facet= {0,0,0,0,{0},
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0};
#//!\name Constructors
QhullFacet::
QhullFacet(const Qhull &q)
: qh_facet(&s_empty_facet)
, qh_qh(q.qh())
{
}
QhullFacet::
QhullFacet(const Qhull &q, facetT *f)
: qh_facet(f ? f : &s_empty_facet)
, qh_qh(q.qh())
{
}
#//!\name GetSet
//! Return voronoi center or facet centrum. Derived from qh_printcenter [io_r.c]
//! if printFormat=qh_PRINTtriangles and qh.DELAUNAY, returns centrum of a Delaunay facet
//! Sets center if needed
//! Code duplicated for PrintCenter and getCenter
//! Returns QhullPoint() if none or qh_INFINITE
QhullPoint QhullFacet::
getCenter(qh_PRINT printFormat)
{
if(!qh_qh){
// returns QhullPoint()
}else if(qh_qh->CENTERtype==qh_ASvoronoi){
if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh_qh->ATinfinity){
if(!qh_facet->center){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_facetcenter(qh_qh, qh_facet->vertices);
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return QhullPoint(qh_qh, qh_qh->hull_dim-1, qh_facet->center);
}
}else if(qh_qh->CENTERtype==qh_AScentrum){
volatile int numCoords= qh_qh->hull_dim;
if(printFormat==qh_PRINTtriangles && qh_qh->DELAUNAY){
numCoords--;
}
if(!qh_facet->center){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->center= qh_getcentrum(qh_qh, getFacetT());
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return QhullPoint(qh_qh, numCoords, qh_facet->center);
}
return QhullPoint();
}//getCenter
//! Return innerplane clearly below the vertices
//! from io_r.c[qh_PRINTinner]
QhullHyperplane QhullFacet::
innerplane() const{
QhullHyperplane h;
if(qh_qh){
realT inner;
// Does not error, TRY_QHULL_ not needed
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), NULL, &inner);
h= hyperplane();
h.setOffset(h.offset()-inner); //inner is negative
}
return h;
}//innerplane
//! Return outerplane clearly above all points
//! from io_r.c[qh_PRINTouter]
QhullHyperplane QhullFacet::
outerplane() const{
QhullHyperplane h;
if(qh_qh){
realT outer;
// Does not error, TRY_QHULL_ not needed
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), &outer, NULL);
h= hyperplane();
h.setOffset(h.offset()-outer); //outer is positive
}
return h;
}//outerplane
//! Set by qh_triangulate for option 'Qt'.
//! Errors if tricoplanar and facetArea() or qh_getarea() called first.
QhullFacet QhullFacet::
tricoplanarOwner() const
{
if(qh_facet->tricoplanar){
if(qh_facet->isarea){
throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called. triCoplanarOwner() is not available.");
}
return QhullFacet(qh_qh, qh_facet->f.triowner);
}
return QhullFacet(qh_qh);
}//tricoplanarOwner
QhullPoint QhullFacet::
voronoiVertex()
{
if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
}
return getCenter();
}//voronoiVertex
#//!\name Value
//! Disables tricoplanarOwner()
double QhullFacet::
facetArea()
{
if(qh_qh && !qh_facet->isarea){
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
qh_facet->f.area= qh_facetarea(qh_qh, qh_facet);
qh_facet->isarea= True;
}
qh_qh->NOerrexit= true;
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
}
return qh_facet->f.area;
}//facetArea
#//!\name Foreach
QhullPointSet QhullFacet::
coplanarPoints() const
{
return QhullPointSet(qh_qh, qh_facet->coplanarset);
}//coplanarPoints
QhullFacetSet QhullFacet::
neighborFacets() const
{
return QhullFacetSet(qh_qh, qh_facet->neighbors);
}//neighborFacets
QhullPointSet QhullFacet::
outsidePoints() const
{
return QhullPointSet(qh_qh, qh_facet->outsideset);
}//outsidePoints
QhullRidgeSet QhullFacet::
ridges() const
{
return QhullRidgeSet(qh_qh, qh_facet->ridges);
}//ridges
QhullVertexSet QhullFacet::
vertices() const
{
return QhullVertexSet(qh_qh, qh_facet->vertices);
}//vertices
}//namespace orgQhull
#//!\name operator<<
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetSet;
using orgQhull::QhullPoint;
using orgQhull::QhullPointSet;
using orgQhull::QhullRidge;
using orgQhull::QhullRidgeSet;
using orgQhull::QhullSetBase;
using orgQhull::QhullVertexSet;
ostream &
operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
{
os << pr.message;
QhullFacet f= *pr.facet;
if(f.getFacetT()==0){ // Special values from set iterator
os << " NULLfacet" << endl;
return os;
}
if(f.getFacetT()==qh_MERGEridge){
os << " MERGEridge" << endl;
return os;
}
if(f.getFacetT()==qh_DUPLICATEridge){
os << " DUPLICATEridge" << endl;
return os;
}
os << f.printHeader();
if(!f.ridges().isEmpty()){
os << f.printRidges();
}
return os;
}//operator<< PrintFacet
//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [_r.]
//! Code duplicated for PrintCenter and getCenter
//! Sets center if needed
ostream &
operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
{
facetT *f= pr.facet->getFacetT();
if(pr.facet->qh()->CENTERtype!=qh_ASvoronoi && pr.facet->qh()->CENTERtype!=qh_AScentrum){
return os;
}
if (pr.message){
os << pr.message;
}
int numCoords;
if(pr.facet->qh()->CENTERtype==qh_ASvoronoi){
numCoords= pr.facet->qh()->hull_dim-1;
if(!f->normal || !f->upperdelaunay || !pr.facet->qh()->ATinfinity){
if(!f->center){
f->center= qh_facetcenter(pr.facet->qh(), f->vertices);
}
for(int k=0; k<numCoords; k++){
os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
}
}else{
for(int k=0; k<numCoords; k++){
os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
}
}
}else{ // qh CENTERtype==qh_AScentrum
numCoords= pr.facet->qh()->hull_dim;
if(pr.print_format==qh_PRINTtriangles && pr.facet->qh()->DELAUNAY){
numCoords--;
}
if(!f->center){
f->center= qh_getcentrum(pr.facet->qh(), f);
}
for(int k=0; k<numCoords; k++){
os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
}
}
if(pr.print_format==qh_PRINTgeom && numCoords==2){
os << " 0";
}
os << endl;
return os;
}//operator<< PrintCenter
//! Print flags for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacet::PrintFlags &p)
{
const facetT *f= p.facet->getFacetT();
if(p.message){
os << p.message;
}
os << (p.facet->isTopOrient() ? " top" : " bottom");
if(p.facet->isSimplicial()){
os << " simplicial";
}
if(p.facet->isTriCoplanar()){
os << " tricoplanar";
}
if(p.facet->isUpperDelaunay()){
os << " upperDelaunay";
}
if(f->visible){
os << " visible";
}
if(f->newfacet){
os << " new";
}
if(f->tested){
os << " tested";
}
if(!f->good){
os << " notG";
}
if(f->seen){
os << " seen";
}
if(f->coplanar){
os << " coplanar";
}
if(f->mergehorizon){
os << " mergehorizon";
}
if(f->keepcentrum){
os << " keepcentrum";
}
if(f->dupridge){
os << " dupridge";
}
if(f->mergeridge && !f->mergeridge2){
os << " mergeridge1";
}
if(f->mergeridge2){
os << " mergeridge2";
}
if(f->newmerge){
os << " newmerge";
}
if(f->flipped){
os << " flipped";
}
if(f->notfurthest){
os << " notfurthest";
}
if(f->degenerate){
os << " degenerate";
}
if(f->redundant){
os << " redundant";
}
os << endl;
return os;
}//operator<< PrintFlags
//! Print header for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
{
QhullFacet facet= *pr.facet;
facetT *f= facet.getFacetT();
os << "- f" << facet.id() << endl;
os << facet.printFlags(" - flags:");
if(f->isarea){
os << " - area: " << f->f.area << endl; //FIXUP QH11010 2.2g
}else if(pr.facet->qh()->NEWfacets && f->visible && f->f.replace){
os << " - replacement: f" << f->f.replace->id << endl;
}else if(f->newfacet){
if(f->f.samecycle && f->f.samecycle != f){
os << " - shares same visible/horizon as f" << f->f.samecycle->id << endl;
}
}else if(f->tricoplanar /* !isarea */){
if(f->f.triowner){
os << " - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
}
}else if(f->f.newcycle){
os << " - was horizon to f" << f->f.newcycle->id << endl;
}
if(f->nummerge){
os << " - merges: " << f->nummerge << endl;
}
os << facet.hyperplane().print(" - normal: ", "\n - offset: "); // FIXUP QH11010 %10.7g
if(pr.facet->qh()->CENTERtype==qh_ASvoronoi || f->center){
os << facet.printCenter(qh_PRINTfacets, " - center: ");
}
#if qh_MAXoutside
if(f->maxoutside > pr.facet->qh()->DISTround){
os << " - maxoutside: " << f->maxoutside << endl; //FIXUP QH11010 %10.7g
}
#endif
QhullPointSet ps= facet.outsidePoints();
if(!ps.isEmpty()){
QhullPoint furthest= ps.last();
if (ps.size() < 6) {
os << " - outside set(furthest p" << furthest.id() << "):" << endl;
for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
QhullPoint p= *i;
os << p.print(" ");
}
}else if(ps.size()<21){
os << ps.print(" - outside set:");
}else{
os << " - outside set: " << ps.size() << " points.";
os << furthest.print(" Furthest");
}
#if !qh_COMPUTEfurthest
os << " - furthest distance= " << f->furthestdist << endl; //FIXUP QH11010 %2.2g
#endif
}
QhullPointSet cs= facet.coplanarPoints();
if(!cs.isEmpty()){
QhullPoint furthest= cs.last();
if (cs.size() < 6) {
os << " - coplanar set(furthest p" << furthest.id() << "):" << endl;
for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
QhullPoint p= *i;
os << p.print(" ");
}
}else if(cs.size()<21){
os << cs.print(" - coplanar set:");
}else{
os << " - coplanar set: " << cs.size() << " points.";
os << furthest.print(" Furthest");
}
// FIXUP QH11027 Can/should zinc_(Zdistio) be called from C++ interface
double d= facet.distance(furthest);
os << " furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
}
QhullVertexSet vs= facet.vertices();
if(!vs.isEmpty()){
os << vs.print(" - vertices:");
}
QhullFacetSet fs= facet.neighborFacets();
fs.selectAll();
if(!fs.isEmpty()){
os << fs.printIdentifiers(" - neighboring facets:");
}
return os;
}//operator<< PrintHeader
//! Print ridges of facet to stream. Same as qh_printfacetridges [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
{
const QhullFacet facet= *pr.facet;
facetT *f= facet.getFacetT();
QhullRidgeSet rs= facet.ridges();
if(!rs.isEmpty()){
if(f->visible && pr.facet->qh()->NEWfacets){
os << " - ridges(ids may be garbage):";
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
os << " r" << r.id();
}
os << endl;
}else{
os << " - ridges:" << endl;
}
// Keep track of printed ridges
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
r.getRidgeT()->seen= false;
}
int ridgeCount= 0;
if(facet.dimension()==3){
for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
r.getRidgeT()->seen= true;
os << r.print("");
++ridgeCount;
if(!r.hasNextRidge3d(facet)){
break;
}
}
}else {
QhullFacetSet ns(facet.neighborFacets());
for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
QhullFacet neighbor= *i;
QhullRidgeSet nrs(neighbor.ridges());
for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
QhullRidge r= *j;
if(r.otherFacet(neighbor)==facet){
r.getRidgeT()->seen= true;
os << r.print("");
ridgeCount++;
}
}
}
}
if(ridgeCount!=rs.count()){
os << " - all ridges:";
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
os << " r" << r.id();
}
os << endl;
}
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
QhullRidge r= *i;
if(!r.getRidgeT()->seen){
os << r.print("");
}
}
}
return os;
}//operator<< PrintRidges
// "No conversion" error if defined inline
ostream &
operator<<(ostream &os, QhullFacet &f)
{
os << f.print("");
return os;
}//<< QhullFacet

View File

@@ -0,0 +1,151 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.h#4 $$Change: 2079 $
** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACET_H
#define QHULLFACET_H
#include "libqhull_r/qhull_ra.h"
#include "libqhullcpp/QhullHyperplane.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullSet.h"
#include "libqhullcpp/QhullPointSet.h"
#include <ostream>
namespace orgQhull {
#//!\name Used here
class Coordinates;
class Qhull;
class QhullFacetSet;
class QhullRidge;
class QhullVertex;
class QhullVertexSet;
#//!\name Defined here
class QhullFacet;
typedef QhullSet<QhullRidge> QhullRidgeSet;
//! A QhullFacet is the C++ equivalent to Qhull's facetT*
class QhullFacet {
#//!\name Defined here
public:
typedef facetT * base_type; // for QhullVertexSet
private:
#//!\name Fields -- no additions (QhullFacetSet of facetT*)
facetT * qh_facet; //!< Corresponding facetT, may be 0 for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
QhullQh * qh_qh; //!< QhullQh/qhT for facetT, may be 0
#//!\name Class objects
static facetT s_empty_facet; // needed for shallow copy
public:
#//!\name Constructors
QhullFacet() : qh_facet(&s_empty_facet), qh_qh(0) {}
explicit QhullFacet(const Qhull &q);
QhullFacet(const Qhull &q, facetT *f);
explicit QhullFacet(QhullQh *qqh) : qh_facet(&s_empty_facet), qh_qh(qqh) {}
QhullFacet(QhullQh *qqh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qqh) {}
// Creates an alias. Does not copy QhullFacet. Needed for return by value and parameter passing
QhullFacet(const QhullFacet &other) : qh_facet(other.qh_facet ? other.qh_facet : &s_empty_facet), qh_qh(other.qh_qh) {}
// Creates an alias. Does not copy QhullFacet. Needed for vector<QhullFacet>
QhullFacet & operator=(const QhullFacet &other) { qh_facet= other.qh_facet ? other.qh_facet : &s_empty_facet; qh_qh= other.qh_qh; return *this; }
~QhullFacet() {}
#//!\name GetSet
int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
QhullPoint getCenter() { return getCenter(qh_PRINTpoints); }
QhullPoint getCenter(qh_PRINT printFormat);
facetT * getBaseT() const { return getFacetT(); } //!< For QhullSet<QhullFacet>
// Do not define facetT(). It conflicts with return type facetT*
facetT * getFacetT() const { return qh_facet; }
QhullHyperplane hyperplane() const { return QhullHyperplane(qh_qh, dimension(), qh_facet->normal, qh_facet->offset); }
countT id() const { return (qh_facet ? qh_facet->id : (int)qh_IDunknown); }
QhullHyperplane innerplane() const;
bool isValid() const { return qh_qh && qh_facet && qh_facet != &s_empty_facet; }
bool isGood() const { return qh_facet && qh_facet->good; }
bool isSimplicial() const { return qh_facet && qh_facet->simplicial; }
bool isTopOrient() const { return qh_facet && qh_facet->toporient; }
bool isTriCoplanar() const { return qh_facet && qh_facet->tricoplanar; }
bool isUpperDelaunay() const { return qh_facet && qh_facet->upperdelaunay; }
QhullFacet next() const { return QhullFacet(qh_qh, qh_facet->next); }
bool operator==(const QhullFacet &other) const { return qh_facet==other.qh_facet; }
bool operator!=(const QhullFacet &other) const { return !operator==(other); }
QhullHyperplane outerplane() const;
QhullFacet previous() const { return QhullFacet(qh_qh, qh_facet->previous); }
QhullQh * qh() const { return qh_qh; }
QhullFacet tricoplanarOwner() const;
QhullPoint voronoiVertex();
#//!\name value
//! Undefined if c.size() != dimension()
double distance(const Coordinates &c) const { return distance(c.data()); }
double distance(const pointT *p) const { return distance(QhullPoint(qh_qh, const_cast<coordT *>(p))); }
double distance(const QhullPoint &p) const { return hyperplane().distance(p); }
double facetArea();
#//!\name foreach
// Can not inline. Otherwise circular reference
QhullPointSet coplanarPoints() const;
QhullFacetSet neighborFacets() const;
QhullPointSet outsidePoints() const;
QhullRidgeSet ridges() const;
QhullVertexSet vertices() const;
#//!\name IO
struct PrintCenter{
QhullFacet * facet; // non-const due to facet.center()
const char * message;
qh_PRINT print_format;
PrintCenter(QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), print_format(printFormat){}
};//PrintCenter
PrintCenter printCenter(qh_PRINT printFormat, const char *message) { return PrintCenter(*this, printFormat, message); }
struct PrintFacet{
QhullFacet * facet; // non-const due to f->center()
const char * message;
explicit PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
};//PrintFacet
PrintFacet print(const char *message) { return PrintFacet(*this, message); }
struct PrintFlags{
const QhullFacet *facet;
const char * message;
PrintFlags(const QhullFacet &f, const char *s) : facet(&f), message(s) {}
};//PrintFlags
PrintFlags printFlags(const char *message) const { return PrintFlags(*this, message); }
struct PrintHeader{
QhullFacet * facet; // non-const due to f->center()
PrintHeader(QhullFacet &f) : facet(&f) {}
};//PrintHeader
PrintHeader printHeader() { return PrintHeader(*this); }
struct PrintRidges{
const QhullFacet *facet;
PrintRidges(QhullFacet &f) : facet(&f) {}
};//PrintRidges
PrintRidges printRidges() { return PrintRidges(*this); }
};//class QhullFacet
}//namespace orgQhull
#//!\name Global
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFacet &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintCenter &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFlags &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintHeader &pr);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintRidges &pr);
std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
#endif // QHULLFACET_H

View File

@@ -0,0 +1,174 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.cpp#3 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacetList -- Qhull's linked facets, as a C++ class
#include "libqhullcpp/QhullFacetList.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullVertex.h"
using std::string;
using std::vector;
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//!\name Constructors
QhullFacetList::
QhullFacetList(const Qhull &q, facetT *b, facetT *e )
: QhullLinkedList<QhullFacet>(QhullFacet(q, b), QhullFacet(q, e))
, select_all(false)
{
}
#//!\name Conversions
// See qt_qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<QhullFacet> QhullFacetList::
toStdVector() const
{
QhullLinkedListIterator<QhullFacet> i(*this);
std::vector<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.push_back(f);
}
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#ifndef QHULL_NO_STL
//! Same as PrintVertices
std::vector<QhullVertex> QhullFacetList::
vertices_toStdVector() const
{
std::vector<QhullVertex> vs;
QhullVertexSet qvs(qh(), first().getFacetT(), 0, isSelectAll());
for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
vs.push_back(*i);
}
return vs;
}//vertices_toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
bool QhullFacetList::
contains(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::contains(facet);
}
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
return true;
}
}
return false;
}//contains
int QhullFacetList::
count() const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::count();
}
int counter= 0;
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
if((*i).isGood()){
counter++;
}
}
return counter;
}//count
int QhullFacetList::
count(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullLinkedList<QhullFacet>::count(facet);
}
int counter= 0;
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
counter++;
}
}
return counter;
}//count
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetList;
using orgQhull::QhullVertex;
using orgQhull::QhullVertexSet;
ostream &
operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
{
os << pr.print_message;
QhullFacetList fs= *pr.facet_list;
os << "Vertices for " << fs.count() << " facets" << endl;
os << fs.printVertices();
os << fs.printFacets();
return os;
}//operator<<
//! Print facet list to stream. From qh_printafacet [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacetList::PrintFacets &pr)
{
for(QhullFacetList::const_iterator i= pr.facet_list->begin(); i != pr.facet_list->end(); ++i){
QhullFacet f= *i;
if(pr.facet_list->isSelectAll() || f.isGood()){
os << f.print("");
}
}
return os;
}//printFacets
//! Print vertices of good faces in facet list to stream. From qh_printvertexlist [io_r.c]
//! Same as vertices_toStdVector
ostream &
operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
{
QhullVertexSet vs(pr.facet_list->qh(), pr.facet_list->first().getFacetT(), NULL, pr.facet_list->isSelectAll());
for(QhullVertexSet::iterator i=vs.begin(); i!=vs.end(); ++i){
QhullVertex v= *i;
os << v.print("");
}
return os;
}//printVertices
std::ostream &
operator<<(ostream &os, const QhullFacetList &fs)
{
os << fs.printFacets();
return os;
}//QhullFacetList

View File

@@ -0,0 +1,106 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.h#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#ifndef QHULLFACETLIST_H
#define QHULLFACETLIST_H
#include "libqhullcpp/QhullLinkedList.h"
#include "libqhullcpp/QhullFacet.h"
#include <ostream>
#ifndef QHULL_NO_STL
#include <vector>
#endif
namespace orgQhull {
#//!\name Used here
class Qhull;
class QhullFacet;
class QhullQh;
#//!\name Defined here
//! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.
//!\see QhullFacetSet.h
class QhullFacetList;
//! QhullFacetListIterator -- if(f.isGood()){ ... }
typedef QhullLinkedListIterator<QhullFacet> QhullFacetListIterator;
class QhullFacetList : public QhullLinkedList<QhullFacet> {
#//!\name Fields
private:
bool select_all; //! True if include bad facets. Default is false.
#//!\name Constructors
public:
QhullFacetList(const Qhull &q, facetT *b, facetT *e);
QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(b, e), select_all(false) {}
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
QhullFacetList(const QhullFacetList &other) : QhullLinkedList<QhullFacet>(*other.begin(), *other.end()), select_all(other.select_all) {}
QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::operator =(other); select_all= other.select_all; return *this; }
~QhullFacetList() {}
private: //!Disable default constructor. See QhullLinkedList
QhullFacetList();
public:
#//!\name Conversion
#ifndef QHULL_NO_STL
std::vector<QhullFacet> toStdVector() const;
std::vector<QhullVertex> vertices_toStdVector() const;
#endif //QHULL_NO_STL
#ifdef QHULL_USES_QT
QList<QhullFacet> toQList() const;
QList<QhullVertex> vertices_toQList() const;
#endif //QHULL_USES_QT
#//!\name GetSet
//! Filtered by facet.isGood(). May be 0 when !isEmpty().
countT count() const;
bool contains(const QhullFacet &f) const;
countT count(const QhullFacet &f) const;
bool isSelectAll() const { return select_all; }
QhullQh * qh() const { return first().qh(); }
void selectAll() { select_all= true; }
void selectGood() { select_all= false; }
//!< operator==() does not depend on isGood()
#//!\name IO
struct PrintFacetList{
const QhullFacetList *facet_list;
const char * print_message; //!< non-null message
PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
};//PrintFacetList
PrintFacetList print(const char *message) const { return PrintFacetList(*this, message); }
struct PrintFacets{
const QhullFacetList *facet_list;
PrintFacets(const QhullFacetList &fl) : facet_list(&fl) {}
};//PrintFacets
PrintFacets printFacets() const { return PrintFacets(*this); }
struct PrintVertices{
const QhullFacetList *facet_list;
PrintVertices(const QhullFacetList &fl) : facet_list(&fl) {}
};//PrintVertices
PrintVertices printVertices() const { return PrintVertices(*this); }
};//class QhullFacetList
}//namespace orgQhull
#//!\name == Global namespace =========================================
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacetList &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacets &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintVertices &p);
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs);
#endif // QHULLFACETLIST_H

View File

@@ -0,0 +1,147 @@
/****************************************************************************
**
** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.cpp#2 $$Change: 2066 $
** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
**
****************************************************************************/
#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
#include "libqhullcpp/QhullFacetSet.h"
#include "libqhullcpp/QhullFacet.h"
#include "libqhullcpp/QhullPoint.h"
#include "libqhullcpp/QhullRidge.h"
#include "libqhullcpp/QhullVertex.h"
#ifndef QHULL_NO_STL
using std::vector;
#endif
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
#endif
namespace orgQhull {
#//!\name Conversions
// See qt-qhull.cpp for QList conversions
#ifndef QHULL_NO_STL
std::vector<QhullFacet> QhullFacetSet::
toStdVector() const
{
QhullSetIterator<QhullFacet> i(*this);
std::vector<QhullFacet> vs;
while(i.hasNext()){
QhullFacet f= i.next();
if(isSelectAll() || f.isGood()){
vs.push_back(f);
}
}
return vs;
}//toStdVector
#endif //QHULL_NO_STL
#//!\name GetSet
bool QhullFacetSet::
contains(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::contains(facet);
}
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
return true;
}
}
return false;
}//contains
int QhullFacetSet::
count() const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::count();
}
int counter= 0;
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f.isGood()){
counter++;
}
}
return counter;
}//count
int QhullFacetSet::
count(const QhullFacet &facet) const
{
if(isSelectAll()){
return QhullSet<QhullFacet>::count(facet);
}
int counter= 0;
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
QhullFacet f= *i;
if(f==facet && f.isGood()){
counter++;
}
}
return counter;
}//count
}//namespace orgQhull
#//!\name Global functions
using std::endl;
using std::ostream;
using orgQhull::QhullFacet;
using orgQhull::QhullFacetSet;
ostream &
operator<<(ostream &os, const QhullFacetSet &fs)
{
os << fs.print("");
return os;
}//<<QhullFacetSet
ostream &
operator<<(ostream &os, const QhullFacetSet::PrintFacetSet &pr)
{
os << pr.print_message;
QhullFacetSet fs= *pr.facet_set;
for(QhullFacetSet::iterator i=fs.begin(); i != fs.end(); ++i){
QhullFacet f= *i;
if(fs.isSelectAll() || f.isGood()){
os << f;
}
}
return os;
}//<< QhullFacetSet::PrintFacetSet
//! Print facet identifiers to stream. Space prefix. From qh_printfacetheader [io_r.c]
ostream &
operator<<(ostream &os, const QhullFacetSet::PrintIdentifiers &p)
{
os << p.print_message;
for(QhullFacetSet::const_iterator i=p.facet_set->begin(); i!=p.facet_set->end(); ++i){
const QhullFacet f= *i;
if(f.getFacetT()==qh_MERGEridge){
os << " MERGE";
}else if(f.getFacetT()==qh_DUPLICATEridge){
os << " DUP";
}else if(p.facet_set->isSelectAll() || f.isGood()){
os << " f" << f.id();
}
}
os << endl;
return os;
}//<<QhullFacetSet::PrintIdentifiers

Some files were not shown because too many files have changed in this diff Show More