mirror of https://github.com/lammps/lammps.git
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@641 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
b78e208740
commit
988a4479e8
|
@ -0,0 +1,21 @@
|
|||
asphere_vis: Tool for triangulating aspherical particles
|
||||
to convert LAMMPS output to PyMol input
|
||||
|
||||
Building the tool:
|
||||
|
||||
cd src
|
||||
make # may need to edit Makefile for your system
|
||||
|
||||
This will place the asphere_vis executable in the bin directory.
|
||||
|
||||
Documentation is in the doc directory. Note that the doc file says
|
||||
the ellipsoid axes are specified by an "Ellipsoid" section in the data
|
||||
file. In the current version of LAMPS, this is now a "Shapes"
|
||||
section.
|
||||
|
||||
See instructions on how to run an example ellipsoid viz in the
|
||||
examples dir.
|
||||
|
||||
Mike Brown, Sandia National Labs
|
||||
wmbrown at sandia.gov
|
||||
June 2007
|
|
@ -0,0 +1,209 @@
|
|||
.if !'\*(.T'ps' .if !'\*(.T'html' .tm warning: eqn should have been given a `-T\*(.T' option
|
||||
.if '\*(.T'html' .if !'ps'ps' .tm warning: eqn should have been given a `-Tps' option
|
||||
.if '\*(.T'html' .if !'ps'ps' .tm warning: (it is advisable to invoke groff via: groff -Thtml -e)
|
||||
.lf 1 /usr/share/groff/1.18.1.1/tmac/eqnrc
|
||||
.\" Startup file for eqn.
|
||||
.EQ
|
||||
.nr 0C \n(.C
|
||||
.cp 0
|
||||
.ds 10
|
||||
.cp \n(0C
|
||||
.lf 63
|
||||
.EN
|
||||
.lf 1 asphere_vis.manpage
|
||||
.TH asphere_vis 1 "June 11, 2007" "asphere_vis (Graphics Utilities) 0.1" "Graphics Utilities"
|
||||
.SH NAME
|
||||
\fBasphere_vis\fR - Tools for LAMMPS ellipsoid trajectory visualization in PyMol.
|
||||
.PD 2
|
||||
.SH VERSION
|
||||
.PD 1
|
||||
Version 0.1
|
||||
.PD 2
|
||||
.SH SYNOPSIS
|
||||
.PD 1
|
||||
.TP
|
||||
\fBasphere_vis\fR input_data_file input_dump_file output_py_file [\fB-b\fR] [\fB-c\fR \fIcolor_file\fR] [\fB-d\fR] [\fB-f\fR \fImax_frame\fR] [\fB-h\fR] [\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR] [\fB-n\fR \fInotice_level\fR] [\fB-r\fR \fIellip_res\fR] [\fB-s\fR]
|
||||
.br
|
||||
.PD 2
|
||||
.SH DESCRIPTION
|
||||
.PD 1
|
||||
Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS 'data' file or a 'in' file with ellipsoid semi-axes specified using the ellipsoid command. The trajectory is input from a 'dump' file that must be generated using a custom style with the following arguments in order:
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
\fItag type x y z quatw quati quatj quatk\fR
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 2
|
||||
.SH PARAMETERS
|
||||
.PD 1
|
||||
.TP
|
||||
\fB-b\fR
|
||||
When used with \fB-s\fR, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.
|
||||
.TP
|
||||
\fB-c\fR \fIcolor_file\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.
|
||||
.TP
|
||||
\fB-d\fR
|
||||
Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as \fIinput_data_file\fR.
|
||||
.TP
|
||||
\fB-f\fR \fImax_frame\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Do not write more than \fImax_frame\fR frames to the output file.
|
||||
.TP
|
||||
\fB-h\fR
|
||||
Print out the man page for help
|
||||
.TP
|
||||
\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Render the specified frame interval inclusive between \fIstart_frame\fR and \fIend_frame\fR. \fIskip\fR gives the number of frames to \fIskip\fR between each rendered frame. A value of 0 outputs every frame between \fIstart_frame\fR and \fIend_frame\fR. The first frame in the dump file is frame 0.
|
||||
.TP
|
||||
\fB-n\fR \fInotice_level\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Set the degree of program output. Use:
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 0 No output
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 10 Normal program output
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 20 Parameters useful for reproducing the results
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 30 All output
|
||||
.TP
|
||||
\fB-r\fR \fIellip_res\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(\fIellip_res\fR^2). Default is 10.
|
||||
.TP
|
||||
\fB-s\fR
|
||||
Output the results into separate .py files. The filename and extension for the output files is taken from \fIoutput_py_file\fR.
|
||||
.PD 2
|
||||
.SH AVAILABLE COLORS
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
black
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
blue
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
brown
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
cmyk_blue
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
cmyk_marine
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
deep
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
forest
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
green
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
grey
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
hotpink
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
magenta
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
marine
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
orange
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
purple
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
red
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
slate
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
teal
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
wheat
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
white
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
yellow
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 2
|
||||
.SH KNOWN BUGS
|
||||
.PD 1
|
||||
Comments are not allowed at any point between a section header and the end of the contents for a section in either the data file or the input file.
|
||||
.PD 2
|
||||
.SH AUTHORS
|
||||
.PD 1
|
||||
W. Michael Brown
|
|
@ -0,0 +1,196 @@
|
|||
.TH asphere_vis 1 "June 11, 2007" "asphere_vis (Graphics Utilities) 0.1" "Graphics Utilities"
|
||||
.SH NAME
|
||||
\fBasphere_vis\fR - Tools for LAMMPS ellipsoid trajectory visualization in PyMol.
|
||||
.PD 2
|
||||
.SH VERSION
|
||||
.PD 1
|
||||
Version 0.1
|
||||
.PD 2
|
||||
.SH SYNOPSIS
|
||||
.PD 1
|
||||
.TP
|
||||
\fBasphere_vis\fR input_data_file input_dump_file output_py_file [\fB-b\fR] [\fB-c\fR \fIcolor_file\fR] [\fB-d\fR] [\fB-f\fR \fImax_frame\fR] [\fB-h\fR] [\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR] [\fB-n\fR \fInotice_level\fR] [\fB-r\fR \fIellip_res\fR] [\fB-s\fR]
|
||||
.br
|
||||
.PD 2
|
||||
.SH DESCRIPTION
|
||||
.PD 1
|
||||
Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS 'data' file or a 'in' file with ellipsoid semi-axes specified using the ellipsoid command. The trajectory is input from a 'dump' file that must be generated using a custom style with the following arguments in order:
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
\fItag type x y z quatw quati quatj quatk\fR
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 2
|
||||
.SH PARAMETERS
|
||||
.PD 1
|
||||
.TP
|
||||
\fB-b\fR
|
||||
When used with \fB-s\fR, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.
|
||||
.TP
|
||||
\fB-c\fR \fIcolor_file\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.
|
||||
.TP
|
||||
\fB-d\fR
|
||||
Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as \fIinput_data_file\fR.
|
||||
.TP
|
||||
\fB-f\fR \fImax_frame\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Do not write more than \fImax_frame\fR frames to the output file.
|
||||
.TP
|
||||
\fB-h\fR
|
||||
Print out the man page for help
|
||||
.TP
|
||||
\fB-i\fR \fIstart_frame\fR \fIskip\fR \fIend_frame\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Render the specified frame interval inclusive between \fIstart_frame\fR and \fIend_frame\fR. \fIskip\fR gives the number of frames to \fIskip\fR between each rendered frame. A value of 0 outputs every frame between \fIstart_frame\fR and \fIend_frame\fR. The first frame in the dump file is frame 0.
|
||||
.TP
|
||||
\fB-n\fR \fInotice_level\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Set the degree of program output. Use:
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 0 No output
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 10 Normal program output
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 20 Parameters useful for reproducing the results
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
\fB-n\fR 30 All output
|
||||
.TP
|
||||
\fB-r\fR \fIellip_res\fR
|
||||
.PD 0
|
||||
.TP
|
||||
.PP
|
||||
.PD 1
|
||||
Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(\fIellip_res\fR^2). Default is 10.
|
||||
.TP
|
||||
\fB-s\fR
|
||||
Output the results into separate .py files. The filename and extension for the output files is taken from \fIoutput_py_file\fR.
|
||||
.PD 2
|
||||
.SH AVAILABLE COLORS
|
||||
.PD 1
|
||||
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
black
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
blue
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
brown
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
cmyk_blue
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
cmyk_marine
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
deep
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
forest
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
green
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
grey
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
hotpink
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
magenta
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
marine
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
orange
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
purple
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
red
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
slate
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
teal
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
wheat
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
white
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
yellow
|
||||
.PD 0
|
||||
.PP
|
||||
.PD 1
|
||||
|
||||
.PD 2
|
||||
.SH KNOWN BUGS
|
||||
.PD 1
|
||||
Comments are not allowed at any point between a section header and the end of the contents for a section in either the data file or the input file.
|
||||
.PD 2
|
||||
.SH AUTHORS
|
||||
.PD 1
|
||||
W. Michael Brown
|
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
The asphere_vis tool needs an input script and a dump file
|
||||
from a LAMMPS run.
|
||||
|
||||
In examples/ellipse, you can run LAMMPS with in.ellipse
|
||||
to generate dump.ellipse
|
||||
|
||||
Copy in.ellipse and dump.ellipse to this dir.
|
||||
|
||||
Run the tool to create a PyMol input file called ellipse.py by typing:
|
||||
|
||||
../bin/asphere_vis in.ellipse dump.ellipse ellipse.py -c colors.ellipse -d
|
||||
|
||||
Launch PyMol on this input and you should see a nice viz of
|
||||
4 ellipsoids in a box of LJ particles:
|
||||
|
||||
pymol ellipse.py
|
|
@ -0,0 +1,3 @@
|
|||
marine 0.3
|
||||
red 1.0
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
#***************************************************************************
|
||||
# Makefile
|
||||
# -------------------
|
||||
#
|
||||
# _________________________________________________________________________
|
||||
# Build for the Graphics Utilities
|
||||
# _________________________________________________________________________
|
||||
#
|
||||
# begin : Thu June 9 2005
|
||||
# copyright : (C) 2003 by W. Michael Brown
|
||||
# email : wmbrown@sandia.gov
|
||||
# ***************************************************************************/
|
||||
|
||||
#Compiler type
|
||||
#COMPILER = intel
|
||||
COMPILER = gnu
|
||||
#COMPILER = mpi
|
||||
#COMPILER = mingw
|
||||
|
||||
#Locations of outside objects relative to a source directory
|
||||
HOBJ_DIR = ../obj
|
||||
|
||||
BIN_DIR = ../bin
|
||||
|
||||
ALL_DIR = .
|
||||
ALL_LIB = $(HOBJ_DIR)/liball.a
|
||||
|
||||
GRPHICS_DIR = .
|
||||
GRPHICS_LIB = $(HOBJ_DIR)/libgraphics.a
|
||||
|
||||
GRID_DIR = .
|
||||
GRID_LIB = $(HOBJ_DIR)/libgrid.a
|
||||
|
||||
MOL_DIR = .
|
||||
MOL_LIB = $(HOBJ_DIR)/libmol.a
|
||||
|
||||
MATH_DIR = .
|
||||
MATH_LIB = $(HOBJ_DIR)/libmath.a
|
||||
|
||||
EVERY_LIB = $(MOL_LIB) $(GRID_LIB) $(GRPHICS_LIB) $(MATH_LIB) $(ALL_LIB)
|
||||
|
||||
MOLSIM_DIR = .
|
||||
MOLSIM_LIB = $(HOBJ_DIR)/molsim.o $(HOBJ_DIR)/dynmif.o $(HOBJ_DIR)/dynmifq.o
|
||||
|
||||
# Include directories
|
||||
INC = -I$(ALL_DIR) -I$(MOLSIM_DIR) -I$(MOL_DIR) -I$(MATH_DIR) -I$(GRID_DIR) -I$(GRPHICS_DIR)
|
||||
|
||||
ifeq ($(COMPILER),intel)
|
||||
CPP = icpc # C++ Compiler
|
||||
CC = icc # C compiler
|
||||
AR = xiar #ar
|
||||
DBUG = -g -DDEBUG -DNANCHECK #-Wall #-ansi
|
||||
OPT = -O2 -xP -ipo -no-prec-div -static
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),gnu)
|
||||
CPP = g++ # C++ Compiler
|
||||
CC = gcc # C compiler
|
||||
AR = ar
|
||||
DBUG = -g -DDEBUG -DNANCHECK -Wall -pedantic #-ansi
|
||||
OPT = #-O3
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),mpi)
|
||||
CPP = mpic++ -DMUSE_MPI # C++ Compiler
|
||||
CC = mpicc -DMUSE_MPI # C compiler
|
||||
AR = ar
|
||||
DBUG = -g -DDEBUG -DNANCHECK #-Wall #-pedantic #-ansi
|
||||
OPT = #-xN -O3 #-ipo -no-prec-div -static #-O3
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),mingw)
|
||||
CPP = /cygdrive/c/MINGW/bin/g++ # C++ Compiler
|
||||
CC = /cygdrive/c/MINGW/bin/gcc # C compiler
|
||||
AR = /cygdrive/c/MINGW/bin/ar
|
||||
DBUG = #-g -DDEBUG -DNANCHECK -Wall -pedantic #-ansi
|
||||
OPT = -O3 -static
|
||||
endif
|
||||
|
||||
# Large file support?
|
||||
LFSC = #-D_LARGEFILE_SOURCE `getconf LFS_CFLAGS`
|
||||
LFSL = #`getconf LFS_LDFLAGS` `getconf LFS_LIBS`
|
||||
|
||||
# GNU Scientific Library?
|
||||
GSLC = #-DUSEGSL -I/usr/local/include/
|
||||
GSLL = #-lgsl -lgslcblas
|
||||
|
||||
# GA Library?
|
||||
LIBGAC = #-DLIBGA -I/usr/local/include/
|
||||
LIBGAL = #-lga -L/usr/local/lib/ -Wl,--allow-multiple-definition
|
||||
|
||||
# Movie frame support?
|
||||
MOVIE = #-DMOVIE
|
||||
|
||||
# VTK ?
|
||||
VTKH = #-DUSEVTK -I/usr/local/include/vtk-5.0
|
||||
VTKL = #-lvtkWidgets -lvtkHybrid -lvtkVolumeRendering -lvtkRendering -lvtkIO -lvtkGenericFiltering -lvtkGraphics -lvtkImaging -l vtkFiltering -lvtkCommon -L/usr/X11R6/lib/ -lGL -lXt -lSM -lICE -lX11 -lXext -lpthread -ldl
|
||||
|
||||
CFLAGS = $(OPT) $(MOVIE) $(DBUG) $(INC) $(GSLC) $(LIBGAC) $(VTKH) -c
|
||||
LFLAGS = $(OPT)
|
||||
LLIBS = $(GSLL) $(LIBGAL) $(LFSL) $(VTKL)
|
||||
|
||||
# Distribution Directories
|
||||
DIST_BIN = /home/wmbrown/distbin/
|
||||
DIST_MAN = /home/wmbrown/cpp/manpages/man1/
|
||||
DIST_DOC = /home/wmbrown/cpp/doc/
|
||||
|
||||
OBJ_DIR = $(HOBJ_DIR)
|
||||
|
||||
# Objects for this project
|
||||
THIS_OBJ = $(OBJ_DIR)/asphere_vis.o $(GRPHICS_LIB) $(MATH_LIB) $(ALL_LIB)
|
||||
EXECS = $(BIN_DIR)/asphere_vis
|
||||
|
||||
all: $(EXECS)
|
||||
|
||||
libraries:
|
||||
cd $(ALL_DIR); make; cd $(MATH_DIR); make; cd $(GRID_DIR); make; \
|
||||
cd $(GRPHICS_DIR); make;
|
||||
|
||||
ALL_OBJS = $(OBJ_DIR)/error.o $(OBJ_DIR)/commandline.o \
|
||||
$(OBJ_DIR)/misc.o
|
||||
|
||||
$(OBJ_DIR)/error.o: error.h error.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ error.cpp
|
||||
|
||||
$(OBJ_DIR)/commandline.o: commandline.h commandline.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ commandline.cpp
|
||||
|
||||
$(OBJ_DIR)/misc.o: misc.h misc.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ misc.cpp
|
||||
|
||||
$(ALL_LIB): $(ALL_OBJS)
|
||||
$(AR) -crusv $(ALL_LIB) $(ALL_OBJS)
|
||||
|
||||
GRPHICS_O = $(OBJ_DIR)/colors.o $(OBJ_DIR)/glsurface.o
|
||||
|
||||
$(OBJ_DIR)/colors.o: colors.h colors.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ colors.cpp
|
||||
|
||||
$(OBJ_DIR)/glsurface.o: glsurface.h glsurface.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ glsurface.cpp
|
||||
|
||||
$(GRPHICS_LIB): $(GRPHICS_O)
|
||||
$(AR) -crusv $(GRPHICS_LIB) $(GRPHICS_O)
|
||||
|
||||
MATH_OBJS = $(OBJ_DIR)/cartesian.o $(OBJ_DIR)/miscm.o \
|
||||
$(OBJ_DIR)/spherical.o
|
||||
|
||||
$(OBJ_DIR)/miscm.o: miscm.h miscm.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ miscm.cpp
|
||||
|
||||
$(OBJ_DIR)/cartesian.o: cartesian.h cartesian.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ cartesian.cpp
|
||||
|
||||
$(OBJ_DIR)/spherical.o: spherical.h spherical.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ spherical.cpp
|
||||
|
||||
$(MATH_LIB): $(MATH_OBJS)
|
||||
$(AR) -crusv $(MATH_LIB) $(MATH_OBJS)
|
||||
|
||||
$(OBJ_DIR)/asphere_vis.o: asphere_vis.cpp
|
||||
$(CPP) $(CFLAGS) -o $@ asphere_vis.cpp
|
||||
|
||||
$(BIN_DIR)/asphere_vis: $(THIS_OBJ)
|
||||
$(CPP) $(LFLAGS) -o $@ $(THIS_OBJ) $(LLIBS)
|
||||
#
|
||||
# Documentation
|
||||
#
|
||||
manpages: all
|
||||
/bin/tcsh make_manpages.sh
|
||||
|
||||
#
|
||||
# Create a .tar distribution file
|
||||
#
|
||||
dist: all manpages
|
||||
/bin/tcsh makedistribution.sh
|
||||
|
||||
|
||||
#
|
||||
# INSTALL to Mike's Directories
|
||||
install: all manpages
|
||||
/bin/cp $(EXECS) $(DIST_BIN); \
|
||||
/bin/cp ./manpages/*.1 $(DIST_MAN); \
|
||||
/bin/cp ./manpages/*.pdf $(DIST_DOC)
|
||||
|
||||
|
||||
#
|
||||
# Remove objects, cores, etc.
|
||||
#
|
||||
|
||||
clean:
|
||||
rm -rf $(EXECS) $(THIS_OBJ) $(ALL_OBJ) $(MATH_OBJ) $(GRPHICS_O)
|
||||
cd $(OBJ_DIR); rm -f *.o
|
||||
|
||||
veryclean: clean
|
||||
rm -rf *~ ./api ./manpages
|
||||
|
||||
cleanproject: clean
|
||||
cd $(ALL_DIR); make clean; cd $(MATH_DIR); make clean; \
|
||||
cd $(GRPHICS_DIR); make clean;
|
|
@ -0,0 +1,438 @@
|
|||
/***************************************************************************
|
||||
asphere_vis.cpp
|
||||
-------------------
|
||||
|
||||
Convert a Lammps ellipsoid trajectory to a Pymol CGO trajectory
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the Graphics Utilities package for command-line
|
||||
access to Graphics Library functions
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Fri Jan 12 2007
|
||||
copyright : (C) 2007 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "commandline.h"
|
||||
#include "glsurface.h"
|
||||
#include <limits>
|
||||
|
||||
// Describe the program parameters
|
||||
void Describe(CommandLine &cl,ostream &out);
|
||||
// Parse the command line parameters
|
||||
void HandleArgs(CommandLine &cl, int argc, char *argv[], Error *error);
|
||||
// Parse past an ITEM line in the lammps dump file
|
||||
bool parse_to(const char *token,ifstream &in);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
CommandLine cl;
|
||||
Error error;
|
||||
Colors colors;
|
||||
FileIterator fi;
|
||||
|
||||
// Parse the command line
|
||||
HandleArgs(cl,argc,argv,&error);
|
||||
|
||||
// ----------------- Set up file names
|
||||
if (cl['s']) {
|
||||
fi.set_file_header(a::namewoext(cl.argstring(' ',2))+".");
|
||||
fi.set_file_extensions("."+a::extension(cl.argstring(' ',2)));
|
||||
fi.set_lead_zeros(4);
|
||||
}
|
||||
|
||||
// ----------------- Get the frame interval
|
||||
unsigned start_frame=0;
|
||||
unsigned skip=0;
|
||||
unsigned end_frame=std::numeric_limits<unsigned>::max();
|
||||
if (cl['i']) {
|
||||
start_frame=cl.argint('i',0);
|
||||
skip=cl.argint('i',1);
|
||||
end_frame=cl.argint('i',2);
|
||||
}
|
||||
|
||||
// ----------------- Get the atom type info from a data file
|
||||
unsigned atom_types=0;
|
||||
vector<cPt> shapes;
|
||||
ifstream in;
|
||||
if (!cl['d']) {
|
||||
a::fileopen(in,cl.argstring(' ',0),error);
|
||||
while (!in.eof()) {
|
||||
char iline[500];
|
||||
in.getline(iline,500);
|
||||
vector<string> tokens;
|
||||
a::get_tokens(iline,tokens);
|
||||
if (tokens.size()>2)
|
||||
if (tokens[1]=="atom" && tokens[2]=="types") {
|
||||
atom_types=atoi(tokens[0].c_str());
|
||||
break;
|
||||
}
|
||||
if (!in)
|
||||
break;
|
||||
}
|
||||
if (atom_types==0)
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Could not find number of atom types in data file.");
|
||||
// ----------------- Get the atom type shapes
|
||||
if (parse_to("Shapes",in))
|
||||
for (unsigned i=0; i<atom_types; i++) {
|
||||
double tempd;
|
||||
cPt shape;
|
||||
in >> tempd >> shape;
|
||||
shape.x *= 0.5;
|
||||
shape.y *= 0.5;
|
||||
shape.z *= 0.5;
|
||||
if (in.eof() || !in)
|
||||
break;
|
||||
shapes.push_back(shape);
|
||||
char iline[500];
|
||||
in.getline(iline,500);
|
||||
}
|
||||
if (shapes.size()!=atom_types) {
|
||||
error.buffer() << "Error reading shapes from Pair Coeffs section of "
|
||||
<< "data file. Read " << shapes.size() << " valid shapes, "
|
||||
<< "but expected " << atom_types;
|
||||
error.addbuf(0,"asphere_vis");
|
||||
}
|
||||
a::fileclose(in,error);
|
||||
} else {
|
||||
// ----------------- Get the atom type info from a input file
|
||||
a::fileopen(in,cl.argstring(' ',0),error);
|
||||
while (!in.eof()) {
|
||||
string token;
|
||||
in >> token;
|
||||
if (token=="create_box") {
|
||||
in >> atom_types;
|
||||
shapes.assign(atom_types,cPt(0.5,0.5,0.5));
|
||||
} else if (token=="shape") {
|
||||
unsigned type;
|
||||
cPt shape;
|
||||
in >> type >> shape;
|
||||
shape.x *= 0.5;
|
||||
shape.y *= 0.5;
|
||||
shape.z *= 0.5;
|
||||
if (type>atom_types) {
|
||||
error.buffer() << "Error reading shapes from LAMMPS input file. "
|
||||
<< "I thought there were " << atom_types
|
||||
<< " atom types. But found an shape command for "
|
||||
<< "atom type: " << type;
|
||||
error.addbuf(0,"asphere_vis");
|
||||
}
|
||||
shapes[type-1]=shape;
|
||||
} else {
|
||||
char iline[500];
|
||||
in.getline(iline,500);
|
||||
}
|
||||
|
||||
if (!in && !in.eof())
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Error reading from LAMMPS input file");
|
||||
}
|
||||
a::fileclose(in,error);
|
||||
}
|
||||
if (atom_types==0)
|
||||
error.generate_error(0,"asphere_vis","Found 0 atom types!");
|
||||
|
||||
// ----------------- Get the colors and alpha values for atom types
|
||||
vector<colorPt> color_list;
|
||||
vector<double> alpha_list;
|
||||
if (cl['c']) {
|
||||
a::fileopen(in,cl.argstring('c',0),error);
|
||||
for (unsigned i=0; i<atom_types; i++) {
|
||||
double alpha;
|
||||
string color;
|
||||
in >> color >> alpha;
|
||||
if (in.eof() || !in)
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Improperly formatted color file.");
|
||||
color_list.push_back(colors[color]);
|
||||
alpha_list.push_back(alpha);
|
||||
}
|
||||
a::fileclose(in,error);
|
||||
}
|
||||
|
||||
a::fileopen(in,cl.argstring(' ',1),error);
|
||||
ofstream out;
|
||||
if (!cl['s']) {
|
||||
a::fileopen(out,cl.argstring(' ',2),error);
|
||||
}
|
||||
|
||||
|
||||
// ----------------- Get the atom count
|
||||
unsigned atom_count;
|
||||
if (parse_to("ITEM: NUMBER OF ATOMS",in))
|
||||
in >> atom_count;
|
||||
else
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Could not find ITEM: NUMBER OF ATOMS in input file.");
|
||||
if (!in)
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Error reading ITEM: NUMBER OF ATOMS in input file.");
|
||||
|
||||
// ----------------- Get the triangles per ellipsoid
|
||||
unsigned ellip_res=10;
|
||||
if (cl['r'])
|
||||
ellip_res=cl.argint('r',0);
|
||||
if (ellip_res==0) {
|
||||
error.addwarning(0,9,"asphere_vis","Cannot use -r 0. Setting to 10.");
|
||||
ellip_res=10;
|
||||
}
|
||||
|
||||
// ----------------- Get the bounding box
|
||||
bool bound_found=false;
|
||||
if (!cl['s']) {
|
||||
if (parse_to("ITEM: BOX BOUNDS",in)) {
|
||||
bound_found=true;
|
||||
cPt bound[2];
|
||||
in >> bound[0].x >> bound[1].x;
|
||||
in >> bound[0].y >> bound[1].y;
|
||||
in >> bound[0].z >> bound[1].z;
|
||||
GLSurface gls;
|
||||
Vertex v;
|
||||
v.transparency=1;
|
||||
v.valid_normal=false;
|
||||
v.color=colors["white"];
|
||||
for (unsigned i=0; i<2; i++)
|
||||
for (unsigned j=0; j<2; j++)
|
||||
for (unsigned k=0; k<2; k++) {
|
||||
v.cpt=cPt(bound[i].x,bound[j].y,bound[k].z);
|
||||
gls.addvertex(v);
|
||||
}
|
||||
gls.addline(0,1);
|
||||
gls.addline(0,2);
|
||||
gls.addline(0,4);
|
||||
gls.addline(1,3);
|
||||
gls.addline(1,5);
|
||||
gls.addline(2,3);
|
||||
gls.addline(2,6);
|
||||
gls.addline(3,7);
|
||||
gls.addline(4,5);
|
||||
gls.addline(4,6);
|
||||
gls.addline(5,7);
|
||||
gls.addline(6,7);
|
||||
gls.writelines(out,"gridb");
|
||||
out << "cmd.set('cgo_dot_width',8)\n";
|
||||
} else
|
||||
error.addwarning(0,9,"asphere_vis",
|
||||
"Could not find ITEM: BOX BOUNDS in input file. No box output.");
|
||||
}
|
||||
|
||||
if (!in)
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Error reading ITEM: BOX BOUNDS.");
|
||||
|
||||
// ----------------- Generate the frames
|
||||
unsigned frame=0;
|
||||
unsigned max_frame=std::numeric_limits<unsigned>::max();
|
||||
if (cl['f'])
|
||||
max_frame=cl.argint('f',0);
|
||||
|
||||
colorPt color=colors["marine"];
|
||||
double alpha=1.0;
|
||||
Vertex v;
|
||||
v.color=color;
|
||||
v.transparency=1.0;
|
||||
|
||||
// ----------------- Get to the start frame
|
||||
while (frame<start_frame)
|
||||
if (!parse_to("ITEM: ATOMS",in))
|
||||
error.generate_error(0,"asphere_vis",
|
||||
"Could not find first frame in interval in dump file.");
|
||||
else
|
||||
frame++;
|
||||
|
||||
unsigned wrote=0;
|
||||
while (true) {
|
||||
if (frame>end_frame)
|
||||
break;
|
||||
if (!parse_to("ITEM: ATOMS",in))
|
||||
break;
|
||||
GLSurface gls;
|
||||
for (unsigned i=0; i<atom_count; i++) {
|
||||
unsigned id;
|
||||
unsigned atom_type;
|
||||
in >> id >> atom_type;
|
||||
cPt atom_center;
|
||||
in >> atom_center;
|
||||
Quaternion q;
|
||||
in >> q;
|
||||
if (!in) {
|
||||
error.addwarning(0,9,"asphere_vis","Error reading frame: "+
|
||||
a::itoa(frame));
|
||||
break;
|
||||
}
|
||||
cPt radius(shapes[atom_type-1]);
|
||||
if (radius.x == radius.y && radius.y == radius.z) {
|
||||
v.cpt=atom_center;
|
||||
if (cl['c']) {
|
||||
v.color=color_list[atom_type-1];
|
||||
v.transparency=alpha_list[atom_type-1];
|
||||
}
|
||||
gls.addvertex(v);
|
||||
gls.add_sphere(gls.size_vertices()-1,radius.x);
|
||||
} else {
|
||||
if (cl['c']) {
|
||||
color=color_list[atom_type-1];
|
||||
alpha=alpha_list[atom_type-1];
|
||||
}
|
||||
gls.add_ellipsoid(atom_center,radius,q,
|
||||
color,alpha,ellip_res);
|
||||
}
|
||||
}
|
||||
if (!in)
|
||||
break;
|
||||
if (cl['s']) {
|
||||
if (cl['b'])
|
||||
fi.set_file_num(frame);
|
||||
a::fileopen(out,fi.nextfilename(),error);
|
||||
}
|
||||
gls.writetris(out,"ellipse");
|
||||
if (gls.size_spheres()!=0)
|
||||
gls.writespheres(out,"spheres");
|
||||
if (cl['s'])
|
||||
a::fileclose(out,error);
|
||||
wrote++;
|
||||
frame++;
|
||||
if (frame==max_frame)
|
||||
break;
|
||||
for (unsigned i=0; i<skip; i++)
|
||||
if (!parse_to("ITEM: ATOMS",in))
|
||||
break;
|
||||
else
|
||||
frame++;
|
||||
}
|
||||
if (frame==0)
|
||||
error.addwarning(0,9,"asphere_vis",
|
||||
"Could not find any frams in input_file!");
|
||||
if (cl['i'] && frame<end_frame) {
|
||||
error.buffer() << "Only found " << frame << " frames in input file.";
|
||||
error.addbuf(0,9,"asphere_vis");
|
||||
}
|
||||
|
||||
if (bound_found)
|
||||
out << "cmd.zoom(\"gridb\",animate=-1)\n";
|
||||
|
||||
cout << "Wrote " << wrote << " frames to output file.\n";
|
||||
a::fileclose(out,error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Describe(CommandLine &cl,ostream &out) {
|
||||
string name=cl.program_name();
|
||||
string progname=a::strcenter(name,70);
|
||||
string gridversion=a::strcenter("Graphics Library Version 0.1",70);
|
||||
out << endl << progname << endl << gridversion << endl
|
||||
<< "______________________________________________________________________\n"
|
||||
<< a::strcenter("W. Michael Brown",70) << endl
|
||||
<< a::strcenter("1/12/2007",70) << endl
|
||||
<< "______________________________________________________________________\n"
|
||||
<< "Tool for LAMMPS aspherical trajectory visualization in pymol.\n\n"
|
||||
<< cl.format_synopsis("","","") << endl << endl
|
||||
<< "Use '" << name << " -h > " << name
|
||||
<< ".1' to generate a man page for this\n"
|
||||
<< "program and type 'man ./" << name << ".1' for help\n"
|
||||
<< "______________________________________________________________________\n";
|
||||
return;
|
||||
}
|
||||
|
||||
void HandleArgs(CommandLine &cl, int argc, char *argv[], Error *error) {
|
||||
// Arguments
|
||||
cl.addmanditory(' ',3);
|
||||
cl.addargname(' ',"input_data_file");
|
||||
cl.addargname(' ',"input_dump_file");
|
||||
cl.addargname(' ',"output_py_file");
|
||||
cl.add('d',0);
|
||||
cl.adddescription('d',"Use a LAMMPS input file rather than a data file for extracting atom type information. The input filename is specified as input_data_file.");
|
||||
cl.add('f',1);
|
||||
cl.addargname('f',"max_frame");
|
||||
cl.adddescription('f',"Do not write more than max_frame frames to the output file.");
|
||||
cl.add('r',1);
|
||||
cl.addargname('r',"ellip_res");
|
||||
cl.adddescription('r',"Resolution of ellipsoids in trajectory. The number of triangles per ellipsoid is equal to 2*(ellip_res^2). Default is 10.");
|
||||
cl.add('c',1);
|
||||
cl.addargname('c',"color_file");
|
||||
cl.adddescription('c',"Color the atom_types and set transparency based on the input file. The input file contains a space delimited set sequence of the color for an atom followed by the alpha. The color should be the string name and the alpha should be between 0 and 1.");
|
||||
cl.add('s',0);
|
||||
cl.adddescription('s',"Output the results into separate .py files. The filename and extension for the output files is taken from output_py_file.");
|
||||
cl.add('i',3);
|
||||
cl.addargname('i',"start_frame");
|
||||
cl.addargname('i',"skip");
|
||||
cl.addargname('i',"end_frame");
|
||||
cl.adddescription('i',"Render the specified frame interval inclusive between start_frame and end_frame. skip gives the number of frames to skip between each rendered frame. A value of 0 outputs every frame between start_frame and end_frame. The first frame in the dump file is frame 0.");
|
||||
cl.add('b',0);
|
||||
cl.adddescription('b',"When used with -s, the option will number the filenames based on the frame number. By default, they are numbered consequtively from zero.");
|
||||
|
||||
// Stuff for every executable
|
||||
cl.addhelp('h',0);
|
||||
cl.adddescription('h',"Print out the man page for help");
|
||||
cl.add('n',1);
|
||||
cl.addargname('n',"notice_level");
|
||||
cl.adddescription('n',"Set the degree of program output. Use: \n\n\t-n 0\tNo output\n\t-n 10\tNormal program output\n\t-n 20\tParameters useful for reproducing the results\n\t-n 30\tAll output");
|
||||
|
||||
// Short Description
|
||||
cl.addtoman_chapter("NAME","Tools for LAMMPS ellipsoid trajectory visualization in PyMol.");
|
||||
|
||||
// Version
|
||||
cl.addtoman_chapter("VERSION","Version 0.1");
|
||||
|
||||
// Full Description
|
||||
const string desc[5]={
|
||||
"Tool for LAMMPS trajectory visualization in PyMol. The input is a LAMMPS ",
|
||||
"'data' file or a 'in' file with ellipsoid semi-axes specified using the ",
|
||||
"ellipsoid command. The trajectory is input from a 'dump' file that must ",
|
||||
"be generated using a custom style with the following arguments in order:\n",
|
||||
".TP\\fItag type x y z quatw quati quatj quatk\\fR\n"
|
||||
};
|
||||
cl.addtoman_chapter("DESCRIPTION",5,desc);
|
||||
|
||||
Colors colors;
|
||||
cl.addtoman_chapter("AVAILABLE COLORS",colors.colorlist());
|
||||
|
||||
// bugs
|
||||
const string bugs[3]={
|
||||
"Comments are not allowed at any point between a section header and ",
|
||||
"the end of the contents for a section in either the data file or ",
|
||||
"the input file."
|
||||
};
|
||||
cl.addtoman_chapter("KNOWN BUGS",3,bugs);
|
||||
|
||||
|
||||
// Authors
|
||||
cl.addtoman_chapter("AUTHORS","W. Michael Brown");
|
||||
|
||||
// Parse the commandline
|
||||
if (!cl.parse(argc,argv,error)) {
|
||||
Describe(cl,cout);
|
||||
error->generate_error(0,a::filenameonly(argv[0]),"Bad Command Line\n");
|
||||
}
|
||||
|
||||
// Set the notice level
|
||||
if (cl['n'])
|
||||
error->note.set_notice_level(cl.argint('n',0));
|
||||
|
||||
// Generate a notice with the command line for records purposes
|
||||
string cm=cl.program_name();
|
||||
for (int j=1; j<argc; j++)
|
||||
cm+=' '+string(argv[j]);
|
||||
cm+="\n";
|
||||
error->note.notice(19,"CommandLine",cm);
|
||||
|
||||
// Output the help
|
||||
if (cl['h']) {
|
||||
cl.write_man_page(cout,"0.1","Graphics Utilities");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse past an ITEM line in the lammps dump file
|
||||
bool parse_to(const char * token,ifstream &in) {
|
||||
char iline[5000];
|
||||
while (true) {
|
||||
in.getline(iline,5000);
|
||||
if (in.eof() || !in)
|
||||
return false;
|
||||
if (strcmp(token,iline)==0)
|
||||
return true;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,466 @@
|
|||
/****************************************************************************
|
||||
* cartesian.h
|
||||
* Shared stuff for dealing with Cartesian coordinates
|
||||
* Also contains quaternion structures and operations
|
||||
*
|
||||
* Cartesian point of doubles: cPt
|
||||
* Cartesian point of intergers: iPt
|
||||
* Vector of doubles: vectorPt
|
||||
* Color of doubles: colorPt
|
||||
* Quaternion: Quaternion
|
||||
*
|
||||
* Can be accessed as cPt.x, cPt[X], colorPt[GREEN], iPt[I], etc.
|
||||
*
|
||||
*
|
||||
* W. Michael Brown
|
||||
****************************************************************************/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#ifndef CARTESIAN_H
|
||||
#define CARTESIAN_H
|
||||
|
||||
#include "miscm.h"
|
||||
#include "m_constants.h"
|
||||
#include "spherical.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
enum { X, ///<0
|
||||
Y, ///<1
|
||||
Z ///<2
|
||||
};
|
||||
enum { I, ///<0
|
||||
J, ///<1
|
||||
K, ///<2
|
||||
W ///<3
|
||||
};
|
||||
enum { RED, ///<0
|
||||
GREEN, ///<1
|
||||
BLUE ///<2
|
||||
};
|
||||
|
||||
// Other coordinates
|
||||
template<class numtyp> class Ball;
|
||||
|
||||
// Template friend declarations
|
||||
template<class numtyp> class TwoD;
|
||||
template<class numtyp>
|
||||
ostream & operator<< (ostream &out, const TwoD<numtyp> &t);
|
||||
template<class numtyp>
|
||||
istream & operator>> (istream &in, TwoD<numtyp> &t);
|
||||
|
||||
template<class numtyp> class ThreeD;
|
||||
template<class numtyp>
|
||||
ostream & operator<< (ostream &out, const ThreeD<numtyp> &t);
|
||||
template<class numtyp>
|
||||
istream & operator>> (istream &in, ThreeD<numtyp> &t);
|
||||
template<class numtyp>
|
||||
ThreeD<numtyp> operator+ (const numtyp, const ThreeD<numtyp> &two);
|
||||
template<class numtyp>
|
||||
ThreeD<numtyp> operator- (const numtyp, const ThreeD<numtyp> &two);
|
||||
template<class numtyp>
|
||||
ThreeD<numtyp> operator* (const numtyp, const ThreeD<numtyp> &two);
|
||||
template<class numtyp>
|
||||
ThreeD<numtyp> operator/ (const numtyp, const ThreeD<numtyp> &two);
|
||||
|
||||
/// Two dimensional vector
|
||||
/** The elements can be accessed directly .x or .y
|
||||
* or by using the operator [] ( [X], [Y] or [I], [J] )
|
||||
*
|
||||
* The following operators are currently overloaded:
|
||||
* +,-,*
|
||||
*
|
||||
* operators *,/ returns a vector with each element multiplied
|
||||
* times the corresponding element in the other vector (Matlab .* )
|
||||
*
|
||||
* the member function dot can be used to compute dot products
|
||||
*
|
||||
* Input and output are overloaded for element I/O of the form "x y"
|
||||
* <<, >>
|
||||
*
|
||||
* \sa cartesian.h for typedefs and defines*/
|
||||
template<class numtyp>
|
||||
class TwoD {
|
||||
public:
|
||||
/// Empty construct. Not necessarily initialized to [0 0]
|
||||
TwoD();
|
||||
/// Assign both x and y the value
|
||||
TwoD(numtyp x);
|
||||
/// Assignment Constructor
|
||||
TwoD(numtyp cx, numtyp cy);
|
||||
|
||||
/// Type conversion
|
||||
TwoD(const TwoD<float> &two);
|
||||
/// Ball projection (onto xy-plane)
|
||||
TwoD(const Ball<float> &ball);
|
||||
|
||||
numtyp x; ///< First element
|
||||
numtyp y; ///< Last element
|
||||
|
||||
numtyp &operator[](unsigned i);
|
||||
|
||||
friend ostream & operator<< <>(ostream &out, const TwoD<numtyp> &t);
|
||||
friend istream & operator>> <>(istream &in, TwoD<numtyp> &t);
|
||||
|
||||
TwoD<numtyp> operator + (const TwoD<numtyp> &two) const;
|
||||
void operator += (const TwoD<numtyp> &two);
|
||||
TwoD<numtyp> operator + (const numtyp two) const;
|
||||
TwoD<numtyp> operator - (const TwoD<numtyp> &two) const;
|
||||
TwoD<numtyp> operator - (const numtyp two) const;
|
||||
TwoD<numtyp> operator * (const numtyp two) const;
|
||||
TwoD<numtyp> operator * (const TwoD<numtyp> &two) const;
|
||||
void operator /= (const numtyp two);
|
||||
|
||||
bool operator != (const TwoD<numtyp> &two) const;
|
||||
|
||||
/// Dot Product
|
||||
numtyp dot(const TwoD<numtyp> &two) const;
|
||||
|
||||
/// Distance between two points
|
||||
numtyp dist(const TwoD<numtyp> &two) const;
|
||||
/// Distance squared between two points
|
||||
numtyp dist2(const TwoD<numtyp> &two) const;
|
||||
/// Returns one of two normals to a line represented by vector
|
||||
TwoD<numtyp> normal();
|
||||
|
||||
/// Move coordinates into array
|
||||
void to_array(numtyp *array);
|
||||
/// Set coordinates from array
|
||||
void from_array(numtyp *array);
|
||||
|
||||
// -------------- Weird functions that help with coord templating
|
||||
unsigned dimensionality();
|
||||
/// Returns the index of *this (for unsigned) in a square 3D array
|
||||
/** \param s_size s_size[0]=1Dsize **/
|
||||
numtyp array_index(vector<unsigned> &s_size);
|
||||
/// Increment a 2D index from min to max (same as nested for)
|
||||
/** Returns false when increment is complete **/
|
||||
bool increment_index(TwoD &minp,TwoD &maxp);
|
||||
/// Return false if x or y is not within the inclusive range
|
||||
bool check_bounds(numtyp min,numtyp max);
|
||||
private:
|
||||
};
|
||||
|
||||
///\var typedef TwoD<double> c2DPt
|
||||
/// Two dimensional vector of doubles
|
||||
typedef TwoD<double> c2DPt;
|
||||
|
||||
|
||||
/// Three dimensional vector
|
||||
/** The elements can be accessed directly .x or .y or .z
|
||||
* or by using the operator [] ( [X], [Y], [Z] or [I], [J], [K] or
|
||||
* [RED], [GREEN], [BLUE] )
|
||||
*
|
||||
* The following operators are currently overloaded:
|
||||
* +,-,*,/,+=,-=,*=,/=,==,!=
|
||||
*
|
||||
* operators *,/,*=,/= returns a vector with each element multiplied
|
||||
* times the corresponding element in the other vector (Matlab .* )
|
||||
* or with each element multiplied by a scalar
|
||||
*
|
||||
* the member function dot can be used to compute dot products
|
||||
|
||||
*
|
||||
* Input and output are overloaded for element I/O of the form "x y z"
|
||||
* <<, >>
|
||||
*
|
||||
* \sa cartesian.h for typedefs and defines*/
|
||||
template<class numtyp>
|
||||
class ThreeD {
|
||||
public:
|
||||
/// Assignment Constructor
|
||||
ThreeD(numtyp cx, numtyp cy, numtyp cz);
|
||||
/// Assign all the value
|
||||
ThreeD(numtyp in);
|
||||
/// Type Conversion
|
||||
ThreeD(const ThreeD<unsigned>&);
|
||||
/// Type Conversion
|
||||
ThreeD(const ThreeD<int>&);
|
||||
/// Type Conversion
|
||||
ThreeD(const ThreeD<float>&);
|
||||
/// Type Conversion
|
||||
ThreeD(const ThreeD<double>&);
|
||||
/// TwoD with (z-coordinate set to zero)
|
||||
ThreeD(const TwoD<float>&);
|
||||
/// Spherical Conversion
|
||||
ThreeD(const Ball<double>&);
|
||||
/// Spherical Conversion
|
||||
ThreeD(const Ball<float>&);
|
||||
/// Empty construct (Not necessarily initialized to zero)
|
||||
ThreeD();
|
||||
|
||||
numtyp x; ///< First Element
|
||||
numtyp y; ///< Second Element
|
||||
numtyp z; ///< Last Element
|
||||
|
||||
friend ostream & operator<< <>(ostream &out, const ThreeD<numtyp> &t);
|
||||
friend istream & operator>> <>(istream &in, ThreeD<numtyp> &t);
|
||||
friend ThreeD<numtyp> operator+ <>(const numtyp, const ThreeD<numtyp> &two);
|
||||
friend ThreeD<numtyp> operator- <>(const numtyp, const ThreeD<numtyp> &two);
|
||||
friend ThreeD<numtyp> operator* <>(const numtyp, const ThreeD<numtyp> &two);
|
||||
friend ThreeD<numtyp> operator/ <>(const numtyp, const ThreeD<numtyp> &two);
|
||||
|
||||
numtyp &operator[](unsigned i);
|
||||
numtyp operator[](unsigned i) const;
|
||||
|
||||
bool operator == (const ThreeD<numtyp> &two) const;
|
||||
bool operator != (const ThreeD<numtyp> &two) const;
|
||||
ThreeD<numtyp> operator + (const ThreeD<numtyp> &two) const;
|
||||
ThreeD<numtyp> operator + (const numtyp &two) const;
|
||||
ThreeD<numtyp> operator - (const ThreeD<numtyp> &two) const;
|
||||
ThreeD<numtyp> operator - (const numtyp &two) const;
|
||||
ThreeD<numtyp> operator * (const numtyp &two) const;
|
||||
ThreeD<numtyp> operator * (const ThreeD<numtyp> &two) const;
|
||||
ThreeD<numtyp> operator / (const numtyp &two) const;
|
||||
ThreeD<numtyp> operator / (const ThreeD<numtyp> &two) const;
|
||||
void operator = (const ThreeD &two);
|
||||
void operator += (const numtyp &two);
|
||||
void operator += (const ThreeD &two);
|
||||
void operator -= (const numtyp &two);
|
||||
void operator -= (const ThreeD &two);
|
||||
void operator *= (const numtyp &two);
|
||||
void operator /= (const numtyp &two);
|
||||
|
||||
/// Move coordinates into array
|
||||
void to_array(numtyp *array);
|
||||
/// Set coordinates from array
|
||||
void from_array(numtyp *array);
|
||||
|
||||
/// Returns the dot product of *this and two
|
||||
numtyp dot(const ThreeD<numtyp> &two) const;
|
||||
|
||||
/// Returns the cross product of \b *this and \b two
|
||||
/** The input vectors do not need to be normalized, however, the output
|
||||
* vector will not be */
|
||||
ThreeD<numtyp> cross(const ThreeD<numtyp> &two) const;
|
||||
/// Returns the angle between \b *this and \b two
|
||||
numtyp angle(const ThreeD<numtyp> &two) const;
|
||||
/// Returns an arbitrary vector that is perpendicular to the input
|
||||
/** The output vector is not normalized */
|
||||
ThreeD<numtyp> perpendicular();
|
||||
/// Rotate a vector in xz-plane by t radians
|
||||
ThreeD<numtyp> rotatey(double t) const;
|
||||
/// Rotate a vector in xy-plane by t radians
|
||||
ThreeD<numtyp> rotatez(double t) const;
|
||||
/// Magnitude of vector
|
||||
numtyp norm() const;
|
||||
/// Squared norm of a vector
|
||||
numtyp norm2() const;
|
||||
/// Magnitude of vector
|
||||
numtyp hypot() const;
|
||||
/// Distance between two points
|
||||
numtyp dist(const ThreeD<numtyp> &two);
|
||||
/// Distance squared between two points
|
||||
numtyp dist2(const ThreeD<numtyp> &two);
|
||||
/// Converts \b *this to the unit vector
|
||||
void normalize();
|
||||
/// Return the unit vector of \b *this
|
||||
ThreeD<numtyp> unit();
|
||||
|
||||
/// Returns the projection of the point or vector onto Z-plane
|
||||
c2DPt projz();
|
||||
|
||||
/// Set this to be the max of one and two for each dimension
|
||||
void max(ThreeD &one, ThreeD &two);
|
||||
/// Set this to be the min of one and two for each dimension
|
||||
void min(ThreeD &one, ThreeD &two);
|
||||
|
||||
// -------------- Weird functions that help with coord templating
|
||||
/// Returns 3
|
||||
unsigned dimensionality();
|
||||
/// Returns the index of *this (for unsigned) in a square 3D array
|
||||
/** \param s_size s_size[0]=1Dsize, and s_size[1]=1D size*1Dsize **/
|
||||
numtyp array_index(vector<unsigned> &s_size);
|
||||
/// Increment a 3D index from min to max (same as nested for)
|
||||
/** \note This is currently only implemented for unsigned numbers
|
||||
* Returns false when increment is complete **/
|
||||
bool increment_index(ThreeD &minp,ThreeD &maxp);
|
||||
/// Return false if x,y, or z is not within the inclusive range
|
||||
bool check_bounds(numtyp min,numtyp max);
|
||||
private:
|
||||
};
|
||||
|
||||
///\var typedef ThreeD<int> iPt;
|
||||
/// Three dimensional vector of integers
|
||||
typedef ThreeD<int> iPt;
|
||||
///\var typedef ThreeD<unsigned> uPt;
|
||||
/// Three dimensional vector of unsigned
|
||||
typedef ThreeD<unsigned> uPt;
|
||||
///\var typedef ThreeD<double> cPt;
|
||||
/// Three dimensional vector of doubles
|
||||
typedef ThreeD<double> cPt;
|
||||
///\var typedef ThreeD<double> vectorPt;
|
||||
/// Three dimensional vector of doubles
|
||||
typedef ThreeD<double> vectorPt;
|
||||
///\var typedef ThreeD<double> colorPt;
|
||||
/// Three dimensional vector of doubles
|
||||
typedef ThreeD<double> colorPt;
|
||||
|
||||
///\def ORIGIN
|
||||
/// Point at origin
|
||||
#define ORIGIN cPt(0.0,0.0,0.0)
|
||||
///\def XAXIS
|
||||
/// Unit vector for x-axis
|
||||
#define XAXIS vectorPt(1.0,0.0,0.0)
|
||||
///\def YAXIS
|
||||
/// Unit vector for y-axis
|
||||
#define YAXIS vectorPt(0.0,1.0,0.0)
|
||||
///\def ZAXIS
|
||||
/// Unit vector for z-axis
|
||||
#define ZAXIS vectorPt(0.0,0.0,1.0)
|
||||
|
||||
class RotMat;
|
||||
|
||||
/// Euler Rotation
|
||||
class EulerRot {
|
||||
public:
|
||||
EulerRot();
|
||||
EulerRot(double theta,double psi,double phi);
|
||||
|
||||
/// Rotate the rotation axis by a given rotation matrix
|
||||
void rotate_axis(const RotMat &rotmat);
|
||||
|
||||
void operator= (const EulerRot &two);
|
||||
friend ostream & operator<<(ostream &out, const EulerRot &rot);
|
||||
|
||||
double theta;
|
||||
double psi;
|
||||
double phi;
|
||||
};
|
||||
|
||||
///\def EU_NOROTATE
|
||||
/// EulerRot with no rotation
|
||||
#define EU_NOROTATE EulerRot(0.0,0.0,0.0)
|
||||
|
||||
//---------------------------Quaternion Stuff -------------------------
|
||||
|
||||
/// Class for handling Quaternion vectors
|
||||
/** The elements can be accessed directly .w .i .j or .k
|
||||
* or by using the operator[] ( [W], [X], [Y], [Z] or [W], [I], [J], [K] )
|
||||
*
|
||||
* The following operators are currently overloaded:
|
||||
* +=,*,*=,=,==
|
||||
*
|
||||
* Overloaded * concatenates two successive rotations \n
|
||||
* \e It \e is \e not \e communative \n
|
||||
* For \e join=q1*q2, \e join is equivalent to performing rotation \e q1
|
||||
* \b followed by \e q2.
|
||||
*
|
||||
* Input and output are overloaded for element I/O of the form "w i j k"
|
||||
* <<, >>
|
||||
*
|
||||
* \sa cartesian.h for typedefs and defines*/
|
||||
class Quaternion {
|
||||
public:
|
||||
Quaternion();
|
||||
~Quaternion();
|
||||
|
||||
double w; ///<Real Component
|
||||
double i; ///<Imaginary Component
|
||||
double j; ///<Imaginary Component
|
||||
double k; ///<Imaginary Component
|
||||
|
||||
double &operator[](unsigned index);
|
||||
|
||||
/// Copy Constructor
|
||||
Quaternion(const Quaternion &two);
|
||||
/// Assignment constructor
|
||||
Quaternion(double inw, double ini, double inj, double ink);
|
||||
/// Axis-Angle Rotation (\b v must be a \b UNIT vector)
|
||||
Quaternion(const vectorPt &v, double angle);
|
||||
/// Rotation from vector 1 to vector 2 (v1 and v2 need not be normalized)
|
||||
/** Angle is between \b v1 and \b v2 and axis is calculated as the cross
|
||||
* product of \b v1 and \b v2 */
|
||||
Quaternion(const vectorPt &v1, const vectorPt &v2);
|
||||
/// Spherical rotation
|
||||
Quaternion(double longitude, double latitude);
|
||||
/// From Euler angles
|
||||
Quaternion(const EulerRot &erot);
|
||||
|
||||
void operator += (const Quaternion &two);
|
||||
Quaternion operator * (const Quaternion &two) const;
|
||||
void operator*= (const Quaternion &two);
|
||||
Quaternion operator * (const double two) const;
|
||||
void operator*= (const double two);
|
||||
void operator= (const Quaternion &two);
|
||||
bool operator== (const Quaternion &two) const;
|
||||
|
||||
/// Returns the conjugate
|
||||
Quaternion conj() const;
|
||||
/// Returns the norm
|
||||
double norm();
|
||||
/// Form \b *this into the unit vector
|
||||
void normalize();
|
||||
/// Returns the unit vector of \b *this
|
||||
Quaternion unit();
|
||||
|
||||
friend ostream & operator<<(ostream &out, const Quaternion &q);
|
||||
friend istream & operator>>(istream &in, Quaternion &q);
|
||||
};
|
||||
|
||||
/// Rotation matrix (about origin)
|
||||
/** Rotation of ThreeD can be applied via overloaded * operator **/
|
||||
class RotMat {
|
||||
public:
|
||||
/// Unspecified matrix!
|
||||
RotMat();
|
||||
/// Initialize with quaternion
|
||||
RotMat(const Quaternion &q);
|
||||
/// Set based on quaternion
|
||||
void set(const Quaternion &q);
|
||||
/// Assert that the rotation is proper
|
||||
void proper();
|
||||
|
||||
cPt operator*(const cPt &in) const;
|
||||
|
||||
double x_x,x_y,x_z,y_x,y_y,y_z,z_x,z_y,z_z;
|
||||
};
|
||||
|
||||
///\def NOROTATE
|
||||
/// Quaternion with no rotation
|
||||
#define NOROTATE Quaternion(1.0,0.0,0.0,0.0)
|
||||
|
||||
/// Global geometry functions
|
||||
namespace c {
|
||||
/// Returns point on a line closest to an outside point
|
||||
/** The line is described by a directional vector and a point on the line
|
||||
*\param v Vector describing the line direction
|
||||
*\param v_point Point on the line
|
||||
*\param point The Outside point */
|
||||
cPt point_to_line(const vectorPt &v, const cPt &v_point,
|
||||
const cPt &point);
|
||||
|
||||
/// Return the closest distance between two line segments input as end points
|
||||
/**\param l1_1 End point of segment 1
|
||||
*\param l1_2 End point of segment 1
|
||||
*\param l2_1 End point of segment 2
|
||||
*\param l2_2 End point of segment 2 */
|
||||
double closest_approach(const cPt &l1_1, const cPt &l1_2,
|
||||
const cPt &l2_1, const cPt &l2_2);
|
||||
/// Calculates the points where two line segments are closest
|
||||
/**\param l1_1 End point of segment 1
|
||||
*\param l1_2 End point of segment 1
|
||||
*\param l2_1 End point of segment 2
|
||||
*\param l2_2 End point of segment 2
|
||||
*\param close_l1 Calculated closest point on line segment 1
|
||||
*\param close_l2 Calculated closest point on line segment 2 */
|
||||
void closest_approach_points(const cPt &l1_1, const cPt &l1_2,
|
||||
const cPt &l2_1, const cPt &l2_2,
|
||||
cPt &close_l1, cPt &close_l2);
|
||||
|
||||
/// Returns true if two line segments intersect
|
||||
bool intersect(const c2DPt &line1_start, const c2DPt &line1_end,
|
||||
const c2DPt &line2_start, const c2DPt &line2_end);
|
||||
|
||||
/// Liang-Barsky Intersection between line segment and line
|
||||
bool sline_intersect(const c2DPt &line1_start, const c2DPt &line1_end,
|
||||
const c2DPt &line2normal, const c2DPt &line2_point);
|
||||
/// Average position
|
||||
cPt mean(vector<cPt> &vec);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/***************************************************************************
|
||||
colors.cpp
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
begin : Wed Jun 11 2003
|
||||
copyright : (C) 2003 by mbrown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "colors.h"
|
||||
|
||||
Colors::Colors() {
|
||||
colors.insert(pair<string,colorPt>("white",colorPt(1,1,1)));
|
||||
colors.insert(pair<string,colorPt>("red",colorPt(1,0,0)));
|
||||
colors.insert(pair<string,colorPt>("green",colorPt(0,1,0)));
|
||||
colors.insert(pair<string,colorPt>("blue",colorPt(0,0,1)));
|
||||
colors.insert(pair<string,colorPt>("cmyk_blue",colorPt(0.074,0.168,0.614)));
|
||||
colors.insert(pair<string,colorPt>("yellow",colorPt(1,1,0)));
|
||||
colors.insert(pair<string,colorPt>("purple",colorPt(0.697,0.2,0.697)));
|
||||
colors.insert(pair<string,colorPt>("hotpink",colorPt(1,0,0.5)));
|
||||
colors.insert(pair<string,colorPt>("brown",colorPt(0.551,0.272,0.15)));
|
||||
colors.insert(pair<string,colorPt>("orange",colorPt(1,0.5,0)));
|
||||
colors.insert(pair<string,colorPt>("black",colorPt(0,0,0)));
|
||||
colors.insert(pair<string,colorPt>("magenta",colorPt(1,0,1)));
|
||||
colors.insert(pair<string,colorPt>("slate",colorPt(0.5,0.5,1)));
|
||||
colors.insert(pair<string,colorPt>("marine",colorPt(0,0.5,1)));
|
||||
colors.insert(pair<string,colorPt>("cmyk_marine",colorPt(0.273,0.469,0.758)));
|
||||
colors.insert(pair<string,colorPt>("teal",colorPt(0.2,0,0.598)));
|
||||
colors.insert(pair<string,colorPt>("forest",colorPt(0.098,0.5,0.098)));
|
||||
colors.insert(pair<string,colorPt>("deep",colorPt(0.098,0.098,0.5)));
|
||||
colors.insert(pair<string,colorPt>("grey",colorPt(0.5,0.5,0.5)));
|
||||
colors.insert(pair<string,colorPt>("wheat",colorPt(0.988,0.819,0.646)));
|
||||
}
|
||||
|
||||
Colors::~Colors(){
|
||||
}
|
||||
|
||||
// Number of colors in the map
|
||||
unsigned Colors::size() {
|
||||
return colors.size();
|
||||
}
|
||||
|
||||
// Return the color in the gradient between start and end according to
|
||||
// value
|
||||
colorPt Colors::gradient(double start, double end, double value,
|
||||
const colorPt &startcolor, const colorPt &endcolor) {
|
||||
double percent;
|
||||
|
||||
if (value<start)
|
||||
return startcolor;
|
||||
else if (value>end)
|
||||
return endcolor;
|
||||
if (start==end)
|
||||
return startcolor;
|
||||
|
||||
percent=((value-start)/(end-start));
|
||||
return ((endcolor-startcolor)*percent)+startcolor;
|
||||
}
|
||||
|
||||
// Three color gradient
|
||||
colorPt Colors::gradient(double start, double mid, double end, double value,
|
||||
const colorPt &startcolor, const colorPt &midcolor,
|
||||
const colorPt &endcolor) {
|
||||
double percent;
|
||||
|
||||
if (value==mid)
|
||||
return midcolor;
|
||||
else if (value<start)
|
||||
return startcolor;
|
||||
else if (value>end)
|
||||
return endcolor;
|
||||
else if (value<mid) {
|
||||
percent=((value-start)/(mid-start));
|
||||
return ((midcolor-startcolor)*percent)+startcolor;
|
||||
} else {
|
||||
if (mid==end)
|
||||
return midcolor;
|
||||
percent=((value-mid)/(end-mid));
|
||||
return ((endcolor-midcolor)*percent)+midcolor;
|
||||
}
|
||||
}
|
||||
|
||||
// Output the colors to standard out
|
||||
void Colors::outputcolors() {
|
||||
map<string, colorPt>::iterator m;
|
||||
|
||||
for (m=colors.begin(); m!=colors.end(); m++)
|
||||
cout << " " << m->first << endl;
|
||||
}
|
||||
|
||||
// Return a string with the list of available colors
|
||||
string Colors::colorlist() {
|
||||
string colorl;
|
||||
map<string, colorPt>::iterator m;
|
||||
|
||||
for (m=colors.begin(); m!=colors.end(); m++)
|
||||
colorl+="\n\t"+m->first;
|
||||
colorl+="\n";
|
||||
return colorl;
|
||||
}
|
||||
|
||||
colorPt Colors::operator[](const string &name) {
|
||||
map<string, colorPt>::iterator m;
|
||||
m=colors.find(name);
|
||||
if (m==colors.end())
|
||||
return colorPt(1,1,1); // Return white if not found
|
||||
else
|
||||
return m->second;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/***************************************************************************
|
||||
colors.h
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Storage and manipulation of colors.
|
||||
|
||||
begin : Wed Jun 11 2003
|
||||
copyright : (C) 2003 by mbrown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef COLORS_H
|
||||
#define COLORS_H
|
||||
|
||||
#include "cartesian.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
/// Class for dealing with RGB color space
|
||||
class Colors {
|
||||
public:
|
||||
Colors();
|
||||
~Colors();
|
||||
|
||||
/// Return number of colors in the map
|
||||
unsigned size();
|
||||
|
||||
/// Return the color in the gradient between start and end
|
||||
/** \param start Starting value
|
||||
* \param end Ending Value
|
||||
* \param value Color in gradient determined for value
|
||||
* relative to start and end
|
||||
* \param startcolor Starting color for the gradient
|
||||
* \param endcolor Ending color for the gradient */
|
||||
colorPt gradient(double start, double end, double value,
|
||||
const colorPt &startcolor, const colorPt &endcolor);
|
||||
/// Three color gradient
|
||||
/** \sa gradient() */
|
||||
colorPt gradient(double start, double mid, double end, double value,
|
||||
const colorPt &startcolor, const colorPt &midcolor,
|
||||
const colorPt &endcolor);
|
||||
|
||||
/// Output the colors to standard out
|
||||
void outputcolors();
|
||||
/// Return a string with the list of available colors
|
||||
string colorlist();
|
||||
|
||||
/// Return an RGB color based on name
|
||||
colorPt operator[](const string &name);
|
||||
|
||||
private:
|
||||
map<string, colorPt> colors;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,504 @@
|
|||
/***************************************************************************
|
||||
commandline.cpp
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Command line parsing stuff..
|
||||
* Add argument with ' ' for arguments that do not use - (i.e. filenames)
|
||||
* Manditory for the ' ' requires only 1 argument regardless of the number
|
||||
- use argsize;
|
||||
|
||||
begin : Sun Jun 11 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : mbrown@nirvana.unm.edu
|
||||
***************************************************************************/
|
||||
|
||||
#include "commandline.h"
|
||||
|
||||
CommandLine::Parameter::Parameter() {
|
||||
num_args=0;
|
||||
manditory_args=0;
|
||||
manditory=false;
|
||||
dash=false;
|
||||
set=false;
|
||||
}
|
||||
|
||||
CommandLine::Parameter::~Parameter() {}
|
||||
|
||||
CommandLine::CommandLine() {
|
||||
help_set=false;
|
||||
progname="";
|
||||
|
||||
// Set up the default man chapters
|
||||
manchapter_order[0]="NAME";
|
||||
man_chapters["NAME"].clear();
|
||||
manchapter_order[1]="VERSION";
|
||||
man_chapters["VERSION"].clear();
|
||||
manchapter_order[2]="SYNOPSIS";
|
||||
man_chapters["SYNOPSIS"].clear();
|
||||
manchapter_order[3]="DESCRIPTION";
|
||||
man_chapters["DESCRIPTION"].clear();
|
||||
manchapter_order[4]="PARAMETERS";
|
||||
man_chapters["PARAMETERS"].clear();
|
||||
man_numchapters=5;
|
||||
}
|
||||
|
||||
CommandLine::~CommandLine() {
|
||||
}
|
||||
|
||||
void CommandLine::addargname(char n, const string &an) {
|
||||
parameters[n].argnames.push_back(an);
|
||||
}
|
||||
|
||||
void CommandLine::adddescription(char n, const string &d) {
|
||||
parameters[n].description.push_back(d);
|
||||
}
|
||||
|
||||
// Returns the argument size for a parameter
|
||||
unsigned CommandLine::argsize(char n) {
|
||||
return parameters[n].args.size();
|
||||
}
|
||||
|
||||
bool CommandLine::operator [](char n) {
|
||||
return set(n);
|
||||
}
|
||||
|
||||
string CommandLine::program_name() {
|
||||
return progname;
|
||||
}
|
||||
|
||||
string CommandLine::full_command_line() {
|
||||
return full_line;
|
||||
}
|
||||
|
||||
// ----------------- Add allowed arguments
|
||||
|
||||
void CommandLine::add(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
}
|
||||
|
||||
// Where num represents maximum number of arguments and man_num represents
|
||||
// manditory number of arguments for a parameter
|
||||
void CommandLine::add(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
}
|
||||
|
||||
void CommandLine::addmanditory(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].manditory_args=num;
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory=true;
|
||||
}
|
||||
|
||||
// Where num represents maximum number of arguments and man_num represents
|
||||
// manditory number of arguments for a parameter
|
||||
void CommandLine::addmanditory(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
parameters[n].manditory=true;
|
||||
}
|
||||
|
||||
// Allow parameter that takes signed numbers as input
|
||||
void CommandLine::addsigned(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
parameters[n].dash=true; // Allow dashes in arguments
|
||||
}
|
||||
|
||||
// Allow parameter that takes signed numbers as input
|
||||
void CommandLine::addsigned(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
parameters[n].dash=true; // Allow dashes in arguments
|
||||
}
|
||||
|
||||
void CommandLine::addhelp(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
|
||||
help_set=true;
|
||||
help_param=n;
|
||||
}
|
||||
|
||||
// Add descriptions for man pages
|
||||
void CommandLine::addargnames(char n, unsigned num, const string args[]) {
|
||||
for (unsigned i=0; i<num; i++)
|
||||
parameters[n].argnames.push_back(args[i]);
|
||||
}
|
||||
|
||||
void CommandLine::adddescription(char n, unsigned num, const string d[]) {
|
||||
for (unsigned i=0; i<num; i++)
|
||||
parameters[n].description.push_back(d[i]);
|
||||
}
|
||||
|
||||
void CommandLine::addtoman_chapter(const string &name, const string &body) {
|
||||
if (man_chapters.find(name)==man_chapters.end()) {
|
||||
manchapter_order[man_numchapters]=name;
|
||||
man_numchapters++;
|
||||
}
|
||||
man_chapters[name].push_back(body);
|
||||
}
|
||||
|
||||
void CommandLine::addtoman_chapter(const string &name, unsigned line_count,
|
||||
const string body[]) {
|
||||
if (man_chapters.find(name)==man_chapters.end()) {
|
||||
manchapter_order[man_numchapters]=name;
|
||||
man_numchapters++;
|
||||
}
|
||||
for (unsigned i=0; i<line_count; i++)
|
||||
man_chapters[name].push_back(body[i]);
|
||||
}
|
||||
|
||||
void CommandLine::check(char n) {
|
||||
map<char,Parameter>::iterator m;
|
||||
m=parameters.find(n);
|
||||
if (m!=parameters.end()) {
|
||||
cerr << "DEVELOPER ERROR: Parameter: " << n << " set twice!\n";
|
||||
cerr << "commandline.h: Exiting...\n\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandLine::optargparams() {
|
||||
map<char,Parameter>::iterator m;
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++)
|
||||
if (m->second.manditory_args<m->second.num_args)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the number of arguments that are not parameters (' ' name)
|
||||
unsigned CommandLine::argsize() {
|
||||
return parameters[' '].args.size();
|
||||
}
|
||||
|
||||
// Whether or not this parameter was set
|
||||
bool CommandLine::set(char n) {
|
||||
return parameters[n].set;
|
||||
}
|
||||
|
||||
// Force a parameter to be unset
|
||||
void CommandLine::unset(char n) {
|
||||
parameters[n].set=false;
|
||||
}
|
||||
|
||||
char* CommandLine::arg(char n, unsigned num) {
|
||||
return parameters[n].args[num];
|
||||
}
|
||||
|
||||
int CommandLine::argint(char n, unsigned num) {
|
||||
return atoi(parameters[n].args[num]);
|
||||
}
|
||||
|
||||
double CommandLine::argdouble(char n, unsigned num) {
|
||||
return atof(parameters[n].args[num]);
|
||||
}
|
||||
|
||||
string CommandLine::argstring(char n, unsigned num) {
|
||||
string s;
|
||||
s=parameters[n].args[num];
|
||||
return s;
|
||||
}
|
||||
|
||||
bool CommandLine::parse(int argc, char* argv[], Error *error) {
|
||||
unsigned i;
|
||||
map<char,Parameter>::iterator m;
|
||||
char flag;
|
||||
int parameter; // Set to the parameter that arguments are being parsed
|
||||
|
||||
progname=a::filenameonly(argv[0]);
|
||||
full_line=string(argv[0]);
|
||||
for (unsigned i=1; i<unsigned(argc); i++)
|
||||
full_line+=' '+string(argv[i]);
|
||||
|
||||
int argnum=1;
|
||||
while (argnum<argc) {
|
||||
// Set an argument
|
||||
if (argv[argnum][0]!='-') {
|
||||
if (parameters[' '].args.size()==parameters[' '].num_args) {
|
||||
error->addwarning(3,9,"CommandLine","Invalid Command Line Argument: "+
|
||||
string(argv[argnum]));
|
||||
return false;
|
||||
}
|
||||
parameters[' '].set=true;
|
||||
parameters[' '].args.push_back(argv[argnum]);
|
||||
argnum++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set a parameter
|
||||
flag=argv[argnum][1];
|
||||
m=parameters.find(flag);
|
||||
if (m==parameters.end()) {
|
||||
error->addwarning(4,9,"CommandLine","Invalid Command Line Parameter: "+
|
||||
string(argv[argnum]));
|
||||
return false;
|
||||
}
|
||||
// Make sure all required arguments are set before parameters with
|
||||
// optional arguments
|
||||
if (m->second.manditory_args<m->second.num_args)
|
||||
if (parameters[' '].args.size()<parameters[' '].num_args) {
|
||||
error->buffer() << "Parameters with optional arguments must be "
|
||||
<< "placed after manditory commandline arguments";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
}
|
||||
|
||||
parameter=argnum;
|
||||
argnum++;
|
||||
m->second.set=true;
|
||||
|
||||
// Get the parameter arguments
|
||||
for (i=0; i<m->second.num_args; i++) {
|
||||
// Make sure we are not at the end of the parameter list
|
||||
if (argnum>=argc)
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
// Assure the right number of arguments for signed numbers
|
||||
if (argv[argnum][0]=='-' && m->second.dash==true)
|
||||
if (!isdigit(argv[argnum][1]))
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
// Assure the right number of arguments for other numbers
|
||||
if (argv[argnum][0]=='-' && m->second.dash==false)
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
m->second.args.push_back(argv[argnum]);
|
||||
argnum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If help was set, we do not need to check for manditory args
|
||||
if (help_set)
|
||||
if (parameters[help_param].set)
|
||||
return true;
|
||||
|
||||
// Assure that the manditory arguments were set for commandline
|
||||
if (parameters[' '].manditory)
|
||||
if (parameters[' '].args.size()<parameters[' '].manditory_args) {
|
||||
error->addwarning(6,9,"CommandLine","Missing Required Argument!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assure that manditory arguments were set for parameters!
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->second.manditory)
|
||||
if (m->second.set==false) {
|
||||
error->buffer() << "Missing Required Argument: \n\n";
|
||||
if (m->first!=' ')
|
||||
error->buffer() << "-" << m->first << " must be set!";
|
||||
error->addbuf(7,9,"CommandLine");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandLine::write_man_page(ostream & out, const string &version,
|
||||
const string &header) {
|
||||
unsigned i;
|
||||
map<char,Parameter>::iterator m;
|
||||
string bold="\\fB";
|
||||
string italic="\\fI";
|
||||
string regular="\\fR";
|
||||
|
||||
out << ".TH " << program_name() << " 1 \"" << a::date()
|
||||
<< "\"" << " \"" << program_name() << " (" << header << ") "
|
||||
<< version << "\" \"" << header << '\"' << endl;
|
||||
|
||||
// Go through the chapters
|
||||
map<unsigned,string>::iterator mc;
|
||||
for (mc=manchapter_order.begin(); mc!=manchapter_order.end(); mc++) {
|
||||
// NAME Section
|
||||
if (mc->second=="NAME") {
|
||||
out << ".SH NAME\n" << bold << program_name() << regular;
|
||||
if (man_chapters["NAME"].size()!=0) {
|
||||
out << " - ";
|
||||
for (i=0; i<man_chapters["NAME"].size(); i++)
|
||||
out << man_chapters["NAME"][i];
|
||||
}
|
||||
out << endl;
|
||||
continue;
|
||||
} // end NAME
|
||||
|
||||
// SYNOPSIS section
|
||||
if (mc->second=="SYNOPSIS" && man_chapters["SYNOPSIS"].empty()) {
|
||||
out << ".PD 2\n.SH SYNOPSIS\n.PD 1\n.TP\n";
|
||||
if (program_name().length()>6)
|
||||
out << bold << program_name() << regular << " ";
|
||||
else
|
||||
out << ".B " << program_name() << endl;
|
||||
out << format_synopsis(bold,italic,regular) << endl;
|
||||
if (program_name().length()>6)
|
||||
out << ".br\n";
|
||||
if (parameters[' '].num_args!=0 && optargparams())
|
||||
out << ".PD 2\n.PP\nParameters with optional arguments should be placed "
|
||||
<< "after manditory commandline arguments.\n";
|
||||
continue;
|
||||
} // end SYNOPSIS
|
||||
|
||||
// PARAMETERS
|
||||
if (mc->second=="PARAMETERS") {
|
||||
if (!(parameters.size()==0 ||
|
||||
(parameters.size()==1 && (parameters.begin())->first==' '))) {
|
||||
out << ".PD 2\n.SH PARAMETERS\n.PD 1\n";
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first==' ')
|
||||
continue;
|
||||
out << ".TP\n";
|
||||
out << format_parameter(m->first,bold,italic,regular) << endl;
|
||||
if (format_parameter(m->first,"","","").length()>6)
|
||||
out << ".PD 0\n.TP\n.PP\n.PD 1\n";
|
||||
// Output the description
|
||||
vector<string> fdesc=man_format(m->second.description,bold,
|
||||
italic,regular);
|
||||
for (i=0; i<fdesc.size(); i++)
|
||||
out << fdesc[i];
|
||||
out << endl;
|
||||
} // end for m=
|
||||
}
|
||||
continue;
|
||||
} // end PARAMETERS
|
||||
writeman_chapter(out,mc->second,bold,italic,regular);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::writeman_chapter(ostream &out,const string &name,
|
||||
const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
if (man_chapters[name].empty())
|
||||
return;
|
||||
|
||||
out << ".PD 2\n.SH " << name << "\n.PD 1\n";
|
||||
|
||||
vector<string> formatted=man_format(man_chapters[name],bold,italic,regular);
|
||||
for (unsigned i=0; i<formatted.size(); i++)
|
||||
out << formatted[i];
|
||||
out << endl;
|
||||
}
|
||||
|
||||
string CommandLine::format_synopsis(const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
string s;
|
||||
map<char,Parameter>::iterator m;
|
||||
bool space=false;
|
||||
|
||||
s=format_parameter(' ',bold,italic,regular)+" ";
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first==' ')
|
||||
continue;
|
||||
if (space)
|
||||
s+=' ';
|
||||
space=true;
|
||||
if (m->second.manditory==false)
|
||||
s+='[';
|
||||
s+=format_parameter(m->first,bold,italic,regular);
|
||||
if (m->second.manditory==false)
|
||||
s+="]";
|
||||
} // end for
|
||||
return s;
|
||||
}
|
||||
|
||||
// Write a synopsis in plain text format fitted to a given column width
|
||||
void CommandLine::write_text_synopsis(ostream &out, unsigned column_width) {
|
||||
string s=format_synopsis("","","");
|
||||
vector<string> lines;
|
||||
a::format_fit(column_width-program_name().length()-1,s,lines);
|
||||
out << program_name() << " ";
|
||||
for (unsigned i=0; i<lines.size(); i++) {
|
||||
out << lines[i] << endl;
|
||||
for (unsigned j=0; j<(program_name().length()+1); j++)
|
||||
out << " ";
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
|
||||
string CommandLine::format_parameter(char param, const string &bold,
|
||||
const string &italic,
|
||||
const string ®ular) {
|
||||
Parameter &p=parameters[param];
|
||||
|
||||
string strp="";
|
||||
if (param!=' ')
|
||||
strp=bold+"-"+param+regular;
|
||||
|
||||
if (p.num_args!=0)
|
||||
for (unsigned i=0; i<p.argnames.size(); i++) {
|
||||
if (!(param==' ' && i==0)) // Ignore first space on command args
|
||||
strp+=' ';
|
||||
if (i>=p.manditory_args)
|
||||
strp+='[';
|
||||
if (param!=' ')
|
||||
strp+=italic+p.argnames[i]+regular;
|
||||
else
|
||||
strp+=p.argnames[i];
|
||||
if (i>=p.manditory_args)
|
||||
strp+=']';
|
||||
}
|
||||
|
||||
if (p.argnames.size()<p.num_args)
|
||||
strp+=" [...]";
|
||||
|
||||
return strp;
|
||||
}
|
||||
|
||||
vector<string> CommandLine::man_format(const vector<string> &input,
|
||||
const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
vector<string> output;
|
||||
map<char,Parameter>::iterator m;
|
||||
|
||||
for (unsigned i=0; i<input.size(); i++) {
|
||||
string temp=input[i];
|
||||
a::str_replace("\n","\n.PD 0\n.PP\n.PD 1\n",temp);
|
||||
a::str_replace(".EN","\n.EN\n",temp);
|
||||
a::str_replace(".EQ","\n.EQ\n",temp);
|
||||
a::str_replace(".TP","\n.PD 0\n.TP\n.PP\n.PD 1\n",temp);
|
||||
a::str_replace(program_name(),bold+program_name()+regular,temp);
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first!=' ') {
|
||||
string source="-";
|
||||
source+=m->first;
|
||||
a::str_replace(source,bold+source+regular,temp);
|
||||
}
|
||||
for (unsigned j=0; j<m->second.argnames.size(); j++)
|
||||
a::str_replace(m->second.argnames[j],
|
||||
italic+m->second.argnames[j]+regular,temp);
|
||||
}
|
||||
output.push_back(temp);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/***************************************************************************
|
||||
commandline.h
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Command line parsing stuff..
|
||||
|
||||
begin : Sun Jun 11 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : mbrown@nirvana.unm.edu
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef COMMANDLINE_H
|
||||
#define COMMANDLINE_H
|
||||
|
||||
#include "error.h"
|
||||
#include "misc.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
/// Parsing of command-line parameters and automatic man page generation
|
||||
/** Allows manditory and optional command line arguments to be specified along
|
||||
* with parameters set using flags. For arguments that do not require flags,
|
||||
* a space char is used to set the flag. To specify the command line:
|
||||
*
|
||||
* foo input_file output_file -t signed_number [-o]
|
||||
*
|
||||
* \verbatim CommandLine cl;
|
||||
cl.addmanditory(' ',2);
|
||||
cl.addargname(' ',"input_file"); cl.addargname(' ',"output_file");
|
||||
cl.addsigned('t',1,1);
|
||||
cl.addargname('t',"arg_name");
|
||||
cl.adddescription('t',"Manditory parameter allowing signed_numbers");
|
||||
cl.add('o',0);
|
||||
\endverbatim
|
||||
* To instead specify that the outputfile is an optional argument:
|
||||
* \verbatim cl.addmanditory(' ',2,1) \endverbatim
|
||||
*
|
||||
* A help flag can also be set which does not require other command line
|
||||
* arguments to be set
|
||||
*
|
||||
* When the commandline is parsed, it is asserted that all manditory arguments
|
||||
* and flags are set, that each flag is set with the correct number of
|
||||
* parameters, and that no unknown flags have been set.
|
||||
*
|
||||
* One can check whether or not optional flags have been set using set() or
|
||||
* the [] operator:
|
||||
* \verbatim cl.set('o') <--> cl['o'] \endverbatim
|
||||
*
|
||||
* Man pages can be generated automatically by adding chapters. The SYNOPSIS
|
||||
* and description of commandline arguments and flags is generated
|
||||
* automatically. Examples of chapters that are consistently used are
|
||||
* NAME, VERSION, DESCRIPTION, PARAMETERS, USAGE, EXAMPLES, AUTHORS, BUGS,
|
||||
* SEE ALSO.
|
||||
*
|
||||
* The following characters can be used for formatting in parameter
|
||||
* descriptions and chapters:
|
||||
* \verbatim
|
||||
\t tab
|
||||
\n forced newline
|
||||
.TP new paragraph (margin indented)
|
||||
\\fB all following text is bold
|
||||
\\fI all following text is italic
|
||||
\\fR all following text is regular
|
||||
\endverbatim
|
||||
*
|
||||
* The arguments, flags and parameter_names are automatically formatted
|
||||
* throughout the man page with bold and italic typeface.
|
||||
**/
|
||||
class CommandLine {
|
||||
public:
|
||||
CommandLine();
|
||||
~CommandLine();
|
||||
|
||||
/// Add an optional argument which takes num parameters
|
||||
/** \note Use ' ' for n to specify an argument with no flag
|
||||
* \param n flag used to pass arguments (i.e. -f)
|
||||
* \param num the number of arguments that must be specified after flag */
|
||||
void add(char n, unsigned num);
|
||||
/// Add a manditory argument which takes num parameters
|
||||
/** \sa add() **/
|
||||
void addmanditory(char n, unsigned num);
|
||||
/// Add a flag which can take signed numbers as parameters
|
||||
/** \sa add() **/
|
||||
void addsigned(char n, unsigned num);
|
||||
|
||||
/// Add an optional flag with minimum and maximum number of args
|
||||
/** \sa add() **/
|
||||
void add(char n, unsigned num, unsigned man_num);
|
||||
/// Add a manditory flag with minimum and maximum number of args
|
||||
/** \sa add() **/
|
||||
void addmanditory(char n, unsigned num, unsigned man_num);
|
||||
/// Add a flag with minimum and maximum number of args that takes signed nums
|
||||
/** \sa add() **/
|
||||
void addsigned(char n, unsigned num, unsigned man_num);
|
||||
|
||||
/// Add a help argument (does not require other manditory arguments be set)
|
||||
/** \sa add() **/
|
||||
void addhelp(char n, unsigned num);
|
||||
|
||||
/// Specify the names for arguments in the synopsis (for man page)
|
||||
/** The names can be added one by one in the order of the flag parameters **/
|
||||
void addargname(char n, const string &an);
|
||||
/// Specify the names for arguments in the synopsis (for man page)
|
||||
void addargnames(char n, unsigned num, const string args[]);
|
||||
/// Specify the description for an argument (for the man page SYNOPSIS)
|
||||
/** See the class description for formating characters **/
|
||||
void adddescription(char n, const string &d);
|
||||
/// Specify the description for an argument (for the man page SYNOPSIS)
|
||||
/** See the class description for formating characters **/
|
||||
void adddescription(char n, unsigned num, const string d[]);
|
||||
/// Add a man page chapter with title 'name'
|
||||
void addtoman_chapter(const string &name,const string &body);
|
||||
/// Add a man page chapter with title 'name'
|
||||
void addtoman_chapter(const string &name,unsigned line_count,
|
||||
const string body[]);
|
||||
|
||||
/// Returns the number of arguments that are not flags (char n=' ')
|
||||
unsigned argsize();
|
||||
/// Returns the number of parameters passed for a given flag
|
||||
unsigned argsize(char n);
|
||||
/// Returns true if the optional flag was set on the commandline
|
||||
bool set(char n);
|
||||
/// Returns true if the optional flag was set on the commandline
|
||||
bool operator [](char n);
|
||||
|
||||
/// Force a parameter to be unset
|
||||
void unset(char n);
|
||||
|
||||
/// Return flag parameter or argument as a cstring (0-based index)
|
||||
char *arg(char n, unsigned num);
|
||||
/// Return flag parameter or argument as a integer (0-based index)
|
||||
int argint(char n, unsigned num);
|
||||
/// Return flag parameter or argument as a double (0-based index)
|
||||
double argdouble(char n, unsigned num);
|
||||
/// Return flag parameter or argument as a string (0-based index)
|
||||
string argstring(char n, unsigned num);
|
||||
|
||||
/// Parse the command line arguments
|
||||
bool parse(int argc, char* argv[], Error *error);
|
||||
|
||||
/// Return the program name
|
||||
string program_name();
|
||||
/// Return a string with the entire commandline as entered
|
||||
string full_command_line();
|
||||
/// Write out a man_page
|
||||
void write_man_page(ostream & out, const string &version,
|
||||
const string &header);
|
||||
|
||||
/// Advanced writing of man page
|
||||
void writeman_chapter(ostream &out, const string &name, const string &bold,
|
||||
const string &italic, const string ®ular);
|
||||
|
||||
/// Return a string with all of the options in a man page synopsis format
|
||||
string format_synopsis(const string &bold, const string &italic,
|
||||
const string ®ular);
|
||||
/// Write a synopsis in plain text format fitted to a given column width
|
||||
void write_text_synopsis(ostream &out, unsigned column_width);
|
||||
|
||||
private:
|
||||
string full_line;
|
||||
void check(char n);
|
||||
// Returns true if parameters have been set with optional arguments
|
||||
bool optargparams();
|
||||
|
||||
class Parameter;
|
||||
map<char,Parameter> parameters;
|
||||
|
||||
bool help_set; // True if there is a parameter for getting help
|
||||
char help_param; // Parameter for help
|
||||
|
||||
// Stuff for man page
|
||||
string progname; // The name for the program (argv[0])
|
||||
unsigned man_numchapters; // Number of chapters in man page
|
||||
map<string,vector<string> > man_chapters;
|
||||
map<unsigned, string> manchapter_order;
|
||||
|
||||
// Format a parameter as a string with argument names
|
||||
string format_parameter(char param, const string &bold, const string &italic,
|
||||
const string ®ular);
|
||||
// Formats the strings in input for a man page by replacing newlines and
|
||||
// adding bold and italic fonts to parameters and arguments respectively
|
||||
vector<string> man_format(const vector<string> &input, const string &bold,
|
||||
const string &italic, const string ®ular);
|
||||
|
||||
};
|
||||
|
||||
// This class is for internal use within CommandLine
|
||||
class CommandLine::Parameter {
|
||||
public:
|
||||
friend class CommandLine;
|
||||
Parameter();
|
||||
~Parameter();
|
||||
|
||||
private:
|
||||
unsigned num_args; // Maximum number of arguments for the parameter
|
||||
unsigned manditory_args; // Minimum number of arguments for the parameter
|
||||
bool manditory; // This parameter MUST be set
|
||||
|
||||
bool dash; // Allow for signed numbers (dashes in args)
|
||||
|
||||
bool set; // This parameter has been set
|
||||
vector<char *> args;
|
||||
|
||||
// Strings for man page description
|
||||
vector<string> argnames; // Names for each argument to the parameter
|
||||
vector<string> description; // Description for how to set this parameter
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,279 @@
|
|||
/***************************************************************************
|
||||
error.cpp
|
||||
-------------------
|
||||
|
||||
Class for error handling
|
||||
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Thu Oct 9 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "error.h"
|
||||
|
||||
Notice::Notice() {
|
||||
nullout=new ostream(NULL);
|
||||
noteout=&cout;
|
||||
notice_level=9;
|
||||
}
|
||||
|
||||
Notice::~Notice() {
|
||||
if (nullout!=NULL)
|
||||
delete nullout;
|
||||
}
|
||||
|
||||
// Returns a null stream if level is two high, else returns notice stream
|
||||
ostream & Notice::operator[] (const unsigned level) {
|
||||
if (level<=notice_level)
|
||||
return *noteout;
|
||||
else
|
||||
return *nullout;
|
||||
}
|
||||
|
||||
void Notice::setostream(ostream &out) {
|
||||
noteout=&out;
|
||||
}
|
||||
|
||||
void Notice::set_notice_level(unsigned l) {
|
||||
notice_level=l;
|
||||
}
|
||||
|
||||
unsigned Notice::get_notice_level() {
|
||||
return notice_level;
|
||||
}
|
||||
|
||||
void Notice::notice(unsigned level, const string calling_class,
|
||||
const string note) {
|
||||
if (level<notice_level)
|
||||
*noteout << calling_class << "::" << note;
|
||||
}
|
||||
|
||||
void Notice::notice(unsigned level,const string calling_class,
|
||||
vector<string> ¬es) {
|
||||
if (level<=notice_level) {
|
||||
*noteout << calling_class << "::";
|
||||
for (unsigned i=0; i<notes.size(); i++)
|
||||
*noteout << notes[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Notice::notice(unsigned level, const string note) {
|
||||
if (level<=notice_level)
|
||||
*noteout << note;
|
||||
}
|
||||
|
||||
void Notice::notice(unsigned level, vector<string> ¬es) {
|
||||
if (level<=notice_level)
|
||||
for (unsigned i=0; i<notes.size(); i++)
|
||||
*noteout << notes[i];
|
||||
}
|
||||
|
||||
Error::Error() {
|
||||
nullout=new ostream(NULL);
|
||||
unhandled_warnings=0;
|
||||
handled_warnings=0;
|
||||
max_level=9;
|
||||
min_level=2;
|
||||
|
||||
handleatend=true;
|
||||
writetotalatend=true;
|
||||
|
||||
errout=&cerr;
|
||||
logout=nullout;
|
||||
column_width=70;
|
||||
}
|
||||
|
||||
Error::~Error() {
|
||||
if (handleatend && unhandled_warnings!=0)
|
||||
writewarnings();
|
||||
if (writetotalatend && total_warnings()!=0)
|
||||
writetotals(0);
|
||||
if (nullout!=NULL)
|
||||
delete nullout;
|
||||
}
|
||||
|
||||
// Set a log file for error AND notice output
|
||||
void Error::set_logfile(ostream &out) {
|
||||
logout=&out;
|
||||
note.setostream(out);
|
||||
}
|
||||
|
||||
// Total number of warnings
|
||||
unsigned Error::total_warnings() {
|
||||
return unhandled_warnings+handled_warnings;
|
||||
}
|
||||
|
||||
// Returns the number of errors generated with ID
|
||||
unsigned Error::operator[](unsigned id) {
|
||||
warning_iter m;
|
||||
m=warning_list.find(id);
|
||||
if (m==warning_list.end())
|
||||
return 0;
|
||||
return m->second.size();
|
||||
}
|
||||
|
||||
void Error::addwarning(unsigned ID, unsigned level, const string calling_class,
|
||||
const string warning) {
|
||||
if (level<min_level)
|
||||
return;
|
||||
if (level>max_level)
|
||||
generate_error(ID,calling_class,warning);
|
||||
vector<ErrCom> *e=&(warning_list[ID]);
|
||||
e->push_back(ErrCom());
|
||||
e->back().level=level;
|
||||
e->back().calling_class=calling_class;
|
||||
e->back().message=warning;
|
||||
unhandled_warnings++;
|
||||
}
|
||||
|
||||
void Error::generate_error(unsigned ID, const string calling_class,
|
||||
const string error) {
|
||||
ErrCom err;
|
||||
err.level=max_level+1;
|
||||
err.calling_class=calling_class;
|
||||
err.message=error;
|
||||
|
||||
if (warnings()!=0)
|
||||
writewarnings();
|
||||
write_err(ID,err);
|
||||
writetotals(1);
|
||||
#ifdef MUSE_MPI
|
||||
MPI_Abort ( MPI_COMM_WORLD, 1 );
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add an error/warning (Program termination if level >= max level
|
||||
ostringstream & Error::buffer() {
|
||||
return buffer_stream;
|
||||
}
|
||||
|
||||
// Generate warning with message in buffer
|
||||
void Error::addbuf(unsigned ID, unsigned level, const string calling_class) {
|
||||
addwarning(ID,level,calling_class,buffer_stream.str());
|
||||
buffer_stream.str("");
|
||||
}
|
||||
|
||||
// Generate serious error with message in buffer
|
||||
void Error::addbuf(unsigned ID, const string calling_class) {
|
||||
generate_error(ID,calling_class,buffer_stream.str());
|
||||
}
|
||||
|
||||
unsigned Error::warnings() {
|
||||
return unhandled_warnings;
|
||||
}
|
||||
|
||||
void Error::writeline() {
|
||||
*errout << "+";
|
||||
*logout << "+";
|
||||
for (unsigned i=0; i<column_width-2; i++) {
|
||||
*errout << "-";
|
||||
*logout << "-";
|
||||
}
|
||||
*errout << "+\n";
|
||||
*logout << "+\n";
|
||||
}
|
||||
|
||||
void Error::write_err(unsigned ID, ErrCom &err) {
|
||||
if (err.level<min_level)
|
||||
return;
|
||||
|
||||
*errout << "\n";
|
||||
*logout << "\n";
|
||||
writeline();
|
||||
(*errout).setf(ios::left);
|
||||
(*errout).unsetf(ios::right);
|
||||
|
||||
// Output the IDs
|
||||
unsigned width12=(unsigned)floor((double)(column_width-10)/3.0);
|
||||
unsigned width3=column_width-10-width12-width12;
|
||||
string et;
|
||||
unsigned width1;
|
||||
if (err.level>max_level) {
|
||||
et="| Error: "; width1=width12-7;
|
||||
} else {
|
||||
et="| Warning: "; width1=width12-9;
|
||||
}
|
||||
*errout << et << setw(width1) << ID << " | Level: "
|
||||
<< setw(width12-7) << err.level << " | " << setw(width3)
|
||||
<< err.calling_class << " |\n";
|
||||
*logout << et << setw(width1) << ID << " | Level: "
|
||||
<< setw(width12-7) << err.level << " | " << setw(width3)
|
||||
<< err.calling_class << " |\n";
|
||||
writeline();
|
||||
|
||||
// Output the message
|
||||
vector <string> messages;
|
||||
a::format_fit(column_width-3,err.message,messages);
|
||||
for (unsigned i=0; i<messages.size(); i++) {
|
||||
*errout << "| " << setw(column_width-3) << messages[i] << "|\n";
|
||||
*logout << "| " << setw(column_width-3) << messages[i] << "|\n";
|
||||
}
|
||||
writeline();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Error::writewarning(unsigned ID) {
|
||||
for (unsigned i=0; i<warning_list[ID].size(); i++)
|
||||
write_err(ID,warning_list[ID][i]);
|
||||
handled_warnings+=warning_list[ID].size();
|
||||
dismiss_all_warnings(ID);
|
||||
return;
|
||||
}
|
||||
|
||||
void Error::dismiss_warning(unsigned ID) {
|
||||
warning_iter m;
|
||||
m=warning_list.find(ID);
|
||||
if (m==warning_list.end())
|
||||
return;
|
||||
unhandled_warnings--;
|
||||
if (m->second.size()==1)
|
||||
warning_list.erase(m);
|
||||
else
|
||||
m->second.erase(m->second.end()--);
|
||||
}
|
||||
|
||||
void Error::dismiss_all_warnings(unsigned ID) {
|
||||
warning_iter m;
|
||||
m=warning_list.find(ID);
|
||||
if (m==warning_list.end())
|
||||
return;
|
||||
unhandled_warnings-=m->second.size();
|
||||
warning_list.erase(m);
|
||||
}
|
||||
|
||||
void Error::writewarnings() {
|
||||
while (warning_list.size()>0)
|
||||
writewarning(warning_list.begin()->first);
|
||||
return;
|
||||
}
|
||||
|
||||
void Error::dismiss_warnings() {
|
||||
while (warning_list.size()>0)
|
||||
dismiss_warning(warning_list.begin()->first);
|
||||
return;
|
||||
}
|
||||
|
||||
// Write out the total warnings and errors
|
||||
void Error::writetotals(unsigned errorcount) {
|
||||
*errout << "\n";
|
||||
*logout << "\n";
|
||||
writeline();
|
||||
(*errout).setf(ios::left);
|
||||
(*errout).unsetf(ios::right);
|
||||
unsigned width1=(unsigned)floor((double)(column_width-7)/2.0);
|
||||
unsigned width2=column_width-7-width1;
|
||||
string swarnings="Total Warnings: "+a::itoa(handled_warnings+
|
||||
unhandled_warnings);
|
||||
string serrors="Total Errors: "+a::itoa(errorcount);
|
||||
*errout << "| " << setw(width1) << swarnings << " | " << setw(width2)
|
||||
<< serrors << " |\n";
|
||||
*logout << "| " << setw(width1) << swarnings << " | " << setw(width2)
|
||||
<< serrors << " |\n";
|
||||
writeline();
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/***************************************************************************
|
||||
error.h
|
||||
-------------------
|
||||
|
||||
Class for error handling
|
||||
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Thu Oct 9 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ERRORCLASS
|
||||
#define ERRORCLASS
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef MUSE_MPI
|
||||
#include <mpi.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
// forward declarations
|
||||
namespace a {
|
||||
string itoa(unsigned int);
|
||||
void format_fit(unsigned, const string &, vector<string> &);
|
||||
}
|
||||
|
||||
/// Notice Class for Handling Object Output
|
||||
/** A notice object stores an ostream for output and a notice_level.
|
||||
* All output is sent along with a level. Any output whose level is
|
||||
* greater than notice_level is sent to a null stream. The C++ output
|
||||
* operator '<<' can be used with the Notice operator '[]' which passes
|
||||
* the level:
|
||||
* \verbatim notice_object[29] << "This notice has level 29" << endl;
|
||||
* \endverbatim
|
||||
*
|
||||
* The guidelines for output notice levels are:
|
||||
* - \e 0: Information that must be output
|
||||
* - \e 1 - 9: Normal program output
|
||||
* - \e 10-19: Parameters useful for storing how the program was run
|
||||
* - \e 20-29: Extraneous information useful that may be useful to user
|
||||
* - \e 30- : Debugging information */
|
||||
class Notice {
|
||||
public:
|
||||
/// Standard output (cout) is the default notice output ostream
|
||||
/** The default maximum notice level is 9 \e (notice_level=10) */
|
||||
Notice();
|
||||
~Notice();
|
||||
|
||||
/// Set the output stream for notice output
|
||||
void setostream(ostream &out);
|
||||
|
||||
/// Returns a null stream if level is two high, else returns notice stream
|
||||
ostream & operator[] (const unsigned level);
|
||||
|
||||
/// Set the degree of program output
|
||||
void set_notice_level(unsigned l);
|
||||
/// Get the degree of program output
|
||||
unsigned get_notice_level();
|
||||
/// Generate a notice with a specified calling class
|
||||
void notice(unsigned level, const string calling_class, const string note);
|
||||
/// Generate a notice with a specified calling class
|
||||
void notice(unsigned level, const string calling_class,
|
||||
vector<string> ¬es);
|
||||
/// Generate a notice
|
||||
void notice(unsigned level, const string note);
|
||||
/// Generate a notice
|
||||
void notice(unsigned level, vector<string> ¬e);
|
||||
|
||||
private:
|
||||
unsigned notice_level;
|
||||
|
||||
ostream *nullout; // Null stream for redirecting output to nowhere
|
||||
ostream *noteout; // Output for notices
|
||||
};
|
||||
|
||||
/// Error and Notice Handling
|
||||
/** This class is intended to handle all output to the user. Output is
|
||||
* divided into notices and warnings/errors. Output of any message is
|
||||
* associated with a level. For notices, if level is greater than or equal to
|
||||
* max_notice_level, no output is generated. For warnings, if level is less
|
||||
* than min_warning_level, it is dismissed with no output. If the level is
|
||||
* greater than max_warning_level, the program is terminated and all warnings
|
||||
* and errors are output.
|
||||
*
|
||||
* \note By default, on destruction of an Error object, all unhandled
|
||||
* warnings and errors are output
|
||||
*
|
||||
* A log file can be specified for each object. In this case, all notices
|
||||
* are output to the log file only and errors are output to both stderr
|
||||
* and the log file
|
||||
*
|
||||
* Errors can be generated with a string or using the internal message buffer:
|
||||
\verbatim
|
||||
Error error;
|
||||
error.buffer() << "Incorrect file format for file: " << filename;
|
||||
error.addbuf(512,19,"FooClass";
|
||||
// --- OR
|
||||
string message = "Incorrect file format for file: "+filename;
|
||||
error.addwarning(512,19,"FooClass",message);
|
||||
\endverbatim
|
||||
*
|
||||
* Newlines will be inserted into the error message automatically in order
|
||||
* to format it for the string. Forced newlines can be specified with \n
|
||||
*
|
||||
* Programs can check whether or not errors have been generated using the []
|
||||
* operator and can 'handle' them by outputing the message or dismissing
|
||||
* them without any output
|
||||
*
|
||||
* Notices are generated using the public Notice class (see Notice())
|
||||
*
|
||||
* \b Error \b Levels:
|
||||
* - \e 0 - 1: Errors expected to happen during normal execution
|
||||
* - \e 2 - 9: Errors that a non-interactive program can handle and continue
|
||||
* - \e 10-19: Errors that interactive program can handle (file not found,etc.)
|
||||
* - \e 20- : Serious errors that should terminate execution
|
||||
**/
|
||||
class Error {
|
||||
public:
|
||||
/// Default constructor (use cerr for output and no log file)
|
||||
/** Default max notice level is 9, min warning level is 2, and max warning
|
||||
* level is 9 */
|
||||
Error();
|
||||
~Error();
|
||||
|
||||
/// Set a log file for error AND notice output
|
||||
void set_logfile(ostream &out);
|
||||
|
||||
/// Returns the number of errors (if any) generated with id
|
||||
unsigned operator[](unsigned id);
|
||||
|
||||
/// Add warning, terminate if level is greater than max level
|
||||
/** Newlines will be inserted into the message automatically when the
|
||||
* message is formatted for output. However, forced newlines can also
|
||||
* be inserted. **/
|
||||
void addwarning(unsigned ID, unsigned level, const string calling_class,
|
||||
const string warning);
|
||||
/// Add serious error (terminates execution)
|
||||
void generate_error(unsigned ID, const string calling_class,
|
||||
const string error);
|
||||
|
||||
/// Add an message to the error buffer. Warning generated with addbuf()
|
||||
/** Newlines will be inserted into the message automatically when the
|
||||
* message is formatted for output. However, forced newlines can also
|
||||
* be inserted.
|
||||
*
|
||||
\verbatim
|
||||
Error error;
|
||||
error.buffer() << "Choice not supported: " << choice;
|
||||
error.addbuf(512,9,"FooClass");
|
||||
\endverbatim **/
|
||||
ostringstream & buffer();
|
||||
/// Generate warning with message in buffer
|
||||
/** \sa buffer() **/
|
||||
void addbuf(unsigned ID, unsigned level, const string calling_class);
|
||||
/// Generate serious error with message in buffer
|
||||
/** \sa buffer() **/
|
||||
void addbuf(unsigned ID, const string calling_class);
|
||||
|
||||
/// Number of Unhandled Warnings
|
||||
unsigned warnings();
|
||||
/// Total number of warnings
|
||||
unsigned total_warnings();
|
||||
|
||||
/// Handle all warnings with this ID by writing them to out
|
||||
void writewarning(unsigned ID);
|
||||
/// Handle LAST warning with this ID WITHOUT writing it
|
||||
void dismiss_warning(unsigned ID);
|
||||
/// Handle ALL warnings with this ID WITHOUT writing it
|
||||
void dismiss_all_warnings(unsigned ID);
|
||||
/// Handle all warnings by writing them out
|
||||
void writewarnings();
|
||||
/// Handle all warnings without writing
|
||||
void dismiss_warnings();
|
||||
|
||||
/// Write out the total warnings (write errorcount errors)
|
||||
void writetotals(unsigned errorcount);
|
||||
|
||||
/// For generating notices
|
||||
/** \sa Notice **/
|
||||
Notice note;
|
||||
private:
|
||||
struct ErrCom;
|
||||
map<unsigned,vector<ErrCom> > warning_list;
|
||||
typedef multimap<unsigned, vector<ErrCom> >::iterator warning_iter;
|
||||
unsigned handled_warnings;
|
||||
unsigned unhandled_warnings;
|
||||
bool handleatend; // Write any unhandled errors on destruct
|
||||
bool writetotalatend; // Write totals on destruct if not 0
|
||||
|
||||
unsigned min_level; // Don't output warnings less than min_level
|
||||
unsigned max_level; // if a warning has a level>max_level error!
|
||||
ostream *errout, *logout; // Output for errors and warnings!
|
||||
ostream *nullout; // No output
|
||||
|
||||
ostringstream buffer_stream; // For creating messages for warnings
|
||||
|
||||
unsigned column_width;
|
||||
void write_err(unsigned ID, ErrCom &err);
|
||||
void writeline();
|
||||
};
|
||||
|
||||
struct Error::ErrCom {
|
||||
unsigned level;
|
||||
string calling_class;
|
||||
string message;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,592 @@
|
|||
/***************************************************************************
|
||||
glsurface.cpp
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Store and manipulate surfaces as OpenGL primitives
|
||||
|
||||
begin : Sun Jun 8 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "glsurface.h"
|
||||
|
||||
GLSurface::GLSurface(){
|
||||
}
|
||||
GLSurface::~GLSurface(){
|
||||
}
|
||||
|
||||
// Operations on GLline structure
|
||||
bool operator < (const GLline &one, const GLline &two) {
|
||||
unsigned minone, mintwo, maxone, maxtwo;
|
||||
|
||||
if (one.points[0]<one.points[1]) {
|
||||
minone=one.points[0];
|
||||
maxone=one.points[1];
|
||||
} else {
|
||||
minone=one.points[1];
|
||||
maxone=one.points[0];
|
||||
}
|
||||
if (two.points[0]<two.points[1]) {
|
||||
mintwo=two.points[0];
|
||||
maxtwo=two.points[1];
|
||||
} else {
|
||||
mintwo=two.points[1];
|
||||
maxtwo=two.points[0];
|
||||
}
|
||||
|
||||
if (minone<mintwo)
|
||||
return true;
|
||||
else if (minone==mintwo)
|
||||
if (maxone<maxtwo)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const GLline &one, const GLline &two) {
|
||||
if (one.points[0]==two.points[0] && one.points[1]==two.points[1])
|
||||
return true;
|
||||
if (one.points[0]==two.points[1] && one.points[1]==two.points[0])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLSurface::clear() {
|
||||
gllines.clear();
|
||||
linestrips.clear();
|
||||
triangles.clear();
|
||||
vertices.clear();
|
||||
xmesh.clear();
|
||||
ymesh.clear();
|
||||
zmesh.clear();
|
||||
}
|
||||
|
||||
// Reserve vector space for specified number of vertices and triangles
|
||||
void GLSurface::reserve(unsigned num_v, unsigned num_t) {
|
||||
vertices.reserve(num_v); triangles.reserve(num_t);
|
||||
}
|
||||
|
||||
// Add a triangle
|
||||
void GLSurface::addtriangle(Triangle &t) {
|
||||
triangles.push_back(t);
|
||||
}
|
||||
|
||||
// Add a vertex
|
||||
void GLSurface::addvertex(Vertex &v) {
|
||||
vertices.push_back(v);
|
||||
}
|
||||
|
||||
// Add many triangles (via swap)
|
||||
void GLSurface::addtriangles(vector<Triangle> &t) {
|
||||
triangles.swap(t);
|
||||
}
|
||||
|
||||
// Add many lines (via swap)
|
||||
void GLSurface::addlinestrips(vector<LineStrip> &l) {
|
||||
linestrips.swap(l);
|
||||
}
|
||||
|
||||
// Add a mesh (via swap)
|
||||
void GLSurface::addxyzmesh(vector<GLline> &x,vector<GLline> &y,
|
||||
vector<GLline> &z) {
|
||||
xmesh.swap(x); ymesh.swap(y); zmesh.swap(z);
|
||||
}
|
||||
|
||||
// Preconditions:
|
||||
// Triangles all loaded with correct vertex ordering
|
||||
// Vertices all loaded
|
||||
// Vertices that need to be calculated are marked as invalid
|
||||
// Postconditions:
|
||||
// For any normals that are marked as invalid, calculate normals by
|
||||
// averaging normals for each triangle
|
||||
void GLSurface::calculatenormals() {
|
||||
unsigned i;
|
||||
|
||||
// Set all invalid normals to zero
|
||||
for (i=0; i<vertices.size(); i++)
|
||||
if (vertices[i].valid_normal==false)
|
||||
vertices[i].normal=vectorPt(0,0,0);
|
||||
|
||||
for (i=0; i<triangles.size(); i++) {
|
||||
vectorPt vec1, vec2, normal;
|
||||
unsigned id0, id1, id2;
|
||||
id0=triangles[i].point[0];
|
||||
id1=triangles[i].point[1];
|
||||
id2=triangles[i].point[2];
|
||||
vec1=vertices[id1].cpt-vertices[id0].cpt;
|
||||
vec2=vertices[id2].cpt-vertices[id0].cpt;
|
||||
normal[X]=vec1[Z]*vec2[Y]-vec1[Y]*vec2[Z];
|
||||
normal[Y]=vec1[X]*vec2[Z]-vec1[Z]*vec2[X];
|
||||
normal[Z]=vec1[Y]*vec2[X]-vec1[X]*vec2[Y];
|
||||
// Only do vertex averaging if the normal has not been
|
||||
// explicitly set
|
||||
if (vertices[id0].valid_normal==false)
|
||||
vertices[id0].normal+=normal;
|
||||
if (vertices[id1].valid_normal==false)
|
||||
vertices[id1].normal+=normal;
|
||||
if (vertices[id2].valid_normal==false)
|
||||
vertices[id2].normal+=normal;
|
||||
}
|
||||
|
||||
// Mark all normals as valid
|
||||
for (i=0; i<vertices.size(); i++)
|
||||
if (vertices[i].valid_normal==false) {
|
||||
vertices[i].valid_normal=true;
|
||||
double no=vertices[i].normal.norm();
|
||||
if (no==0)
|
||||
vertices[i].normal=ORIGIN;
|
||||
else
|
||||
vertices[i].normal/=no*-1;
|
||||
}
|
||||
//error->note[31] << "Calculated normals: " << flush;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Normalize normals.
|
||||
void GLSurface::normalize() {
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<vertices.size(); i++) {
|
||||
vertices[i].normal.normalize();
|
||||
if (am::not_nan(vertices[i].normal.x)==false) {
|
||||
cerr << "Bad normal!"; // cerr fix me
|
||||
vertices[i].normal=vectorPt(0,0,0);
|
||||
}
|
||||
}
|
||||
//error->note[31] << "Normalized normals: " << flush;
|
||||
}
|
||||
|
||||
// Flip normals
|
||||
void GLSurface::flipnormals() {
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<vertices.size(); i++)
|
||||
vertices[i].normal*=-1.0;
|
||||
//error->note[31] << "Flipped normals: " << flush;
|
||||
}
|
||||
|
||||
// Calculate the Area of the Surface
|
||||
double GLSurface::surfacearea() {
|
||||
double sa=0;
|
||||
|
||||
for (unsigned i=0; i<triangles.size(); i++)
|
||||
sa+=triarea(triangles[i]);
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
double GLSurface::triarea(Triangle &t) {
|
||||
double a=vertices[t.point[0]].cpt.dist(vertices[t.point[1]].cpt);
|
||||
double b=vertices[t.point[1]].cpt.dist(vertices[t.point[2]].cpt);
|
||||
double c=vertices[t.point[0]].cpt.dist(vertices[t.point[2]].cpt);
|
||||
double d=a+b+c;
|
||||
|
||||
return (sqrt(d*(d-a)*(d-b)*(d-c))/4);
|
||||
}
|
||||
|
||||
// Color surfaces
|
||||
void GLSurface::color(const colorPt &color) {
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<vertices.size(); i++)
|
||||
vertices[i].color=color;
|
||||
}
|
||||
|
||||
void GLSurface::colorbygradient(const colorPt &start, const colorPt &end) {
|
||||
colorPt step, current;
|
||||
unsigned i;
|
||||
|
||||
step=(end-start)/double(vertices.size());
|
||||
current=start;
|
||||
for (i=0; i<vertices.size(); i++) {
|
||||
vertices[i].color=current;
|
||||
current+=step;
|
||||
}
|
||||
}
|
||||
|
||||
void GLSurface::colorbymarker(const colorPt &zero, const colorPt &nonzero) {
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<vertices.size(); i++) {
|
||||
if (vertices[i].marker==0)
|
||||
vertices[i].color=zero;
|
||||
else
|
||||
vertices[i].color=nonzero;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Color a surface based on interpolation of values on a grid
|
||||
// void GLSurface::colorbygrid(GridNUM<double> &grid,const colorPt &neg,
|
||||
// const colorPt &mid, const colorPt &pos, double minv,
|
||||
// double midv, double maxv) {
|
||||
// Colors c;
|
||||
// for (unsigned i=0; i<vertices.size(); i++)
|
||||
// vertices[i].color=c.gradient(minv,midv,maxv,grid.interp(vertices[i].cpt),
|
||||
// neg,mid,pos);
|
||||
// }
|
||||
|
||||
void GLSurface::set_transparency(double alpha) {
|
||||
for (unsigned i=0; i<vertices.size(); i++)
|
||||
vertices[i].transparency=alpha;
|
||||
}
|
||||
|
||||
// Write out triangles as BEGIN,TRIANGLES,END primitives
|
||||
void GLSurface::writetris(ofstream &out, const string &objname) {
|
||||
unsigned i,j,k;
|
||||
int index;
|
||||
|
||||
writepymolheader(out);
|
||||
out << "BEGIN, TRIANGLES," << endl;
|
||||
for (i=0; i<triangles.size(); i++) {
|
||||
// Output coords, colors, and normals of points
|
||||
for (j=0; j<3; j++) {
|
||||
index=triangles[i].point[j];
|
||||
// if (vertices[index].transparency!=1)
|
||||
out << "ALPHA," << vertices[index].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].color[k] << ",";
|
||||
if (vertices[index].valid_normal) {
|
||||
out << "NORMAL,";
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[index].normal[k] << ",";
|
||||
}
|
||||
out << "VERTEX,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].cpt[k] << ",";
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
out << "END";
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out triangles as TRIANGLE primitives
|
||||
void GLSurface::writetris_surf(ofstream &out, const string &objname) {
|
||||
unsigned i,j,k;
|
||||
int index;
|
||||
|
||||
writepymolheader(out);
|
||||
for (i=0; i<triangles.size(); i++) {
|
||||
// if (vertices[triangles[i].point[0]].transparency!=1)
|
||||
out << "ALPHA," << vertices[triangles[i].point[0]].transparency << ",";
|
||||
out << "TRIANGLE,";
|
||||
// Output coords of points
|
||||
for (j=0; j<3; j++) {
|
||||
index=triangles[i].point[j];
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].cpt[k] << ",";
|
||||
}
|
||||
// Output normals of points
|
||||
for (j=0; j<3; j++) {
|
||||
index=triangles[i].point[j];
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].normal[k] << ",";
|
||||
}
|
||||
// Output colors of points
|
||||
for (j=0; j<3; j++) {
|
||||
index=triangles[i].point[j];
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[index].color[k] << ",";
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out triangles as POINTS
|
||||
void GLSurface::writetris_points(ofstream &out, const string &objname) {
|
||||
unsigned i,k;
|
||||
|
||||
writepymolheader(out);
|
||||
out << "BEGIN, POINTS," << endl;
|
||||
for (i=0; i<vertices.size(); i++) {
|
||||
// Output coords, colors, and normals of points
|
||||
// if (vertices[i].transparency!=1)
|
||||
out << "ALPHA," << vertices[i].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[i].color[k] << ",";
|
||||
if (vertices[i].valid_normal) {
|
||||
out << "NORMAL,";
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[i].normal[k] << ",";
|
||||
}
|
||||
out << "VERTEX,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[i].cpt[k] << ",";
|
||||
out << endl;
|
||||
}
|
||||
out << "END\n";
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out triangles as POINTS
|
||||
void GLSurface::write_vspheres(ofstream &out, const string &objname,
|
||||
double radius) {
|
||||
unsigned i,k;
|
||||
|
||||
writepymolheader(out);
|
||||
for (i=0; i<vertices.size(); i++) {
|
||||
// Output coords, colors, and normals of points
|
||||
// if (vertices[i].transparency!=1)
|
||||
out << "ALPHA," << vertices[i].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[i].color[k] << ",";
|
||||
out << "SPHERE,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[i].cpt[k] << ",";
|
||||
out << radius << ",\n";
|
||||
}
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out triangles as POINTS
|
||||
void GLSurface::writespheres(ofstream &out, const string &objname) {
|
||||
unsigned i,k;
|
||||
|
||||
writepymolheader(out);
|
||||
for (i=0; i<spheres.size(); i++) {
|
||||
// Output coords, colors, and normals of points
|
||||
// if (vertices[i].transparency!=1)
|
||||
out << "ALPHA," << vertices[spheres[i].i].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[spheres[i].i].color[k] << ",";
|
||||
out << "SPHERE,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[spheres[i].i].cpt[k] << ",";
|
||||
out << spheres[i].radius << ",\n";
|
||||
}
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out triangles as mesh
|
||||
// OPTIMIZE TO REMOVE IDENTICAL LINES
|
||||
void GLSurface::writetris_mesh(ofstream &out, const string &objname) {
|
||||
unsigned i,j,k;
|
||||
int index;
|
||||
|
||||
writepymolheader(out);
|
||||
for (i=0; i<triangles.size(); i++) {
|
||||
out << "BEGIN, LINE_LOOP," << endl;
|
||||
// Output coords, colors, and normals of points
|
||||
for (j=0; j<3; j++) {
|
||||
index=triangles[i].point[j];
|
||||
// if (vertices[index].transparency!=1)
|
||||
out << "ALPHA," << vertices[index].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].color[k] << ",";
|
||||
if (vertices[index].valid_normal) {
|
||||
out << "NORMAL,";
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[index].normal[k] << ",";
|
||||
}
|
||||
out << "VERTEX,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].cpt[k] << ",";
|
||||
}
|
||||
out << "END,";
|
||||
out << endl;
|
||||
}
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write out Line Strips (Loops)
|
||||
void GLSurface::writelinestrips(ofstream &out, const string &objname) {
|
||||
unsigned i,j,k, size;
|
||||
int index;
|
||||
|
||||
writepymolheader(out);
|
||||
//out << "LINEWIDTH, 2," << endl;
|
||||
for (i=0; i<linestrips.size(); i++) {
|
||||
size=linestrips[i].line.size();
|
||||
if (size==1)
|
||||
out << "BEGIN, POINTS," << endl;
|
||||
else if (size==2)
|
||||
out << "BEGIN, LINES," << endl;
|
||||
else if (linestrips[i].loop)
|
||||
out << "BEGIN, LINE_LOOP," << endl;
|
||||
else
|
||||
out << "BEGIN, LINE_STRIP," << endl;
|
||||
// Output coords, colors, and normals of points
|
||||
for (j=0; j<linestrips[i].line.size(); j++) {
|
||||
index=linestrips[i].line[j];
|
||||
// if (vertices[index].transparency!=1)
|
||||
out << "ALPHA," << vertices[index].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].color[k] << ",";
|
||||
if (vertices[index].valid_normal) {
|
||||
out << "NORMAL,";
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[index].normal[k] << ",";
|
||||
}
|
||||
out << "VERTEX,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].cpt[k] << ",";
|
||||
}
|
||||
out << "END,";
|
||||
out << endl;
|
||||
}
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Add a line
|
||||
void GLSurface::addline(unsigned v1, unsigned v2) {
|
||||
GLline line;
|
||||
line.points[0]=v1;
|
||||
line.points[1]=v2;
|
||||
gllines.push_back(line);
|
||||
}
|
||||
|
||||
// Write out GLlines
|
||||
void GLSurface::writelines(ofstream &out, const string &objname) {
|
||||
writelines(gllines, out, objname);
|
||||
}
|
||||
|
||||
void GLSurface::writelines(vector<GLline> &l, ofstream &out,
|
||||
const string &objname) {
|
||||
unsigned i,j,k;
|
||||
int index;
|
||||
|
||||
writepymolheader(out);
|
||||
//out << "LINEWIDTH, 2," << endl;
|
||||
out << "BEGIN, LINES," << endl;
|
||||
for (i=0; i<l.size(); i++)
|
||||
for (j=0; j<2; j++) {
|
||||
index=l[i].points[j];
|
||||
// if (vertices[index].transparency!=1)
|
||||
out << "ALPHA," << vertices[index].transparency << ",";
|
||||
out << "COLOR,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].color[k] << ",";
|
||||
if (vertices[i].valid_normal) {
|
||||
out << "NORMAL,";
|
||||
for (k=RED; k<=BLUE; k++)
|
||||
out << vertices[index].normal[k] << ",";
|
||||
}
|
||||
out << "VERTEX,";
|
||||
for (k=X; k<=Z; k++)
|
||||
out << vertices[index].cpt[k] << ",";
|
||||
out << endl;
|
||||
}
|
||||
out << "END,\n";
|
||||
writepymoltail(out,objname);
|
||||
}
|
||||
|
||||
// Write a set of triangles as an xyzmesh - Requires surface was created on
|
||||
// a grid of 'resolution' with minimum latice point at 'min'
|
||||
void GLSurface::writexyzmesh(ofstream &out, const string &objname) {
|
||||
writelines(xmesh,out,objname+"x");
|
||||
writelines(ymesh,out,objname+"y");
|
||||
writelines(zmesh,out,objname+"z");
|
||||
return;
|
||||
}
|
||||
|
||||
void GLSurface::writepymolheader(ofstream &out) {
|
||||
out << "from pymol.cgo import *\n"
|
||||
<< "from pymol import cmd\n"
|
||||
<< "obj = [\n";
|
||||
}
|
||||
|
||||
void GLSurface::writepymoltail(ofstream &out, const string &objname) {
|
||||
out << "]\n"
|
||||
<< "cmd.load_cgo(obj,'" << objname << "')\n\n";
|
||||
}
|
||||
|
||||
// Helper function to set the xyz and the normal for a ellipsoid vertex
|
||||
void GLSurface::SQE_helper(Vertex &ver, const cPt &rad, const double u,
|
||||
const double v, const double n,
|
||||
const double e) {
|
||||
double sqCun=am::sign(cos(u))*powf(fabs(cos(u)),n);
|
||||
double sqSun=am::sign(sin(u))*powf(fabs(sin(u)),n);
|
||||
double sqCve=am::sign(cos(v))*powf(fabs(cos(v)),e);
|
||||
double sqSve=am::sign(sin(v))*powf(fabs(sin(v)),e);
|
||||
double sqCu2n=am::sign(cos(u))*powf(fabs(cos(u)),2.0-n);
|
||||
double sqSu2n=am::sign(sin(u))*powf(fabs(sin(u)),2.0-n);
|
||||
double sqCv2e=am::sign(cos(v))*powf(fabs(cos(v)),2.0-e);
|
||||
double sqSv2e=am::sign(sin(v))*powf(fabs(sin(v)),2.0-e);
|
||||
|
||||
ver.cpt=rad;
|
||||
ver.cpt.x*=sqCun*sqCve;
|
||||
ver.cpt.y*=sqCun*sqSve;
|
||||
ver.cpt.z*=sqSun;
|
||||
ver.normal.x=sqCu2n*sqCv2e/rad.x;
|
||||
ver.normal.y=sqCu2n*sqSv2e/rad.y;
|
||||
ver.normal.z=sqSu2n/rad.z;
|
||||
}
|
||||
|
||||
void GLSurface::add_super_ellipsoid(const cPt &cen, const cPt &rad,
|
||||
const Quaternion &q,
|
||||
const double n, const double e,
|
||||
const double u1, const double u2,
|
||||
const double v1, const double v2,
|
||||
const unsigned u_segs,
|
||||
const unsigned v_segs,
|
||||
const colorPt &color, const double alpha){
|
||||
RotMat rot(q);
|
||||
Vertex ver;
|
||||
ver.color=color;
|
||||
ver.transparency=alpha;
|
||||
double dU=(u2-u1)/u_segs;
|
||||
double dV=(v2-v1)/v_segs;
|
||||
double U=u1;
|
||||
for (unsigned i=0; i<u_segs; i++) {
|
||||
double V=v1;
|
||||
for (unsigned j=0; j<v_segs; j++) {
|
||||
unsigned offset=vertices.size();
|
||||
|
||||
SQE_helper(ver,rad,U,V,n,e);
|
||||
ver.cpt=rot*ver.cpt+cen;
|
||||
ver.normal=rot*ver.normal;
|
||||
addvertex(ver);
|
||||
SQE_helper(ver,rad,U+dU,V,n,e);
|
||||
ver.cpt=rot*ver.cpt+cen;
|
||||
ver.normal=rot*ver.normal;
|
||||
addvertex(ver);
|
||||
SQE_helper(ver,rad,U+dU,V+dV,n,e);
|
||||
ver.cpt=rot*ver.cpt+cen;
|
||||
ver.normal=rot*ver.normal;
|
||||
addvertex(ver);
|
||||
SQE_helper(ver,rad,U,V+dV,n,e);
|
||||
ver.cpt=rot*ver.cpt+cen;
|
||||
ver.normal=rot*ver.normal;
|
||||
addvertex(ver);
|
||||
|
||||
Triangle t;
|
||||
t.point[0]=offset;
|
||||
t.point[1]=offset+1;
|
||||
t.point[2]=offset+3;
|
||||
addtriangle(t);
|
||||
t.point[0]=offset+1;
|
||||
t.point[1]=offset+2;
|
||||
t.point[2]=offset+3;
|
||||
addtriangle(t);
|
||||
|
||||
V+=dV;
|
||||
}
|
||||
U+=dU;
|
||||
}
|
||||
}
|
||||
|
||||
void GLSurface::add_ellipsoid(const cPt ¢er, const cPt &rad,
|
||||
const Quaternion &rot, const colorPt &color,
|
||||
const double alpha, const unsigned res) {
|
||||
assert(res!=0);
|
||||
add_super_ellipsoid(center,rad,rot,1.0,1.0,HALFPI*-1.0,HALFPI,PI*-1.0,PI,
|
||||
res,res,color,alpha);
|
||||
}
|
||||
|
||||
void GLSurface::add_ellipsoid(const cPt ¢er, const cPt &rad,
|
||||
const Quaternion &rot, const colorPt &color,
|
||||
const double alpha) {
|
||||
add_super_ellipsoid(center,rad,rot,1.0,1.0,HALFPI*-1.0,HALFPI,PI*-1.0,PI,
|
||||
5,5,color,alpha);
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
/***************************************************************************
|
||||
glsurface.h
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Store and manipulate surfaces as OpenGL primitives
|
||||
|
||||
begin : Sun Jun 8 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GLSURFACE_H
|
||||
#define GLSURFACE_H
|
||||
|
||||
#include "miscm.h"
|
||||
#include "cartesian.h"
|
||||
#include "colors.h"
|
||||
//#include "gridnum.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
/// Stores the ID numbers of the vertices making a triangle
|
||||
struct Triangle {
|
||||
/// Triangle position
|
||||
unsigned point[3];
|
||||
};
|
||||
|
||||
/// Vertex information used for all primitives
|
||||
struct Vertex {
|
||||
/// True if normal is being set for vertex
|
||||
bool valid_normal;
|
||||
/// Cartesian coords
|
||||
cPt cpt;
|
||||
// Used for surface area calculations
|
||||
vectorPt normal;
|
||||
/// Color
|
||||
colorPt color;
|
||||
/// For coloring surface
|
||||
char marker;
|
||||
/// For transparency (0 transparent, 1 opaque)
|
||||
double transparency;
|
||||
};
|
||||
|
||||
/// ID numbers for vertices making a line
|
||||
struct GLline {
|
||||
unsigned points[2];
|
||||
};
|
||||
|
||||
// This stuff is used for removing duplicate lines by sorting;
|
||||
bool operator < (const GLline &one, const GLline &two);
|
||||
bool operator == (const GLline &one, const GLline &two);
|
||||
|
||||
/// Line Strip (loop) primitive (stores vertex indices)
|
||||
struct LineStrip {
|
||||
/// True for loop, false for line_strip
|
||||
bool loop;
|
||||
vector<unsigned> line;
|
||||
};
|
||||
|
||||
/// Sphere primitive
|
||||
struct Sphere {
|
||||
unsigned i;
|
||||
double radius;
|
||||
};
|
||||
|
||||
/// Class for storage and I/O of a set of OpenGL primitives
|
||||
class GLSurface {
|
||||
public:
|
||||
GLSurface();
|
||||
~GLSurface();
|
||||
/// Reserve vector space for specified number of vertices and triangles
|
||||
void reserve(unsigned num_v, unsigned num_t);
|
||||
/// Delete all primitives
|
||||
void clear();
|
||||
|
||||
/// Add a triangle
|
||||
void addtriangle(Triangle &t);
|
||||
/// Add a vertex
|
||||
void addvertex(Vertex &v);
|
||||
|
||||
/// Add many triangles (via swap)
|
||||
/** \note triangles are removed from input vector */
|
||||
void addtriangles(vector<Triangle> &t);
|
||||
/// Add many lines (via swap)
|
||||
/** \note lines are removed from input vector */
|
||||
void addlinestrips(vector<LineStrip> &l);
|
||||
/// Add a mesh (via swap)
|
||||
/** \note lines are removed from input vector */
|
||||
void addxyzmesh(vector<GLline> &x,vector<GLline> &y,vector<GLline> &z);
|
||||
/// Add a line
|
||||
void addline(unsigned v1, unsigned v2);
|
||||
/// Add a sphere based on a current vertex and a radius
|
||||
void add_sphere(unsigned index, double radius) {
|
||||
Sphere s;
|
||||
s.i=index;
|
||||
s.radius=radius;
|
||||
spheres.push_back(s);
|
||||
}
|
||||
|
||||
/// Add an ellipsoid with specified resolution
|
||||
/** The number of triangles is equal to twice the resolution squared **/
|
||||
void add_ellipsoid(const cPt ¢er, const cPt &rad,
|
||||
const Quaternion &rot, const colorPt &color,
|
||||
const double alpha,const unsigned resolution);
|
||||
/// Add an ellipsoid with resolution of 10
|
||||
/** \sa add_ellipsoid **/
|
||||
void add_ellipsoid(const cPt ¢er, const cPt &rad,
|
||||
const Quaternion &rot, const colorPt &color,
|
||||
const double alpha);
|
||||
|
||||
/// Calculate the unit normals for any vertices marked with invalid normals
|
||||
void calculatenormals();
|
||||
/// Normalize normals.
|
||||
void normalize();
|
||||
/// Flip normals
|
||||
void flipnormals();
|
||||
/// Calculate the Area of the Surface
|
||||
double surfacearea();
|
||||
/// Calculate the Area of a Triangle
|
||||
double triarea(Triangle &t);
|
||||
|
||||
/// Return the number of spheres
|
||||
unsigned size_spheres() { return spheres.size(); }
|
||||
/// Return the number of vertices
|
||||
unsigned size_vertices() { return vertices.size(); }
|
||||
|
||||
/// Solid color a surface
|
||||
void color(const colorPt &color);
|
||||
/// Color a surface by using a gradient
|
||||
void colorbygradient(const colorPt &start, const colorPt &end);
|
||||
/// Color a surface based on a marker
|
||||
void colorbymarker(const colorPt &zero, const colorPt &nonzero);
|
||||
/// Color a surface based on interpolation of values on a grid
|
||||
/** \param grid Grid with appropriate interpolation scheme set
|
||||
* \param neg Color for the value at and below minv
|
||||
* \param mid Color for the value at midv
|
||||
* \param pos Color for the value at and above posv **/
|
||||
//void colorbygrid(GridNUM<double> &grid,const colorPt &neg,
|
||||
// const colorPt &mid, const colorPt &pos, double minv,
|
||||
// double midv, double maxv);
|
||||
/// Set the transparency of the entire surface (0-1 [1=no transparency])
|
||||
void set_transparency(double alpha);
|
||||
|
||||
/// Write out triangles as BEGIN,TRIANGLES,END primitives
|
||||
void writetris(ofstream &out, const string &objname);
|
||||
/// Write out triangles as TRIANGLE primitives
|
||||
void writetris_surf(ofstream &out, const string &objname);
|
||||
/// Write out triangles as POINTS
|
||||
void writetris_points(ofstream &out, const string &objname);
|
||||
/// Write out vertices as spheres
|
||||
void write_vspheres(ofstream &out, const string &objname, double radius);
|
||||
/// Write out triangles as Mesh
|
||||
void writetris_mesh(ofstream &out, const string &objname);
|
||||
|
||||
/// Write out triangles as an xyzmesh
|
||||
void writexyzmesh(ofstream &out,const string &objname);
|
||||
|
||||
void writelines(ofstream &out, const string &objname);
|
||||
void writelines(vector<GLline> &l, ofstream &out, const string &objname);
|
||||
/// Write out Line Strips (Loops)
|
||||
void writelinestrips(ofstream &out, const string &objname);
|
||||
void writespheres(ofstream &out, const string &objname);
|
||||
|
||||
/// Write header for Python scripts for rendering in PyMol
|
||||
void writepymolheader(ofstream &out);
|
||||
/// Write tail for Python script for rendering in Pymol
|
||||
void writepymoltail(ofstream &out, const string &objname);
|
||||
private:
|
||||
vector<Triangle> triangles;
|
||||
vector<Vertex> vertices;
|
||||
vector<GLline> gllines;
|
||||
vector<Sphere> spheres;
|
||||
|
||||
// For xyzmesh
|
||||
vector<GLline> xmesh;
|
||||
vector<GLline> ymesh;
|
||||
vector<GLline> zmesh;
|
||||
|
||||
vector<LineStrip> linestrips;
|
||||
|
||||
void add_super_ellipsoid(const cPt &cen, const cPt &rad,const Quaternion &q,
|
||||
const double n, const double e, const double u1,
|
||||
const double u2, const double v1, const double v2,
|
||||
const unsigned u_segs, const unsigned v_segs,
|
||||
const colorPt &color, const double alpha);
|
||||
void SQE_helper(Vertex &ver, const cPt &rad, const double u,
|
||||
const double v, const double n, const double e);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/***************************************************************************
|
||||
m_constants.h
|
||||
-------------------
|
||||
W. Michael Brown
|
||||
|
||||
Misc constants
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the Math Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Wed Aug 10 2005
|
||||
copyright : (C) 2005 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
#include <math.h>
|
||||
using namespace std;
|
||||
|
||||
#define MATHLIB_VER "0.15"
|
||||
|
||||
#ifndef PI
|
||||
///\def PI
|
||||
/// pi
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
///\def TWOPI
|
||||
/// pi*2
|
||||
#define TWOPI 6.2831853071795862
|
||||
///\def HALFPI
|
||||
/// pi/2
|
||||
#define HALFPI 1.5707963267948966
|
||||
///\def DEGTORAD
|
||||
/// Convert Degrees to Radians (pi/180)
|
||||
#define DEGTORAD 0.017453292519943295
|
||||
///\def SQRT_TWO
|
||||
/// sqrt(2.0)
|
||||
#define SQRT_TWO 1.4142135623730951
|
||||
///\def SQRT_PI
|
||||
/// sqrt(PI)
|
||||
#define SQRT_PI 1.7724538509055159
|
||||
///\def INF
|
||||
/// Infinity
|
||||
#define INF 1e308
|
||||
///\def MINUSINF
|
||||
/// Negative infinity
|
||||
#define MINUSINF -1e308
|
||||
|
||||
#ifndef EPS
|
||||
///\def EPS
|
||||
/// Small number
|
||||
#define EPS 1e-100
|
||||
#endif
|
||||
|
||||
/** \mainpage Math Library
|
||||
* \section intro Introduction
|
||||
* Math library with containers and operations for vectors, matrices, graphs,
|
||||
* cartesian coordinates, quaternions, Euler angles, support vector machine
|
||||
* models, etc. **/
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/tcsh
|
||||
|
||||
set execs="asphere_vis"
|
||||
set execdir="../bin"
|
||||
|
||||
if ( -e ../doc ) then
|
||||
echo Manpage directory exists...
|
||||
else
|
||||
echo Creating directory 'manpages'
|
||||
mkdir ../doc
|
||||
endif
|
||||
|
||||
cd ../doc
|
||||
|
||||
foreach exec ($execs)
|
||||
$execdir/$exec -h > $exec.manpage
|
||||
eqn $exec.manpage > $exec.1
|
||||
man -t -p eqn ./$exec.manpage > $exec.ps
|
||||
ps2pdf $exec.ps $exec.pdf
|
||||
end
|
||||
|
||||
cd ../src
|
||||
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
/***************************************************************************
|
||||
misc.cpp
|
||||
-------------------
|
||||
W. Michael Brown
|
||||
|
||||
Miscellaneous functions that do not deserve their own class
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the "All" Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : May 30 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
void a::copyright(ostream &out, unsigned year) {
|
||||
out << "Copyright (" << year << ") Sandia Corporation. Under the terms of "
|
||||
<< "Contract\nDE-AC04-94AL85000, there is a non-exclusive license for "
|
||||
<< "use of this\nwork by or on behalf of the U.S. Government. Export "
|
||||
<< "of this program\nmay require a license from the United States "
|
||||
<< "Government.\n";
|
||||
}
|
||||
|
||||
// Get the SNL Copyright info as a string
|
||||
string a::copyrightstring(unsigned year) {
|
||||
return string("Copyright (")+a::itoa(year)+") Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive license for use of this work by or on behalf of the U.S. Government. Export of this program may require a license from the United States Government.";
|
||||
}
|
||||
|
||||
void a::fileopen(ifstream &in, const char *filename, Error &error) {
|
||||
in.clear();
|
||||
in.open(filename);
|
||||
if (!in) {
|
||||
error.addwarning(1,15,"Misc",
|
||||
"Could not open "+string(filename)+" for input!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopen(ifstream &in, const string &filename, Error &error) {
|
||||
in.clear();
|
||||
in.open(filename.c_str());
|
||||
if (!in) {
|
||||
error.addwarning(1,15,"Misc",
|
||||
"Could not open "+string(filename)+" for input!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopenbinary(ifstream &in, const string &filename, Error &error) {
|
||||
in.clear();
|
||||
in.open(filename.c_str(), ios::binary);
|
||||
if (!in) {
|
||||
error.addwarning(1,15,"Misc",
|
||||
"Could not open "+string(filename)+" for input!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopen(ofstream &out, const char *filename, Error &error) {
|
||||
out.clear();
|
||||
out.open(filename);
|
||||
if (!out) {
|
||||
error.addwarning(2,15,"Misc",
|
||||
"Could not open "+string(filename)+" for output!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopen(ofstream &out, const string &filename, Error &error) {
|
||||
out.clear();
|
||||
out.open(filename.c_str());
|
||||
if (!out) {
|
||||
error.addwarning(2,15,"Misc",
|
||||
"Could not open "+string(filename)+" for output!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopenbinary(ofstream &out, const string &filename, Error &error) {
|
||||
out.clear();
|
||||
out.open(filename.c_str(),ios::binary);
|
||||
if (!out) {
|
||||
error.addwarning(2,15,"Misc",
|
||||
"Could not open "+string(filename)+" for output!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileopenapp(ofstream &out, const string &filename, Error &error) {
|
||||
out.clear();
|
||||
out.open(filename.c_str(),ios::app);
|
||||
if (!out) {
|
||||
error.addwarning(2,15,"Misc",
|
||||
"Could not open "+string(filename)+" for output!");
|
||||
error.writewarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void a::fileclose(ifstream &in, Error &error) {
|
||||
in.close();
|
||||
}
|
||||
|
||||
void a::fileclose(ofstream &out, Error &error) {
|
||||
if (out.fail()) {
|
||||
error.addwarning(10,15,"Misc","Error writing to output file!");
|
||||
error.writewarnings();
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
// Put a string back into an istream
|
||||
void a::putback(istream &in, const string &s) {
|
||||
if (s.size()==0)
|
||||
return;
|
||||
unsigned i=s.size()-1;
|
||||
while (true) {
|
||||
in.putback(s[i]);
|
||||
if (i==0)
|
||||
return;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
string a::date() {
|
||||
char datestr[40];
|
||||
|
||||
time_t t;
|
||||
time(&t);
|
||||
|
||||
strftime(datestr,40,"%B %d, %Y",localtime(&t));
|
||||
return string(datestr);
|
||||
}
|
||||
|
||||
// Return the filename without the extension
|
||||
string a::namewoext(const string &filename) {
|
||||
return (filename.substr(0,filename.find_last_of('.')));
|
||||
}
|
||||
|
||||
// Return the filename without extension or directory
|
||||
string a::filenameonly(const string &filename) {
|
||||
// Find the start of the filename
|
||||
unsigned start=0;
|
||||
if (filename.find_last_of('/')<(filename.length()-1))
|
||||
start=filename.find_last_of('/')+1;
|
||||
|
||||
// Find the end of the filename
|
||||
unsigned end=filename.find_last_of('.')-start;
|
||||
return(filename.substr(start,end));
|
||||
}
|
||||
|
||||
// Return the extension of a filename
|
||||
string a::extension(const string &filename) {
|
||||
// Find the start of the extension
|
||||
unsigned start=filename.find_last_of('.')+1;
|
||||
if (start>=filename.length())
|
||||
return "";
|
||||
|
||||
return filename.substr(start,filename.length()-start);
|
||||
}
|
||||
|
||||
// Center a string over the specified length
|
||||
string a::strcenter(const string &s, unsigned length) {
|
||||
string empty(" ");
|
||||
unsigned half=length/2;
|
||||
unsigned spacer=half-(s.length()/2)-1;
|
||||
return (empty.substr(0,spacer)+s);
|
||||
}
|
||||
|
||||
// True if a character is whitespace
|
||||
bool a::whitespace(char c) {
|
||||
if (c==' ' || c=='\n' || c=='\t' || c=='\f' || c=='\r' || c=='\v')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if a string is only whitespace
|
||||
bool a::whitespace(const string &s) {
|
||||
for (unsigned i=0; i<s.length(); i++)
|
||||
if (!whitespace(s[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Remove all whitespace from a string
|
||||
string a::remove_whitespace(const string &s) {
|
||||
string n;
|
||||
for (unsigned i=0; i<s.length(); i++)
|
||||
if (!whitespace(s[i]))
|
||||
n+=s[i];
|
||||
return n;
|
||||
}
|
||||
|
||||
void a::str_replace(const string &source, const string &target, string &s) {
|
||||
unsigned slength=source.length();
|
||||
unsigned tlength=target.length();
|
||||
unsigned loc=0;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert(slength>0 && tlength>0);
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
if (loc>=s.length())
|
||||
break;
|
||||
loc=s.find(source,loc);
|
||||
if (loc>=s.length())
|
||||
break;
|
||||
s.replace(loc,slength,target,0,tlength);
|
||||
loc+=tlength;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert all alpha characters to lower case
|
||||
string a::tolower(const string &s) {
|
||||
string r="";
|
||||
for (unsigned i=0; i<s.length(); i++)
|
||||
r+=std::tolower(s[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return a string of num underscores
|
||||
string a::underline(unsigned num) {
|
||||
return string(num,'_');
|
||||
}
|
||||
|
||||
// The tokens parsed from cstring are \e added to the input vector
|
||||
void a::get_tokens(const char *line, vector<string> &tokens) {
|
||||
string sline=line;
|
||||
get_tokens(sline,tokens);
|
||||
}
|
||||
|
||||
void a::get_tokens(const string &sline, vector<string> &tokens) {
|
||||
string token="";
|
||||
unsigned i=0;
|
||||
while (i<sline.length()) {
|
||||
if (whitespace(sline[i])) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
while (i<sline.length()) {
|
||||
if (whitespace(sline[i])) {
|
||||
tokens.push_back(token);
|
||||
token="";
|
||||
break;
|
||||
}
|
||||
token+=sline[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (token!="")
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
// Return the first token in a string
|
||||
string a::get_first_token(const char *line) {
|
||||
string sline=line;
|
||||
string token="";
|
||||
unsigned i=0;
|
||||
while (i<sline.length()) {
|
||||
if (whitespace(sline[i])) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
while (i<sline.length()) {
|
||||
if (whitespace(sline[i]))
|
||||
return token;
|
||||
token+=sline[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
void a::get_tokens(char delimiter, const string &sline,vector<string> &tokens) {
|
||||
string token="";
|
||||
unsigned i=0;
|
||||
while (i<sline.length()) {
|
||||
if (delimiter==sline[i]) {
|
||||
tokens.push_back(token);
|
||||
token="";
|
||||
} else
|
||||
token+=sline[i];
|
||||
i++;
|
||||
}
|
||||
if (token!="")
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
// Format a string to fit within a specified column width
|
||||
void a::format_fit(unsigned column_width, const string &input,
|
||||
vector<string> &output) {
|
||||
vector<string> forced;
|
||||
a::get_tokens('\n',input,forced);
|
||||
for (unsigned i=0; i<forced.size(); i++) {
|
||||
string current_line;
|
||||
vector<string> tokens;
|
||||
a::get_tokens(forced[i],tokens);
|
||||
for (unsigned j=0; j<tokens.size(); j++) {
|
||||
if (current_line.length()+tokens[j].length()<column_width) {
|
||||
current_line+=tokens[j]+' ';
|
||||
} else {
|
||||
if (tokens[j].length()+1>column_width) {
|
||||
unsigned this_count=column_width-current_line.length();
|
||||
current_line+=tokens[j].substr(0,this_count);
|
||||
output.push_back(current_line);
|
||||
current_line="";
|
||||
tokens[j]=tokens[j].substr(this_count,tokens[j].length()-this_count);
|
||||
j--;
|
||||
} else {
|
||||
output.push_back(current_line);
|
||||
current_line=tokens[j]+' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
output.push_back(current_line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
string a::itoa(unsigned i) {
|
||||
ostringstream o;
|
||||
o << i;
|
||||
return o.str();
|
||||
}
|
||||
|
||||
string a::itoa(int i) {
|
||||
ostringstream o;
|
||||
o << i;
|
||||
return o.str();
|
||||
}
|
||||
|
||||
string a::ftoa(double i) {
|
||||
ostringstream o;
|
||||
o << i;
|
||||
return o.str();
|
||||
}
|
||||
|
||||
// Seed the random number generator
|
||||
void a::seedrandom(unsigned seed) {
|
||||
srand(seed);
|
||||
}
|
||||
|
||||
// Seed the random number generator with the current time
|
||||
void a::seedrandom_time() {
|
||||
srand(unsigned(time(0))); //+getpid());
|
||||
}
|
||||
|
||||
// Return an integer between 0 and max
|
||||
double a::frandom(double max) {
|
||||
return double(rand())/double(RAND_MAX)*max;
|
||||
}
|
||||
|
||||
// Return an integer between 0 and max
|
||||
unsigned a::irandom(unsigned max) {
|
||||
return unsigned(double(rand())/double(RAND_MAX)*max);
|
||||
}
|
||||
|
||||
// Return an integer between 0 and max
|
||||
long a::lrandom(long max) {
|
||||
return long(double(rand())/double(RAND_MAX)*max);
|
||||
}
|
||||
|
||||
// Empty constructer with no header, no extension, no lead zeros
|
||||
FileIterator::FileIterator() {
|
||||
file_num=0;
|
||||
digits=0;
|
||||
header="";
|
||||
extension="";
|
||||
}
|
||||
|
||||
// Specify the filename format with leading zeros
|
||||
FileIterator::FileIterator(const string &h,const string &e,unsigned d) {
|
||||
file_num=0;
|
||||
digits=d;
|
||||
header=h;
|
||||
extension=e;
|
||||
}
|
||||
|
||||
// Specify the filename format without leading zeros
|
||||
FileIterator::FileIterator(const string &h,const string &e) {
|
||||
digits=0;
|
||||
file_num=0;
|
||||
header=h;
|
||||
extension=e;
|
||||
}
|
||||
|
||||
// Set the current file number
|
||||
void FileIterator::set_file_num(unsigned fnum) {
|
||||
file_num=fnum;
|
||||
}
|
||||
|
||||
// Set the file header
|
||||
void FileIterator::set_file_header(const string &head) {
|
||||
header=head;
|
||||
}
|
||||
|
||||
// Set the file extension
|
||||
void FileIterator::set_file_extensions(const string &ext) {
|
||||
extension=ext;
|
||||
}
|
||||
|
||||
// Set the number of leading zeros
|
||||
void FileIterator::set_lead_zeros(unsigned digs) {
|
||||
digits=digs;
|
||||
}
|
||||
|
||||
// Set the current file number, header, extension, leading zeros
|
||||
void FileIterator::set(unsigned fnum, const string &head, const string &ext,
|
||||
unsigned digs) {
|
||||
file_num=fnum;
|
||||
header=head;
|
||||
extension=ext;
|
||||
digits=digs;
|
||||
}
|
||||
|
||||
string FileIterator::nextfilename() {
|
||||
// Get an output filename from a string
|
||||
string filename;
|
||||
filename=a::itoa(file_num);
|
||||
while (filename.length()<digits)
|
||||
filename='0'+filename;
|
||||
file_num++;
|
||||
return header+filename+extension;
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/***************************************************************************
|
||||
misc.h
|
||||
-------------------
|
||||
W. Michael Brown
|
||||
|
||||
Miscellaneous functions that do not deserve their own class
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the "All" Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : May 30 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MISC_H
|
||||
#define MISC_H
|
||||
|
||||
#include "error.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/// Miscellaneous functions that do not deserve their own class
|
||||
/** \e a contains functions for \n
|
||||
* - fileio
|
||||
* - string manipulation
|
||||
* - conversion from numbers to strings */
|
||||
namespace a {
|
||||
/// Output the SNL Copyright info for publication \e year.
|
||||
void copyright(ostream &out, unsigned year);
|
||||
/// Get the SNL Copyright info as a string
|
||||
string copyrightstring(unsigned year);
|
||||
|
||||
/// Open a file for input. Generates error ID \b 1-15 on fail.
|
||||
void fileopen(ifstream &in, const char *filename, Error &error);
|
||||
/// Open a file for input. Generates error ID \b 1-15 on fail.
|
||||
void fileopen(ifstream &in, const string &filename, Error &error);
|
||||
/// Open a binary file for input. Generates error ID \b 1-15 on fail.
|
||||
void fileopenbinary(ifstream &in, const string &filename, Error &error);
|
||||
|
||||
/// Open a file for output. Generates error ID \b 2-15 on fail.
|
||||
void fileopen(ofstream &out, const string &filename, Error &error);
|
||||
/// Open a file for output. Generates error ID \b 2-15 on fail.
|
||||
void fileopenbinary(ofstream &out, const string &filename, Error &error);
|
||||
/// Open a file for append. Generates error ID \b 2-15 on fail.
|
||||
void fileopenapp(ofstream &out, const string &filename, Error &error);
|
||||
/// Open a file for output. Generates error ID \b 2-15 on fail.
|
||||
void fileopen(ofstream &out, const char *filename, Error &error);
|
||||
|
||||
/// Close an input file. Generates error ID \b 10-15 on fail.
|
||||
void fileclose(ifstream &in, Error &error);
|
||||
/// Close an output file. Generates error ID \b 11-15 on fail.
|
||||
void fileclose(ofstream &out, Error &error);
|
||||
|
||||
/// Put a string back into an istream
|
||||
void putback(istream &in, const string &s);
|
||||
|
||||
/// Get the current date in the format "January 1, 2003"
|
||||
string date();
|
||||
|
||||
/// Returns the filename without the extension
|
||||
string namewoext(const string &filename);
|
||||
/// Returns the filename without extension or directory
|
||||
string filenameonly(const string &filename);
|
||||
/// Return the extension of a filename
|
||||
string extension(const string &filename);
|
||||
/// Centers a string over the specified length
|
||||
string strcenter(const string &s, unsigned length);
|
||||
/// True if a character is whitespace
|
||||
bool whitespace(char c);
|
||||
/// True if a string is only whitespace
|
||||
bool whitespace(const string &s);
|
||||
/// Remove all whitespace from a string
|
||||
string remove_whitespace(const string &s);
|
||||
/// Replace any instance of \e source with \e target within the string \e s
|
||||
void str_replace(const string &source, const string &target, string &s);
|
||||
/// Convert all alpha characters to lower case
|
||||
string tolower(const string &s);
|
||||
|
||||
/// The tokens parsed from cstring are \e added to the input vector
|
||||
/** \param line The line with 'white space' delimeted tokens
|
||||
* \param tokens Each token parsed is added to the vector */
|
||||
void get_tokens(const char *line, vector<string> &tokens);
|
||||
/// The tokens parsed from string are \e added to the input vector
|
||||
/** \param line The line with 'white space' delimeted tokens
|
||||
* \param tokens Each token parsed is added to the vector */
|
||||
void get_tokens(const string &line, vector<string> &tokens);
|
||||
/// Parse a string into tokens based on delimiter
|
||||
/** \param line The line with 'white space' delimeted tokens
|
||||
* \param tokens Each token parsed is added to the vector */
|
||||
void get_tokens(char delimiter, const string &line, vector<string> &tokens);
|
||||
/// Return the first token in a string
|
||||
string get_first_token(const char *line);
|
||||
/// Format a string to fit within a specified column width
|
||||
/** Newlines are inserted between whitespace if possible, otherwise line is
|
||||
* wrapped. Each string in the vector represents one line of text
|
||||
* \note The output vector is not emptied! **/
|
||||
void format_fit(unsigned column_width, const string &input,
|
||||
vector<string> &output);
|
||||
|
||||
/// Return a string of num underscores
|
||||
string underline(unsigned num);
|
||||
|
||||
/// Returns string representation of unsigned number
|
||||
string itoa(unsigned i);
|
||||
/// Returns string representation of int number
|
||||
string itoa(int i);
|
||||
/// Returns string representation of double number
|
||||
string ftoa(double i);
|
||||
|
||||
/// Seed the random number generator
|
||||
void seedrandom(unsigned seed);
|
||||
/// Seed the random number generator with the current time
|
||||
void seedrandom_time();
|
||||
/// Returns a random integer between 0 and max
|
||||
unsigned irandom(unsigned max);
|
||||
/// Returns a random integer between 0 and max
|
||||
long lrandom(long max);
|
||||
/// Returns a random double between 0 and max
|
||||
double frandom(double max);
|
||||
}
|
||||
|
||||
/// Iterate through file names to give each unique numbers
|
||||
class FileIterator {
|
||||
public:
|
||||
/// Empty constructer with no header, no extension, no lead zeros
|
||||
FileIterator();
|
||||
/// Specify the filename format using leading zeros
|
||||
/** Files are generated according to the following format:
|
||||
* \verbatim header+%0'digits'file_number+extension \endverbatim */
|
||||
FileIterator(const string &header, const string &extension, unsigned digits);
|
||||
/// Specify the filename format without leading zeros
|
||||
/** Files are generated according to the following format:
|
||||
* \verbatim header+file_number+extension \endverbatim */
|
||||
FileIterator(const string &header, const string &extension);
|
||||
|
||||
/// Set the current file number
|
||||
void set_file_num(unsigned fnum);
|
||||
/// Set the file header
|
||||
void set_file_header(const string &head);
|
||||
/// Set the file extension
|
||||
void set_file_extensions(const string &ext);
|
||||
/// Set the number of leading zeros
|
||||
void set_lead_zeros(unsigned digs);
|
||||
/// Set the current file number, header, extension, leading zeros
|
||||
void set(unsigned fnum, const string &head, const string &ext, unsigned digs);
|
||||
|
||||
/// Returns the next filename.
|
||||
string nextfilename();
|
||||
private:
|
||||
string header,extension;
|
||||
unsigned digits;
|
||||
unsigned file_num;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,212 @@
|
|||
/***************************************************************************
|
||||
miscm.cpp
|
||||
-------------------
|
||||
W. Michael Brown
|
||||
|
||||
Miscellaneous functions that do not deserve their own class
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the Math Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : May 30 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "miscm.h"
|
||||
|
||||
double am::square(double num) {
|
||||
return num*num;
|
||||
}
|
||||
|
||||
// Rounds a number
|
||||
double am::round(double n) {
|
||||
double r=ceil(n);
|
||||
if (r-n>0.5)
|
||||
return floor(n);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return the -1 for negative, 0 for zero, and 1 for positive
|
||||
int am::sign(double v) {
|
||||
if (v<0)
|
||||
return -1;
|
||||
if (v>0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the range of elements in a vector
|
||||
double am::range(const vector<double> &v) {
|
||||
if (v.empty())
|
||||
return 0;
|
||||
double min=v[0];
|
||||
double max=v[0];
|
||||
for (unsigned i=1; i<v.size(); i++) {
|
||||
if (v[i]<min)
|
||||
min=v[i];
|
||||
if (v[i]>max)
|
||||
max=v[i];
|
||||
}
|
||||
return max-min;
|
||||
}
|
||||
|
||||
// Return the average of elements in a vector
|
||||
double am::mean(const vector<double> &v) {
|
||||
double sum=0;
|
||||
for (unsigned i=0; i<v.size(); i++)
|
||||
sum+=v[i];
|
||||
return sum/v.size();
|
||||
}
|
||||
|
||||
// Return the max of two objects
|
||||
namespace am {
|
||||
template double max<double>(double,double);
|
||||
template float max<float>(float,float);
|
||||
template unsigned max<unsigned>(unsigned,unsigned);
|
||||
template int max<int>(int,int);
|
||||
}
|
||||
|
||||
template <typename numtyp>
|
||||
numtyp am::max(numtyp one,numtyp two) {
|
||||
if (one>two)
|
||||
return one;
|
||||
return two;
|
||||
}
|
||||
|
||||
// Return the min of two objects
|
||||
namespace am {
|
||||
template double min<double>(double,double);
|
||||
template float min<float>(float,float);
|
||||
template unsigned min<unsigned>(unsigned,unsigned);
|
||||
template int min<int>(int,int);
|
||||
}
|
||||
|
||||
template <typename numtyp>
|
||||
numtyp am::min(numtyp one,numtyp two) {
|
||||
if (one<two)
|
||||
return one;
|
||||
return two;
|
||||
}
|
||||
|
||||
// Swap two objects
|
||||
void am::swap(double a, double b) {
|
||||
double temp=a;
|
||||
a=b;
|
||||
b=temp;
|
||||
}
|
||||
|
||||
// --------------------- Finite Precision stuff
|
||||
double am::epsilon(double number) { // Finite Precision zero
|
||||
return fabs(DBL_EPSILON*number);
|
||||
}
|
||||
|
||||
// Bring number 1 digit closer to zero
|
||||
double am::minus_eps(double number) {
|
||||
return (number-DBL_EPSILON*number);
|
||||
}
|
||||
|
||||
// Bring number 1 digit away from zero
|
||||
double am::plus_eps(double number) {
|
||||
return (number+DBL_EPSILON*number);
|
||||
}
|
||||
|
||||
// Bring number m digits away from zero
|
||||
double am::plus_Meps(double m,double number) {
|
||||
return (number+m*DBL_EPSILON*number);
|
||||
}
|
||||
|
||||
// Bring number precision/2.0 digits away
|
||||
double am::plus_2eps(double number) {
|
||||
return (number+100000000*DBL_EPSILON*number);
|
||||
}
|
||||
|
||||
// Bring number pre/2 digits away
|
||||
double am::minus_2eps(double number) {
|
||||
return (number-100000000*DBL_EPSILON*number);
|
||||
}
|
||||
// Not a number checks
|
||||
bool am::not_nan(double number) { // False if NAN
|
||||
if (number-number!=0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Matrix stuff
|
||||
|
||||
// Invert a matrix - from numerical recipes in C
|
||||
void am::invert(double **a, unsigned n, Error &error) {
|
||||
int *indxc=new int[n];
|
||||
int *indxr=new int[n];
|
||||
int *ipiv=new int[n];
|
||||
unsigned i,icol,irow,j,k,l,ll;
|
||||
double big,dum,pivinv;
|
||||
|
||||
for (j=0;j<unsigned(n);j++)
|
||||
ipiv[j]=0;
|
||||
|
||||
for(i=0;i<n;i++) { /* *main loop for columns to be reduced */
|
||||
big = 0.0;
|
||||
for (j=0;j<n;j++) /* outer loop for search of a pivot element*/
|
||||
if (ipiv[j] !=1)
|
||||
for(k=0;k<n;k++) {
|
||||
if (ipiv[k] ==0) {
|
||||
if (fabs(a[j][k]) >= big) {
|
||||
big =fabs(a[j][k]);
|
||||
irow=j;
|
||||
icol=k;
|
||||
}
|
||||
} else if (ipiv[k] > 1) {
|
||||
error.addwarning(303,9,"Invert",
|
||||
"Cannot invert a singular matrix.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
++(ipiv[icol]);
|
||||
if (irow !=icol) {
|
||||
for (l=0;l<n;l++)
|
||||
swap(a[irow][l],a[icol][l]);
|
||||
}
|
||||
|
||||
indxr[i]=irow;
|
||||
indxc[i]=icol;
|
||||
if (a[icol][icol] == 0.0) {
|
||||
error.addwarning(303,9,"Invert",
|
||||
"Cannot invert a singular matrix.");
|
||||
return;
|
||||
}
|
||||
|
||||
pivinv=1.0/a[icol][icol];
|
||||
a[icol][icol]=1.0;
|
||||
for (l=0;l<n;l++)
|
||||
a[icol][l] *=pivinv;
|
||||
for (ll=0;ll<n;ll++)
|
||||
if (ll!= icol) {
|
||||
dum=a[ll][icol];
|
||||
a[ll][icol]=0.0;
|
||||
for (l=0;l<n;l++)
|
||||
a[ll][l] -=a[icol][l]*dum;
|
||||
}
|
||||
}
|
||||
|
||||
for (l=1;l>=1;l--) {
|
||||
if (indxr[l] != indxc[l])
|
||||
for (k=0;k<n;k++)
|
||||
swap(a[k][indxr[l]],a[k][indxc[l]]);
|
||||
}
|
||||
|
||||
delete []ipiv;
|
||||
delete []indxr;
|
||||
delete []indxc;
|
||||
return;
|
||||
}
|
||||
|
||||
// Move a value from a fraction of one range to a fraction of another
|
||||
double am::rerange(double one_start, double one_end, double value,
|
||||
double two_start, double two_end) {
|
||||
double one_diff=one_end-one_start;
|
||||
if (one_diff==0)
|
||||
return two_end;
|
||||
return (value-one_start)/one_diff*(two_end-two_start)+two_start;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/***************************************************************************
|
||||
miscm.h
|
||||
-------------------
|
||||
W. Michael Brown
|
||||
|
||||
Miscellaneous functions that do not deserve their own class
|
||||
|
||||
__________________________________________________________________________
|
||||
This file is part of the Math Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : May 30 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MISCM_H
|
||||
#define MISCM_H
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include "error.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/// Miscellaneous functions that do not deserve their own class
|
||||
/** \e a contains functions for \n
|
||||
* - simple math functions
|
||||
* - finite precision stuff */
|
||||
|
||||
namespace am {
|
||||
/// Returns the square of a number
|
||||
double square(double);
|
||||
/// Rounds a number
|
||||
double round(double);
|
||||
|
||||
/// Return the range of elements in a vector (0 if empty)
|
||||
double range(const vector<double> &v);
|
||||
/// Return the average of elements in a vector (0 if empty)
|
||||
double mean(const vector<double> &v);
|
||||
|
||||
/// Return the max of two objects
|
||||
template <class numtyp>
|
||||
numtyp max(numtyp one,numtyp two);
|
||||
|
||||
/// Return the min of two objects
|
||||
template <class numtyp>
|
||||
numtyp min(numtyp one,numtyp two);
|
||||
|
||||
/// Return the -1 for negative, 0 for zero, and 1 for positive
|
||||
int sign(double v);
|
||||
|
||||
/// Swap two objects
|
||||
void swap(double a, double b);
|
||||
|
||||
// Finite Precision stuff
|
||||
|
||||
/// Returns a number representing zero for finite checks
|
||||
double epsilon(double number);
|
||||
/// Returns number closer to zero by the smallest interval possible
|
||||
double minus_eps(double number);
|
||||
/// Returns number farther from zero by the smallest interval possible
|
||||
double plus_eps(double number);
|
||||
/// Returns number farther from zero by smallest interval * \b m
|
||||
double plus_Meps(double m,double number);
|
||||
/// Returns number farther from zero by smallest interval * 10^8
|
||||
double plus_2eps(double number);
|
||||
/// Returns number closer to zero by smallest interval * 10^8
|
||||
double minus_2eps(double number);
|
||||
|
||||
/// Returns false if the number is stored as NAN
|
||||
bool not_nan(double number);
|
||||
|
||||
// Matrix stuff
|
||||
|
||||
/// Invert a matrix (Gauss-Jordan)
|
||||
/** Generates error 303 L 9 for singular matrix
|
||||
* No checking for memory limitations **/
|
||||
void invert(double **matrix, unsigned size, Error &error);
|
||||
|
||||
/// Move a value from a fraction of one range to a fraction of another
|
||||
/** am::rerange(0,1,0.3,0,100) will return 30. No checking to enforce
|
||||
* that the value actually lies within the range is made. **/
|
||||
double rerange(double one_start, double one_end, double value,
|
||||
double two_start, double two_end);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,145 @@
|
|||
/***************************************************************************
|
||||
spherical.cpp
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Stuff for working spherical coordinates
|
||||
|
||||
__________________________________________________________________________
|
||||
|
||||
Part of the Math Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Tue Aug 29 2006
|
||||
copyright : (C) 2006 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#include "spherical.h"
|
||||
|
||||
template class Ball<double>;
|
||||
template class Ball<float>;
|
||||
template ostream & operator<< <double>(ostream &out, const Ball<double> &t);
|
||||
template ostream & operator<< <float>(ostream &out, const Ball<float> &t);
|
||||
template istream & operator>> <double>(istream &in, Ball<double> &t);
|
||||
template istream & operator>> <float>(istream &in, Ball<float> &t);
|
||||
|
||||
// Empty construct. Not necessarily initialized to [0 0]
|
||||
template<class numtyp>
|
||||
Ball<numtyp>::Ball() {
|
||||
}
|
||||
|
||||
// Assign theta and phi to the value
|
||||
template<class numtyp>
|
||||
Ball<numtyp>::Ball(numtyp value) : theta(value), phi(value) {
|
||||
}
|
||||
|
||||
// Assignment Constructor
|
||||
template<class numtyp>
|
||||
Ball<numtyp>::Ball(numtyp thet, numtyp ph) : theta(thet), phi(ph) {
|
||||
}
|
||||
|
||||
// Convert from cartesian
|
||||
template<class numtyp>
|
||||
Ball<numtyp>::Ball(const ThreeD<numtyp> &pt) {
|
||||
theta=atan2(pt.y,pt.x);
|
||||
if (theta<0)
|
||||
theta+=TWOPI;
|
||||
phi=acos(pt.z/pt.norm());
|
||||
}
|
||||
|
||||
template<class numtyp>
|
||||
numtyp & Ball<numtyp>::operator[](unsigned i) {
|
||||
if (i==THETA)
|
||||
return theta;
|
||||
else
|
||||
return phi;
|
||||
}
|
||||
|
||||
template<class numtyp>
|
||||
ostream & operator<< (ostream &out, const Ball<numtyp> &t) {
|
||||
out << t.theta << " " << t.phi;
|
||||
return out;
|
||||
}
|
||||
|
||||
template<class numtyp>
|
||||
istream & operator>> (istream &in, Ball<numtyp> &t) {
|
||||
in >> t.theta >> t.phi;
|
||||
return in;
|
||||
}
|
||||
|
||||
// Distance between two points (along arc)
|
||||
template<class numtyp>
|
||||
numtyp Ball<numtyp>::dist(const Ball &two) const {
|
||||
double dot=cPt(*this).dot(cPt(two));
|
||||
if (dot>1.0)
|
||||
dot=1.0;
|
||||
return acos(dot);
|
||||
}
|
||||
|
||||
// Distance squared between two points
|
||||
template<class numtyp>
|
||||
numtyp Ball<numtyp>::dist2(const Ball &two) const {
|
||||
numtyp d=dist(two);
|
||||
return d*d;
|
||||
}
|
||||
|
||||
// Add both angles
|
||||
template<class numtyp>
|
||||
void Ball<numtyp>::operator += (const Ball<numtyp> &two) {
|
||||
theta+=two.theta;
|
||||
phi+=two.phi;
|
||||
}
|
||||
|
||||
// Add to both angles
|
||||
template<class numtyp>
|
||||
Ball<numtyp> Ball<numtyp>::operator + (const numtyp two) const {
|
||||
return Ball(theta+two,phi+two);
|
||||
}
|
||||
|
||||
// Multiply both angles
|
||||
template<class numtyp>
|
||||
Ball<numtyp> Ball<numtyp>::operator * (const numtyp two) const {
|
||||
return Ball(theta*two,phi*two);
|
||||
}
|
||||
|
||||
// Divide both angles
|
||||
template<class numtyp>
|
||||
void Ball<numtyp>::operator /= (const numtyp two) {
|
||||
theta/=two;
|
||||
phi/=two;
|
||||
}
|
||||
|
||||
// Add both angles
|
||||
template<class numtyp>
|
||||
Ball<numtyp> Ball<numtyp>::operator + (const Ball<numtyp> &two) {
|
||||
return Ball(theta+two.theta,phi+two.phi);
|
||||
}
|
||||
|
||||
// Move coordinates into array
|
||||
template<class numtyp>
|
||||
void Ball<numtyp>::to_array(numtyp *array) {
|
||||
*array=theta;
|
||||
array++;
|
||||
*array=phi;
|
||||
}
|
||||
|
||||
// Set coordinates from array
|
||||
template<class numtyp>
|
||||
void Ball<numtyp>::from_array(numtyp *array) {
|
||||
theta=*array;
|
||||
array++;
|
||||
phi=*array;
|
||||
}
|
||||
|
||||
// Returns 2
|
||||
template<class numtyp>
|
||||
unsigned Ball<numtyp>::dimensionality() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Returns true
|
||||
template<class numtyp>
|
||||
bool Ball<numtyp>::check_bounds(numtyp min,numtyp max) {
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/***************************************************************************
|
||||
spherical.h
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Stuff for working spherical coordinates
|
||||
|
||||
__________________________________________________________________________
|
||||
|
||||
Part of the Math Library
|
||||
__________________________________________________________________________
|
||||
|
||||
begin : Tue Aug 29 2006
|
||||
copyright : (C) 2006 by W. Michael Brown
|
||||
email : wmbrown@sandia.gov
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SPHERICAL_H
|
||||
#define SPHERICAL_H
|
||||
|
||||
#include "miscm.h"
|
||||
#include "m_constants.h"
|
||||
#include "cartesian.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
// Other coordinates
|
||||
template<class numtyp> class ThreeD;
|
||||
|
||||
// Friends
|
||||
template<class numtyp> class Ball;
|
||||
template<class numtyp>
|
||||
ostream & operator<< (ostream &out, const Ball<numtyp> &t);
|
||||
template<class numtyp>
|
||||
istream & operator>> (istream &in, Ball<numtyp> &t);
|
||||
|
||||
enum { THETA, ///<0
|
||||
PHI ///<1
|
||||
};
|
||||
|
||||
/// Two dimensional spherical coordinates on a unit sphere
|
||||
/** The elements can be accessed directly .theta or .phi
|
||||
* or by using the operator [] ( [THETA], [PHI] )
|
||||
*
|
||||
* Input and output are overloaded for element I/O of the form "theta phi"
|
||||
* <<, >>
|
||||
**/
|
||||
template<class numtyp>
|
||||
class Ball {
|
||||
public:
|
||||
/// Empty construct. Not necessarily initialized to [0 0]
|
||||
Ball();
|
||||
/// Assignment Constructor
|
||||
Ball(numtyp theta, numtyp phi);
|
||||
/// Assign theta and phi to the value
|
||||
Ball(numtyp value);
|
||||
/// Convert from cartesian
|
||||
Ball(const ThreeD<numtyp> &pt);
|
||||
|
||||
numtyp theta;
|
||||
numtyp phi;
|
||||
|
||||
numtyp &operator[](unsigned i);
|
||||
|
||||
friend ostream & operator<< <>(ostream &out, const Ball &t);
|
||||
friend istream & operator>> <>(istream &in, Ball &t);
|
||||
|
||||
/// Add both angles
|
||||
void operator += (const Ball<numtyp> &two);
|
||||
/// Add to both angles
|
||||
Ball<numtyp> operator + (const numtyp two) const;
|
||||
/// Multiply both angles
|
||||
Ball<numtyp> operator * (const numtyp two) const;
|
||||
/// Divide both angles
|
||||
void operator /= (const numtyp two);
|
||||
/// Add both angles
|
||||
Ball<numtyp> operator + (const Ball<numtyp> &two);
|
||||
|
||||
/// Distance between two points (along arc)
|
||||
/** \note The form of calculation used suffers from round off error
|
||||
* when points are antipodal **/
|
||||
numtyp dist(const Ball &two) const;
|
||||
/// Distance squared between two points (along arc)
|
||||
/** \note The form of calculation used suffers from round off error
|
||||
* when points are antipodal **/
|
||||
numtyp dist2(const Ball &two) const;
|
||||
|
||||
/// Move coordinates into array
|
||||
void to_array(numtyp *array);
|
||||
/// Set coordinates from array
|
||||
void from_array(numtyp *array);
|
||||
|
||||
// -------------- Weird functions that help with coord templating
|
||||
/// Returns 2
|
||||
unsigned dimensionality();
|
||||
// Returns true
|
||||
bool check_bounds(numtyp min,numtyp max);
|
||||
private:
|
||||
};
|
||||
|
||||
///\var typedef Ball<double> BallD
|
||||
/// Double unit sphere
|
||||
typedef Ball<double> BallD;
|
||||
///\var typedef Ball<double> BallF
|
||||
/// Float unit sphere
|
||||
typedef Ball<float> BallF;
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue