1 /*
2 
3 -Procedure dskw02_c ( DSK, write type 2 segment )
4 
5 -Abstract
6 
7    Write a type 2 segment to a DSK file.
8 
9 -Disclaimer
10 
11    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
12    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
13    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
14    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
15    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
16    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
17    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
18    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
19    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
20    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
21 
22    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
23    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
24    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
25    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
26    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
27    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
28 
29    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
30    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
31    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
32    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
33 
34 -Required_Reading
35 
36    DAS
37    DSK
38    NAIF_IDS
39 
40 -Keywords
41 
42    DAS
43    DSK
44    FILES
45    PLATE
46    TOPOGRAPHY
47 
48 */
49 
50    #include "SpiceUsr.h"
51    #include "SpiceZfc.h"
52    #include "SpiceZmc.h"
53    #undef dskw02_c
54 
55 
dskw02_c(SpiceInt handle,SpiceInt center,SpiceInt surfid,SpiceInt dclass,ConstSpiceChar * frame,SpiceInt corsys,ConstSpiceDouble corpar[],SpiceDouble mncor1,SpiceDouble mxcor1,SpiceDouble mncor2,SpiceDouble mxcor2,SpiceDouble mncor3,SpiceDouble mxcor3,SpiceDouble first,SpiceDouble last,SpiceInt nv,ConstSpiceDouble vrtces[][3],SpiceInt np,ConstSpiceInt plates[][3],ConstSpiceDouble spaixd[],ConstSpiceInt spaixi[])56    void dskw02_c ( SpiceInt             handle,
57                    SpiceInt             center,
58                    SpiceInt             surfid,
59                    SpiceInt             dclass,
60                    ConstSpiceChar     * frame,
61                    SpiceInt             corsys,
62                    ConstSpiceDouble     corpar[],
63                    SpiceDouble          mncor1,
64                    SpiceDouble          mxcor1,
65                    SpiceDouble          mncor2,
66                    SpiceDouble          mxcor2,
67                    SpiceDouble          mncor3,
68                    SpiceDouble          mxcor3,
69                    SpiceDouble          first,
70                    SpiceDouble          last,
71                    SpiceInt             nv,
72                    ConstSpiceDouble     vrtces[][3],
73                    SpiceInt             np,
74                    ConstSpiceInt        plates[][3],
75                    ConstSpiceDouble     spaixd[],
76                    ConstSpiceInt        spaixi[]      )
77 
78 /*
79 
80 -Brief_I/O
81 
82    Variable  I/O  Description
83    --------  ---  --------------------------------------------------
84    handle     I   Handle assigned to the opened DSK file.
85    center     I   Central body ID code.
86    surfid     I   Surface ID code.
87    dclass     I   Data class.
88    frame      I   Reference frame.
89    corsys     I   Coordinate system code.
90    corpar     I   Coordinate system parameters.
91    mncor1     I   Minimum value of first coordinate.
92    mxcor1     I   Maximum value of first coordinate.
93    mncor2     I   Minimum value of second coordinate.
94    mxcor2     I   Maximum value of second coordinate.
95    mncor3     I   Minimum value of third coordinate.
96    mxcor3     I   Maximum value of third coordinate.
97    first      I   Coverage start time.
98    last       I   Coverage stop time.
99    nv         I   Number of vertices.
100    vrtces     I   Vertices.
101    np         I   Number of plates.
102    plates     I   Plates.
103    spaixd     I   Double precision component of spatial index.
104    spaixi     I   Integer component of spatial index.
105    SPICE_DSK_ANGMRG
106               P   Angular round-off margin.
107    SPICE_DSK_GENCLS
108               P   General surface DSK class.
109    SPICE_DSK_SVFCLS
110               P   Single-valued function DSK class.
111    SPICE_DSK_NSYPAR
112               P   Maximum number of coordinate system parameters in
113                   a DSK descriptor.
114    SPICE_DSK02_MAXCGR
115               P   Maximum DSK type 2 coarse voxel count.
116    SPICE_DSK02_MAXPLT
117               P   Maximum DSK type 2 plate count.
118    SPICE_DSK02_MAXVOX
119               P   Maximum DSK type 2 voxel count.
120    SPICE_DSK02_MAXVRT
121               P   Maximum DSK type 2 vertex count.
122 
123 -Detailed_Input
124 
125    handle      is the DAS file handle associated with a DSK file.
126                The file must be open for write access.
127 
128    center      is the ID code of the body whose surface is described
129                by the input plate model. `center' refers to an
130                ephemeris object.
131 
132    surfid      is the ID code of the surface described by the input
133                plate model. Multiple surfaces (for example, surfaces
134                having different resolutions) may be associated with a
135                given body.
136 
137    dclass      is the data class of the input data set. See the
138                header file SpiceDSK.h for values and meanings.
139 
140    frame       is the name of the reference frame with respect to
141                which the input data are expressed.
142 
143    corsys      is the coordinate system in which the spatial coverage
144                of the input data is expressed. `corsys' is an integer
145                code. See the header file SpiceDSK.h for values and
146                meanings.
147 
148    corpar      is an array of parameters associated with the input
149                coordinate system.
150 
151                For latitudinal and rectangular coordinates, `corpar'
152                is ignored.
153 
154                For planetodetic coordinates, the contents of `corpar'
155                are:
156 
157                   Element         Contents
158                   ---------       -----------------------------------
159                   corpar[0]       Equatorial radius of reference
160                                   spheroid.
161 
162                   corpar[1]       Flattening coefficient. The polar
163                                   radius of the reference spheroid
164                                   is given by
165 
166                                      corpar[0] * ( 1 - corpar[1] )
167 
168                   corpar[2]...
169                   corpar[SPICE_DSK_NSYPAR-1]  Unused.
170 
171 
172    mncor1,
173    mxcor1,
174    mncor2,
175    mxcor2,
176    mncor3,
177    mxcor3      are, respectively, lower and upper bounds of
178                each of the coordinates of the input data, where the
179                coordinate system is defined by `corsys' and `corpar'.
180                These bounds define the region for which the segment
181                provides data.
182 
183                Distance units are km. Angular units are radians.
184 
185                The interpretation of these bounds depends on the data
186                class; see `dclass' above.
187 
188                   Single-valued surfaces
189                   ----------------------
190 
191                   If the segment has data class SPICE_DSK_SVFCLS (see
192                   SpiceDSK.h), the segment defines a surface as a
193                   single-valued function of its domain coordinates:
194                   for example, it may define the radius of the
195                   surface as a function of planetocentric longitude
196                   and latitude.
197 
198                   In this case, the input data must cover a
199                   rectangle in dimensions 1 and 2 of the input
200                   coordinate system: the set of points
201 
202                      R = { (x,y): mncor1 < x < mxcor1;
203                                   mncor2 < y < mxcor2  }
204 
205                   must be completely covered by the input data. In
206                   other words, for each point (x,y) of R, there must
207                   be some plate containing a point whose first two
208                   coordinates are (x,y).
209 
210                   The plate set may extend beyond the coordinate
211                   range defined by the bounds on the domain.
212 
213                   Normally for single-valued surfaces, `mncor3' and
214                   `mxcor3' are the minimum and maximum values of the
215                   function attained on the domain.
216 
217 
218                   General surfaces
219                   ----------------
220 
221                   If the segment has data class SPICE_DSK_GENCLS (see
222                   SpiceDSK.h), the segment simply contains a collection
223                   of plates: no guarantees are made about the topology
224                   of the surface. The coordinate bounds simply indicate
225                   the spatial region for which the segment provides
226                   data.
227 
228                   Note that shapes of small bodies such as asteroids
229                   and comet nuclei may fall into the "general
230                   surface" category. Surface features such as cliffs,
231                   caves, and arches can prevent a surface from being
232                   represented as a single-valued function of latitude
233                   and longitude, for example.
234 
235 
236                Longitude interpretation and restrictions
237                -----------------------------------------
238 
239                The following rules apply to longitudes provided in
240                the arguments
241 
242                   mncor1
243                   mxcor1
244 
245                All angles have units of radians. The tolerance
246                SPICE_DSK_ANGMRG is used for the comparisons shown
247                below.
248 
249                   1) Longitudes must be in the range
250 
251                         -2*pi  :  2*pi
252 
253                      Values that are out of range by no more than
254                      SPICE_DSK_ANGMRG are bracketed to be in range.
255 
256 
257                   2) It is acceptable for the longitude bounds to be
258                      equal or out of order. If
259 
260                         mxcor1 < mncor1
261                                -
262 
263                      then either `mxcor1' is treated by the DSK
264                      subsystem as though it were mxcor1 + 2*pi, or
265                      `mncor1' is treated as mncor1 - 2*pi: whichever
266                      shift puts the bounds in the allowed range is
267                      made.
268 
269                      The input longitude bounds must not be equal.
270                      If the lower bound is greater than the upper
271                      bound, the difference between the bounds must
272                      not be an integer multiple of 2*pi.
273 
274                      Aside from any small changes made to move the
275                      input values of `mncor1' or `mxcor1' into range,
276                      the values are stored in the DSK segment as is.
277 
278 
279                   3) `mxcor1' must not exceed `mncor1' by more than 2*pi.
280                      Values that are out of range by no more than
281                      SPICE_DSK_ANGMRG are bracketed to be in range.
282 
283    first,
284    last        are the endpoints of the time interval over which this
285                data set is applicable. These times are expressed as
286                seconds past J2000 TDB.
287 
288    nv          is the number of vertices belonging to the plate
289                model.
290 
291    vrtces      is an array of coordinates of the vertices.
292                The ith vertex occupies elements [i-1][0:2] of
293                this array.
294 
295    np          is the number of plates in the plate model.
296 
297    plates      is an array representing the plates of the model.
298                The elements of `plates' are vertex indices. The vertex
299                indices of the ith plate occupy elements [i-1][0:2] of
300                this array.
301 
302    spaixd,
303    spaixi      are, respectively, the double precision and integer
304                components of the spatial index of the segment.
305 
306                It is strongly recommended that the helper routine
307                dskmi2_c be used to create these arrays. See the
308                Examples section below.
309 
310 
311 -Detailed_Output
312 
313    None. This routine operates by side effects.
314 
315 -Parameters
316 
317    See the header files
318 
319       SpiceDSK.h
320       SpiceDtl.h
321 
322    for declarations of parameters that may be used as inputs to this
323    routine, or that may be used to declare bounds of arrays which are
324    arguments of this routine.
325 
326 -Exceptions
327 
328 
329    1)  If the reference frame name `frame' could not be mapped to
330        an ID code, the error SPICE(FRAMEIDNOTFOUND) is signaled.
331 
332    2)  If the segment stop time precedes the start time, the
333        error SPICE(TIMESOUTOFORDER) is signaled.
334 
335    3)  If an input longitude value is outside the range
336 
337           [ -2*pi - SPICE_DSK_ANGMRG,   2*pi + SPICE_DSK_ANGMRG ]
338 
339        the error SPICE(VALUEOUTOFRANGE) will be signaled. Longitudes
340        outside of the range by a smaller amount than SPICE_DSK_ANGMRG
341        will be truncated to lie in the interval [-2*pi, 2*pi].
342 
343    4)  If the absolute value of the difference between the input
344        maximum longitude and the minimum longitude is more than 2*pi +
345        SPICE_DSK_ANGMRG, the error SPICE(INVALIDLONEXTENT) will be
346        signaled. If either longitude bound exceeds the other by an
347        amount between 2*pi and 2*pi+SPICE_DSK_ANGMRG, the larger value
348        will be truncated to the smaller value plus 2*pi.
349 
350    5)  If an input latitude value is outside the range
351 
352           [ -pi/2 - SPICE_DSK_ANGMRG,   pi/2 + SPICE_DSK_ANGMRG ]
353 
354        the error SPICE(VALUEOUTOFRANGE) will be signaled. Latitudes
355        outside of the range by a smaller amount than SPICE_DSK_ANGMRG
356        will be truncated to lie in the interval [-pi/2, pi/2].
357 
358 
359    6)  If the coordinate system is latitudinal and the lower radius
360        bound is negative, or if the upper radius bound is
361        non-positive, the error SPICE(VALUEOUTOFRANGE) will be
362        signaled.
363 
364    7)  If the coordinate system is latitudinal or planetodetic
365        and the bounds of the radius or altitude coordinate are
366        out of order, the error SPICE(BOUNDSOUTOFORDER) will be
367        signaled.
368 
369    8)  If the coordinate system is latitudinal or planetodetic and
370        the lower and upper bounds of the longitude, latitude, radius
371        or altitude coordinate, respectively, are equal, the error
372        SPICE(ZEROBOUNDSEXTENT) will be signaled. If the lower
373        longitude bound is greater than the upper bound, and if the
374        difference between the bounds is an integer multiple of 2*pi,
375        the same error will be signaled.
376 
377    9)  If the coordinate system is planetodetic and the input
378        equatorial radius is non-positive, the error
379        SPICE(VALUEOUTOFRANGE) will be signaled.
380 
381   10)  If the coordinate system is planetodetic and the input
382        flattening coefficient is greater than or equal to 1, the
383        error SPICE(VALUEOUTOFRANGE) will be signaled.
384 
385   11)  If the coordinate system is planetodetic, and if the minimum
386        altitude is less than the maximum of
387 
388                   2           2
389             {  -(B / A),   -(A / B)  }
390 
391        where A and B are the semi-major and semi-minor axis lengths
392        of the reference ellipsoid, the error
393        SPICE(DEGENERATESURFACE) will be signaled.
394 
395   12)  If the coordinate system is rectangular and any coordinate
396        lower bound is greater than or equal to the corresponding
397        upper bound, the error SPICE(BOUNDSOUTOFORDER) will be
398        signaled.
399 
400   13)  If the coordinate system code is not recognized, the error
401        SPICE(NOTSUPPORTED) will be signaled.
402 
403   14)  If any vertex index belonging to an input plate is outside
404        of the range 1:nv, the error SPICE(BADVERTEXINDEX) will be
405        signaled.
406 
407   15)  If `nv' is less than 1 or greater than SPICE_DSK02_MAXVRT, the
408        error SPICE(VALUEOUTOFRANGE) is signaled.
409 
410   16)  If `np' is less than 1 or greater than SPICE_DSK02_MAXPLT, the
411        error SPICE(VALUEOUTOFRANGE) is signaled.
412 
413   17)  If any voxel grid extent is less than 1 or greater than
414        SPICE_DSK02_MAXVOX, the error SPICE(VALUEOUTOFRANGE) is
415        signaled.
416 
417   18)  If the voxel count is greater than SPICE_DSK02_MAXVOX, the error
418        SPICE(VALUEOUTOFRANGE) is signaled.
419 
420   19)  If the coarse voxel count is less than 1 or greater than
421        SPICE_DSK02_MAXCGR, the error SPICE(VALUEOUTOFRANGE) is
422        signaled.
423 
424   20)  If the coarse voxel scale is less than 1 or more than
425        the cube root of the fine voxel count, the error
426        SPICE(VALUEOUTOFRANGE) will be signaled.
427 
428   21)  If the cube of the coarse voxel scale does not divide the
429        fine voxel count evenly, the error SPICE(INCOMPATIBLESCALE)
430        will be signaled.
431 
432   22)  If the input data class is not recognized, the error
433        SPICE(NOTSUPPORTED) is signaled.
434 
435   23)  If an error occurs while writing the segment to the output
436        DSK file, the error will be diagnosed by routines in the call
437        tree of this routine.
438 
439   24)  The error SPICE(EMPTYSTRING) is signaled if the input frame name
440        string does not contain at least one character, since such an
441        input string cannot be converted to a Fortran-style string in
442        this case.
443 
444   25)  The error SPICE(NULLPOINTER) is signaled if the input frame name
445        string pointer is null.
446 
447 
448 -Files
449 
450    See argument `handle'.
451 
452 -Particulars
453 
454    This routine writes a type 2 segment to a DSK file that has been
455    opened for write access.
456 
457    Users planning to create DSK files should consider whether the
458    SPICE DSK creation utility MKDSK may be suitable for their needs.
459 
460    This routine is supported by the routines dskmi2_c and dskrb2_c
461    dskmi2_c simplifies use of this routine by creating the "spatial
462    index" arrays required as inputs by this routine. dskrb2_c computes
463    bounds on the third coordinate of the input plate set.
464 
465    Spatial Indexes
466    ===============
467 
468    A spatial index is a group of data structures that facilitates
469    rapid high-level computations involving sets of plates. The data
470    structures created by this routine are aggregated into arrays
471    of type SpiceInt and type SpiceDouble.
472 
473 
474    Voxel grids
475    ===========
476 
477    A key geometric computation---probably the most important, as it
478    serves as a foundation for other high-level computations---is
479    finding the intersection of a ray with the plate set. DSK type 2
480    segments use data structures called "voxel grids" as part of
481    their indexing mechanism. There is a "coarse grid": a box that
482    completely encloses a DSK type 2 segment's plate set, and which
483    is composed of identically-sized cubes called "coarse voxels."
484    Each coarse voxel in composed of smaller cubes called "fine
485    voxels." When the term "voxel" is used without qualification, it
486    refers to fine voxels.
487 
488    Type 2 DSK segments contain data structures that associate plates
489    with the fine voxels intersected by those plates. These
490    structures enable the type 2 DSK software to rapidly find plates
491    in a given region of space.
492 
493    Voxel scales
494    ============
495 
496    There are two voxel scales:
497 
498       - The coarse voxel scale is the integer ratio of the
499         edge length of a coarse voxel to the edge length of
500         a fine voxel
501 
502       - The fine voxel scale is the double precision ratio
503         of the edge length of a fine voxel to the average
504         extent of the plates in the input plate set. "Extents"
505         of a plate are the absolute values of the differences
506         between the respective maximum and minimum X, Y, and Z
507         coordinates of the plate's vertices.
508 
509    Voxel scales determine the resolution of the voxel grid.
510    Voxel scales must be chosen to satisfy size constraints and
511    provide reasonable plate lookup performance.
512 
513    The following considerations apply to spatial indexes of
514    type 2 DSK segments:
515 
516       1)  The maximum number of coarse voxels is fixed at
517           SPICE_DSK02_MAXCGR (declared in SpiceDSK.h).
518 
519       2)  If there are too few fine voxels, the average number of
520           plates per fine voxel will be very large. This largely
521           negates the performance improvement afforded by having an
522           index. Also, the number of plates per voxel may exceed limits
523           imposed by DSK subroutines that use static arrays.
524 
525       3)  If there are too many fine voxels, the average number of
526           voxels intersected by a given plate may be too large for all
527           the plate-voxel associations to be stored. In addition, the
528           time needed to examine the plate lists for each voxel
529           (including the empty ones) may become quite large, again
530           negating the value of the index.
531 
532    In many cases, voxel scales yielding optimum performance must be
533    determined by experiment. However, the following heuristics can
534    provide reasonable starting values:
535 
536       Let `np' be the number of plates. Let `fs' be the fine voxel
537       scale. Then a reasonable value of `fs' may be
538 
539                  (0.25)
540          fs =  np       / 8.
541 
542       In general, `fs' should not smaller than 1.
543 
544 
545 -Examples
546 
547 
548    The numerical results shown for this example may differ across
549    platforms. The results depend on the SPICE kernels used as
550    input, the compiler and supporting libraries, and the machine
551    specific arithmetic implementation.
552 
553    1) Create a three-segment DSK file using plate model data for
554       Phobos. Use latitudinal, rectangular, and planetodetic
555       coordinates in the respective segments. This is not a
556       realistic example, but it serves to demonstrate use of
557       the supported coordinate systems.
558 
559       For simplicity, use an existing DSK file to provide the
560       input plate and vertex data. The selected input file has one
561       segment.
562 
563       Example code begins here.
564 
565 
566          /.
567 
568          Example program for dskw02_c, dskmi2_c, and dskrb2_c
569 
570          Create a three-segment DSK file using plate model data for
571          Phobos. Use latitudinal, rectangular, and planetodetic
572          coordinates in the respective segments.
573 
574          For simplicity, use an existing DSK file to provide the
575          input plate and vertex data. The selected input file has one
576          segment.
577 
578             Version 1.0.0 22-JAN-2016 (NJB)
579 
580          ./
581 
582          #include <stdio.h>
583          #include "SpiceUsr.h"
584 
585          int main()
586          {
587 
588             /.
589             Local constants
590             ./
591             #define FILSIZ          256
592             #define LNSIZE           81
593             #define NCOR              4
594             #define NSEG              3
595             #define NAMLEN           21
596 
597             /.
598             Local variables
599             ./
600 
601             /.
602             Below, we declare large arrays static to avoid stack
603             overflow problems.
604             ./
605 
606             SpiceBoolean            found;
607 
608             SpiceChar               cornam [ NCOR ][ NAMLEN ] =
609                                     { "radius",
610                                       "Z-coordinate",
611                                       "Z-coordinate",
612                                       "altitude" };
613 
614             SpiceChar             * dsk;
615             SpiceChar             * frame;
616             SpiceChar             * indsk;
617 
618             SpiceDLADescr           dladsc;
619 
620             SpiceDouble             corpar [ SPICE_DSK_NSYPAR ];
621             SpiceDouble             f;
622             SpiceDouble             finscl;
623             SpiceDouble             first;
624             SpiceDouble             last;
625             SpiceDouble             mncor1;
626             SpiceDouble             mncor2;
627             SpiceDouble             mncor3;
628             SpiceDouble             mxcor1;
629             SpiceDouble             mxcor2;
630             SpiceDouble             mxcor3;
631             SpiceDouble             re;
632             SpiceDouble             rp;
633 
634             /.
635             Note: the values of SPICE_DSK02_MAXVRT and
636             SPICE_DSK02_MAXPLT declared in SpiceDSK.h,
637             integer spatial index dimension SPICE_DSK02_SPAISZ,
638             and the workspace dimension SPICE_DSK02_MAXCEL
639             are very large. Smaller buffers can be used for most
640             applications.
641             ./
642             static SpiceDouble      spaixd [ SPICE_DSK02_SPADSZ ];
643             static SpiceDouble      vrtces [ SPICE_DSK02_MAXVRT ][3];
644 
645             SpiceInt                center;
646             SpiceInt                corscl;
647             SpiceInt                corsys;
648             SpiceInt                dclass;
649             SpiceInt                handle;
650             SpiceInt                i;
651             SpiceInt                inhan;
652             SpiceInt                np;
653             SpiceInt                nv;
654             static SpiceInt         plates [ SPICE_DSK02_MAXPLT ][3];
655             SpiceInt                segno;
656             static SpiceInt         spaixi [ SPICE_DSK02_SPAISZ ];
657             SpiceInt                spaisz;
658             SpiceInt                surfid;
659             SpiceInt                voxpsz;
660             SpiceInt                voxlsz;
661             static SpiceInt         work   [ SPICE_DSK02_MAXCEL ][2];
662             SpiceInt                worksz;
663 
664 
665             /.
666             Assign names of input and output DSK files.
667             ./
668             indsk = "phobos_3_3.bds";
669             dsk   = "phobos_3_3_3seg.bds";
670 
671             /.
672             Open input DSK for read access; find first segment.
673             ./
674             dasopr_c ( indsk, &inhan );
675             dlabfs_c ( inhan, &dladsc, &found );
676 
677             /.
678             Fetch vertices and plates from input DSK file.
679 
680             Note that vertex and plate indices are 1-based.
681             ./
682             printf ( "Reading input data...\n" );
683 
684             dskv02_c ( inhan, &dladsc, 1, SPICE_DSK02_MAXVRT,
685                        &nv,   vrtces                           );
686             dskp02_c ( inhan, &dladsc, 1, SPICE_DSK02_MAXPLT,
687                        &np,   plates                           );
688 
689             printf ( "Done.\n" );
690 
691 
692             /.
693             Set input array sizes required by dskmi2_c.
694             ./
695             voxpsz = SPICE_DSK02_MAXVXP;
696             voxlsz = SPICE_DSK02_MXNVLS;
697             worksz = SPICE_DSK02_MAXCEL;
698             spaisz = SPICE_DSK02_SPAISZ;
699 
700             /.
701             Set fine and coarse voxel scales. (These usually
702             need to determined by experimentation.)
703             ./
704             finscl = 5.0;
705             corscl = 4;
706 
707             /.
708             Open a new DSK file.
709             ./
710             dskopn_c ( dsk, dsk, 0, &handle );
711 
712             /.
713             Create three segments and add them to the file.
714             ./
715             for ( segno = 1;  segno <= NSEG;  segno++ )
716             {
717                /.
718                Create spatial index. We won't generate a
719                vertex-plate mapping, so we set the flag
720                for creating this map to "false."
721                ./
722                printf ( "Creating segment %d\n", (int)segno );
723                printf ( "Creating spatial index...\n" );
724 
725                dskmi2_c ( nv,     vrtces,     np,     plates,
726                           finscl, corscl,     worksz, voxpsz,
727                           voxlsz, SPICEFALSE, spaisz, work,
728                           spaixd, spaixi                    );
729 
730                printf ( "Done.\n" );
731 
732                /.
733                Set up inputs describing segment attributes:
734 
735                - Central body: Phobos
736                - Surface ID code: user's choice.
737                  We use the segment number here.
738                - Data class: general (arbitrary) shape
739                - Body-fixed reference frame
740                - Time coverage bounds (TBD)
741                ./
742                center = 401;
743                surfid = segno;
744                dclass = SPICE_DSK_GENCLS;
745                frame  = "IAU_PHOBOS";
746 
747                first = -50 * jyear_c();
748                last  =  50 * jyear_c();
749 
750                /.
751                Set the coordinate system and coordinate system
752                bounds based on the segment index.
753 
754                Zero out the coordinate parameters to start.
755                ./
756                for ( i = 0;  i < SPICE_DSK_NSYPAR;  i++ )
757                {
758                   corpar[i] = 0.0;
759                }
760 
761                if ( segno == 1 )
762                {
763                   /.
764                   Use planetocentric latitudinal coordinates. Set
765                   the longitude and latitude bounds.
766                   ./
767                   corsys = SPICE_DSK_LATSYS;
768 
769                   mncor1 = -pi_c();
770                   mxcor1 =  pi_c();
771                   mncor2 = -pi_c()/2;
772                   mxcor2 =  pi_c()/2;
773                }
774                else if ( segno == 2 )
775                {
776 
777                   /.
778                   Use rectangular coordinates. Set the
779                   X and Y bounds.
780 
781                   The bounds shown here were derived from
782                   the plate data. They lie slightly outside
783                   of the range spanned by the plates.
784                   ./
785                   corsys = SPICE_DSK_RECSYS;
786 
787                   mncor1 = -1.3;
788                   mxcor1 =  1.31;
789                   mncor2 = -1.21;
790                   mxcor2 =  1.2;
791                }
792                else
793                {
794                   /.
795                   Set the coordinate system to planetodetic.
796                   ./
797                   corsys    = SPICE_DSK_PDTSYS;
798 
799                   mncor1    = -pi_c();
800                   mxcor1    =  pi_c();
801                   mncor2    = -pi_c()/2;
802                   mxcor2    =  pi_c()/2;
803 
804                   /.
805                   We'll use equatorial and polar radii from
806                   pck00010.tpc. These normally would be fetched
807                   at run time, but for simplicity, we'll use
808                   hard-coded values.
809                   ./
810                   re        = 13.0;
811                   rp        =  9.1;
812                   f         = ( re - rp ) / re;
813 
814                   corpar[0] = re;
815                   corpar[1] = f;
816                }
817                /.
818                Compute plate model radius bounds.
819                ./
820                printf ( "Computing %s bounds of plate set...\n",
821                         cornam[corsys-1]                        );
822 
823                dskrb2_c ( nv,     vrtces, np,      plates,
824                           corsys, corpar, &mncor3, &mxcor3 );
825 
826                printf ( "Done.\n" );
827 
828                /.
829                Write the segment to the file.
830                ./
831                printf ( "Writing segment...\n" );
832 
833                dskw02_c ( handle,
834                           center, surfid, dclass, frame,  corsys,
835                           corpar, mncor1, mxcor1, mncor2, mxcor2,
836                           mncor3, mxcor3, first,  last,   nv,
837                           vrtces, np,     plates, spaixd, spaixi );
838 
839                printf ( "Done.\n" );
840             }
841 
842             /.
843             Segregate the data records in the DSK file and
844             close the file.
845             ./
846             printf ( "Segregating and closing DSK file...\n" );
847 
848             dskcls_c ( handle, SPICETRUE );
849 
850             printf ( "Done.\n" );
851 
852             return ( 0 );
853          }
854 
855 
856 -Restrictions
857 
858    None.
859 
860 -Literature_References
861 
862    None.
863 
864 -Author_and_Institution
865 
866    N.J. Bachman    (JPL)
867 
868 -Version
869 
870    -CSPICE Version 1.0.0, 04-APR-2017 (NJB)
871 
872        Based on Alpha DSK version 2.0.0, 13-MAY-2010 (NJB).
873 
874        Caution: this routine's argument list has been changed.
875 
876 -Index_Entries
877 
878    write a type 2 dsk segment
879 
880 -&
881 */
882 
883 { /* Begin dskw02_c */
884 
885 
886    /*
887    Participate in error tracing.
888    */
889    chkin_c ( "dskw02_c" );
890 
891    /*
892    Check the input frame string to make sure the pointer is non-null
893    and the string length is non-zero.
894    */
895    CHKFSTR ( CHK_STANDARD, "dskw02_c", frame );
896 
897 
898    dskw02_ ( (integer     * ) &handle,
899              (integer     * ) &center,
900              (integer     * ) &surfid,
901              (integer     * ) &dclass,
902              (char        * ) frame,
903              (integer     * ) &corsys,
904              (doublereal  * ) corpar,
905              (doublereal  * ) &mncor1,
906              (doublereal  * ) &mxcor1,
907              (doublereal  * ) &mncor2,
908              (doublereal  * ) &mxcor2,
909              (doublereal  * ) &mncor3,
910              (doublereal  * ) &mxcor3,
911              (doublereal  * ) &first,
912              (doublereal  * ) &last,
913              (integer     * ) &nv,
914              (doublereal  * ) vrtces,
915              (integer     * ) &np,
916              (integer     * ) plates,
917              (doublereal  * ) spaixd,
918              (integer     * ) spaixi,
919              (ftnlen        ) strlen(frame)  );
920 
921 
922    chkout_c ( "dskw02_c" );
923 
924 } /* End dskw02_c */
925