1 | /*<html><pre> -<a href="index.htm#TOC"
|
---|
2 | >-------------------------------</a><a name="TOP">-</a>
|
---|
3 |
|
---|
4 | random.c -- utilities
|
---|
5 | Park & Miller's minimimal standard random number generator
|
---|
6 | argc/argv conversion
|
---|
7 |
|
---|
8 | Used by rbox. Do not use 'qh'
|
---|
9 | */
|
---|
10 |
|
---|
11 | #include "libqhull.h"
|
---|
12 | #include <string.h>
|
---|
13 | #include <stdio.h>
|
---|
14 | #include <stdlib.h>
|
---|
15 |
|
---|
16 | #ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
|
---|
17 | #pragma warning( disable : 4706) /* assignment within conditional function */
|
---|
18 | #pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
|
---|
19 | #endif
|
---|
20 |
|
---|
21 | /*-<a href="qh-globa.htm#TOC"
|
---|
22 | >-------------------------------</a><a name="argv_to_command">-</a>
|
---|
23 |
|
---|
24 | qh_argv_to_command( argc, argv, command, max_size )
|
---|
25 |
|
---|
26 | build command from argc/argv
|
---|
27 | max_size is at least
|
---|
28 |
|
---|
29 | returns:
|
---|
30 | a space-delimited string of options (just as typed)
|
---|
31 | returns false if max_size is too short
|
---|
32 |
|
---|
33 | notes:
|
---|
34 | silently removes
|
---|
35 | makes option string easy to input and output
|
---|
36 | matches qh_argv_to_command_size()
|
---|
37 |
|
---|
38 | argc may be 0
|
---|
39 | */
|
---|
40 | int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
|
---|
41 | int i, remaining;
|
---|
42 | char *s;
|
---|
43 | *command= '\0'; /* max_size > 0 */
|
---|
44 |
|
---|
45 | if (argc) {
|
---|
46 | if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
|
---|
47 | || (s= strrchr( argv[0], '/')))
|
---|
48 | s++;
|
---|
49 | else
|
---|
50 | s= argv[0];
|
---|
51 | if ((int)strlen(s) < max_size) /* WARN64 */
|
---|
52 | strcpy(command, s);
|
---|
53 | else
|
---|
54 | goto error_argv;
|
---|
55 | if ((s= strstr(command, ".EXE"))
|
---|
56 | || (s= strstr(command, ".exe")))
|
---|
57 | *s= '\0';
|
---|
58 | }
|
---|
59 | for (i=1; i < argc; i++) {
|
---|
60 | s= argv[i];
|
---|
61 | remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
|
---|
62 | if (!*s || strchr(s, ' ')) {
|
---|
63 | char *t= command + strlen(command);
|
---|
64 | remaining -= 2;
|
---|
65 | if (remaining < 0) {
|
---|
66 | goto error_argv;
|
---|
67 | }
|
---|
68 | *t++= ' ';
|
---|
69 | *t++= '"';
|
---|
70 | while (*s) {
|
---|
71 | if (*s == '"') {
|
---|
72 | if (--remaining < 0)
|
---|
73 | goto error_argv;
|
---|
74 | *t++= '\\';
|
---|
75 | }
|
---|
76 | *t++= *s++;
|
---|
77 | }
|
---|
78 | *t++= '"';
|
---|
79 | *t= '\0';
|
---|
80 | }else if (remaining < 0) {
|
---|
81 | goto error_argv;
|
---|
82 | }else
|
---|
83 | strcat(command, " ");
|
---|
84 | strcat(command, s);
|
---|
85 | }
|
---|
86 | return 1;
|
---|
87 |
|
---|
88 | error_argv:
|
---|
89 | return 0;
|
---|
90 | } /* argv_to_command */
|
---|
91 |
|
---|
92 | /*-<a href="qh-globa.htm#TOC"
|
---|
93 | >-------------------------------</a><a name="argv_to_command_size">-</a>
|
---|
94 |
|
---|
95 | qh_argv_to_command_size( argc, argv )
|
---|
96 |
|
---|
97 | return size to allocate for qh_argv_to_command()
|
---|
98 |
|
---|
99 | notes:
|
---|
100 | argc may be 0
|
---|
101 | actual size is usually shorter
|
---|
102 | */
|
---|
103 | int qh_argv_to_command_size(int argc, char *argv[]) {
|
---|
104 | unsigned int count= 1; /* null-terminator if argc==0 */
|
---|
105 | int i;
|
---|
106 | char *s;
|
---|
107 |
|
---|
108 | for (i=0; i<argc; i++){
|
---|
109 | count += (int)strlen(argv[i]) + 1; /* WARN64 */
|
---|
110 | if (i>0 && strchr(argv[i], ' ')) {
|
---|
111 | count += 2; /* quote delimiters */
|
---|
112 | for (s=argv[i]; *s; s++) {
|
---|
113 | if (*s == '"') {
|
---|
114 | count++;
|
---|
115 | }
|
---|
116 | }
|
---|
117 | }
|
---|
118 | }
|
---|
119 | return count;
|
---|
120 | } /* argv_to_command_size */
|
---|
121 |
|
---|
122 | /*-<a href="qh-geom.htm#TOC"
|
---|
123 | >-------------------------------</a><a name="rand">-</a>
|
---|
124 |
|
---|
125 | qh_rand()
|
---|
126 | qh_srand( seed )
|
---|
127 | generate pseudo-random number between 1 and 2^31 -2
|
---|
128 |
|
---|
129 | notes:
|
---|
130 | For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
|
---|
131 |
|
---|
132 | From Park & Miller's minimal standard random number generator
|
---|
133 | Communications of the ACM, 31:1192-1201, 1988.
|
---|
134 | Does not use 0 or 2^31 -1
|
---|
135 | this is silently enforced by qh_srand()
|
---|
136 | Can make 'Rn' much faster by moving qh_rand to qh_distplane
|
---|
137 | */
|
---|
138 |
|
---|
139 | /* Global variables and constants */
|
---|
140 |
|
---|
141 | int qh_rand_seed= 1; /* define as global variable instead of using qh */
|
---|
142 |
|
---|
143 | #define qh_rand_a 16807
|
---|
144 | #define qh_rand_m 2147483647
|
---|
145 | #define qh_rand_q 127773 /* m div a */
|
---|
146 | #define qh_rand_r 2836 /* m mod a */
|
---|
147 |
|
---|
148 | int qh_rand( void) {
|
---|
149 | int lo, hi, test;
|
---|
150 | int seed = qh_rand_seed;
|
---|
151 |
|
---|
152 | hi = seed / qh_rand_q; /* seed div q */
|
---|
153 | lo = seed % qh_rand_q; /* seed mod q */
|
---|
154 | test = qh_rand_a * lo - qh_rand_r * hi;
|
---|
155 | if (test > 0)
|
---|
156 | seed= test;
|
---|
157 | else
|
---|
158 | seed= test + qh_rand_m;
|
---|
159 | qh_rand_seed= seed;
|
---|
160 | /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
|
---|
161 | /* seed = qh_RANDOMmax; for testing */
|
---|
162 | return seed;
|
---|
163 | } /* rand */
|
---|
164 |
|
---|
165 | void qh_srand( int seed) {
|
---|
166 | if (seed < 1)
|
---|
167 | qh_rand_seed= 1;
|
---|
168 | else if (seed >= qh_rand_m)
|
---|
169 | qh_rand_seed= qh_rand_m - 1;
|
---|
170 | else
|
---|
171 | qh_rand_seed= seed;
|
---|
172 | } /* qh_srand */
|
---|
173 |
|
---|
174 | /*-<a href="qh-geom.htm#TOC"
|
---|
175 | >-------------------------------</a><a name="randomfactor">-</a>
|
---|
176 |
|
---|
177 | qh_randomfactor( scale, offset )
|
---|
178 | return a random factor r * scale + offset
|
---|
179 |
|
---|
180 | notes:
|
---|
181 | qh.RANDOMa/b are defined in global.c
|
---|
182 | */
|
---|
183 | realT qh_randomfactor(realT scale, realT offset) {
|
---|
184 | realT randr;
|
---|
185 |
|
---|
186 | randr= qh_RANDOMint;
|
---|
187 | return randr * scale + offset;
|
---|
188 | } /* randomfactor */
|
---|
189 |
|
---|
190 | /*-<a href="qh-geom.htm#TOC"
|
---|
191 | >-------------------------------</a><a name="randommatrix">-</a>
|
---|
192 |
|
---|
193 | qh_randommatrix( buffer, dim, rows )
|
---|
194 | generate a random dim X dim matrix in range [-1,1]
|
---|
195 | assumes buffer is [dim+1, dim]
|
---|
196 |
|
---|
197 | returns:
|
---|
198 | sets buffer to random numbers
|
---|
199 | sets rows to rows of buffer
|
---|
200 | sets row[dim] as scratch row
|
---|
201 | */
|
---|
202 | void qh_randommatrix(realT *buffer, int dim, realT **rows) {
|
---|
203 | int i, k;
|
---|
204 | realT **rowi, *coord, realr;
|
---|
205 |
|
---|
206 | coord= buffer;
|
---|
207 | rowi= rows;
|
---|
208 | for (i=0; i < dim; i++) {
|
---|
209 | *(rowi++)= coord;
|
---|
210 | for (k=0; k < dim; k++) {
|
---|
211 | realr= qh_RANDOMint;
|
---|
212 | *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
|
---|
213 | }
|
---|
214 | }
|
---|
215 | *rowi= coord;
|
---|
216 | } /* randommatrix */
|
---|
217 |
|
---|
218 | /*-<a href="qh-globa.htm#TOC"
|
---|
219 | >-------------------------------</a><a name="strtol">-</a>
|
---|
220 |
|
---|
221 | qh_strtol( s, endp) qh_strtod( s, endp)
|
---|
222 | internal versions of strtol() and strtod()
|
---|
223 | does not skip trailing spaces
|
---|
224 | notes:
|
---|
225 | some implementations of strtol()/strtod() skip trailing spaces
|
---|
226 | */
|
---|
227 | double qh_strtod(const char *s, char **endp) {
|
---|
228 | double result;
|
---|
229 |
|
---|
230 | result= strtod(s, endp);
|
---|
231 | if (s < (*endp) && (*endp)[-1] == ' ')
|
---|
232 | (*endp)--;
|
---|
233 | return result;
|
---|
234 | } /* strtod */
|
---|
235 |
|
---|
236 | int qh_strtol(const char *s, char **endp) {
|
---|
237 | int result;
|
---|
238 |
|
---|
239 | result= (int) strtol(s, endp, 10); /* WARN64 */
|
---|
240 | if (s< (*endp) && (*endp)[-1] == ' ')
|
---|
241 | (*endp)--;
|
---|
242 | return result;
|
---|
243 | } /* strtol */
|
---|