1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // grid_system.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University Hamburg //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
48 ///////////////////////////////////////////////////////////
49
50 //---------------------------------------------------------
51 #include "grid.h"
52 #include "shapes.h"
53 #include "parameters.h"
54
55
56 ///////////////////////////////////////////////////////////
57 // //
58 // //
59 // //
60 ///////////////////////////////////////////////////////////
61
62 //---------------------------------------------------------
63 int CSG_Grid_System::m_Precision = 16; // 16 decimal digits, default precision used for storing cellsize and extent
64
65 //---------------------------------------------------------
Set_Precision(int Decimals)66 int CSG_Grid_System::Set_Precision(int Decimals)
67 {
68 if( Decimals >= 0 )
69 {
70 m_Precision = Decimals;
71 }
72
73 return( m_Precision );
74 }
75
76 //---------------------------------------------------------
Get_Precision(void)77 int CSG_Grid_System::Get_Precision(void)
78 {
79 return( m_Precision );
80 }
81
82
83 ///////////////////////////////////////////////////////////
84 // //
85 ///////////////////////////////////////////////////////////
86
87 //---------------------------------------------------------
CSG_Grid_System(void)88 CSG_Grid_System::CSG_Grid_System(void)
89 {
90 Destroy();
91 }
92
93 //---------------------------------------------------------
CSG_Grid_System(const CSG_Grid_System & System)94 CSG_Grid_System::CSG_Grid_System(const CSG_Grid_System &System)
95 {
96 Create(System);
97 }
98
99 //---------------------------------------------------------
CSG_Grid_System(double Cellsize,const CSG_Rect & Extent)100 CSG_Grid_System::CSG_Grid_System(double Cellsize, const CSG_Rect &Extent)
101 {
102 Create(Cellsize, Extent);
103 }
104
105 //---------------------------------------------------------
CSG_Grid_System(double Cellsize,double xMin,double yMin,double xMax,double yMax)106 CSG_Grid_System::CSG_Grid_System(double Cellsize, double xMin, double yMin, double xMax, double yMax)
107 {
108 Create(Cellsize, xMin, yMin, xMax, yMax);
109 }
110
111 //---------------------------------------------------------
CSG_Grid_System(double Cellsize,double xMin,double yMin,int NX,int NY)112 CSG_Grid_System::CSG_Grid_System(double Cellsize, double xMin, double yMin, int NX, int NY)
113 {
114 Create(Cellsize, xMin, yMin, NX, NY);
115 }
116
117 //---------------------------------------------------------
~CSG_Grid_System(void)118 CSG_Grid_System::~CSG_Grid_System(void)
119 {
120 Destroy();
121 }
122
123
124 ///////////////////////////////////////////////////////////
125 // //
126 ///////////////////////////////////////////////////////////
127
128 //---------------------------------------------------------
Create(const CSG_Grid_System & System)129 bool CSG_Grid_System::Create(const CSG_Grid_System &System)
130 {
131 m_NX = System.m_NX;
132 m_NY = System.m_NY;
133 m_NCells = System.m_NCells;
134
135 m_Cellsize = System.m_Cellsize;
136 m_Cellarea = System.m_Cellarea;
137 m_Diagonal = System.m_Diagonal;
138
139 m_Extent = System.m_Extent;
140 m_Extent_Cells = System.m_Extent_Cells;
141
142 return( is_Valid() );
143 }
144
145 //---------------------------------------------------------
Create(double Cellsize,const CSG_Rect & Extent)146 bool CSG_Grid_System::Create(double Cellsize, const CSG_Rect &Extent)
147 {
148 if( Cellsize > 0. && Extent.Get_XRange() >= 0. && Extent.Get_YRange() >= 0. )
149 {
150 int nx = 1 + (int)(0.5 + Extent.Get_XRange() / Cellsize);
151 int ny = 1 + (int)(0.5 + Extent.Get_YRange() / Cellsize);
152
153 double x = fabs(Cellsize - Extent.Get_XRange() / (nx - 1.)) <= 0. ? Extent.Get_XMin() : Extent.Get_Center().Get_X() - Cellsize * (nx - 1.) / 2.;
154 double y = fabs(Cellsize - Extent.Get_YRange() / (ny - 1.)) <= 0. ? Extent.Get_YMin() : Extent.Get_Center().Get_Y() - Cellsize * (ny - 1.) / 2.;
155
156 return( Create(Cellsize, x, y, nx, ny) );
157 }
158
159 Destroy();
160
161 return( false );
162 }
163
164 //---------------------------------------------------------
Create(double Cellsize,double xMin,double yMin,double xMax,double yMax)165 bool CSG_Grid_System::Create(double Cellsize, double xMin, double yMin, double xMax, double yMax)
166 {
167 return( Create(Cellsize, CSG_Rect(xMin, yMin, xMax, yMax)) );
168 }
169
170 //---------------------------------------------------------
Create(double Cellsize,double xMin,double yMin,int NX,int NY)171 bool CSG_Grid_System::Create(double Cellsize, double xMin, double yMin, int NX, int NY)
172 {
173 if( Cellsize > 0. && NX > 0 && NY > 0 )
174 {
175 Cellsize = SG_Get_Rounded(Cellsize, m_Precision);
176 xMin = SG_Get_Rounded(xMin , m_Precision);
177 yMin = SG_Get_Rounded(yMin , m_Precision);
178
179 if( Cellsize > 0. )
180 {
181 m_NX = NX;
182 m_NY = NY;
183 m_NCells = (sLong)NY * NX;
184
185 m_Cellsize = Cellsize;
186 m_Cellarea = Cellsize * Cellsize;
187 m_Diagonal = Cellsize * sqrt(2.);
188
189 m_Extent.m_rect.xMin = xMin;
190 m_Extent.m_rect.yMin = yMin;
191 m_Extent.m_rect.xMax = xMin + (NX - 1.) * Cellsize;
192 m_Extent.m_rect.yMax = yMin + (NY - 1.) * Cellsize;
193
194 m_Extent_Cells = m_Extent;
195 m_Extent_Cells.Inflate(0.5 * Cellsize, false);
196
197 return( true );
198 }
199 }
200
201 //-----------------------------------------------------
202 m_NX = 0;
203 m_NY = 0;
204 m_NCells = 0;
205
206 m_Cellsize = 0.;
207 m_Cellarea = 0.;
208 m_Diagonal = 0.;
209
210 m_Extent .Assign(0., 0., 0., 0.);
211 m_Extent_Cells .Assign(0., 0., 0., 0.);
212
213 return( false );
214 }
215
216 //---------------------------------------------------------
Destroy(void)217 bool CSG_Grid_System::Destroy(void)
218 {
219 Create(0., 0., 0., 0, 0);
220
221 return( true );
222 }
223
224 //---------------------------------------------------------
Assign(const CSG_Grid_System & System)225 bool CSG_Grid_System::Assign(const CSG_Grid_System &System)
226 { return( Create(System) ); }
227
Assign(double Cellsize,const CSG_Rect & Extent)228 bool CSG_Grid_System::Assign(double Cellsize, const CSG_Rect &Extent)
229 { return( Create(Cellsize, Extent) ); }
230
Assign(double Cellsize,double xMin,double yMin,double xMax,double yMax)231 bool CSG_Grid_System::Assign(double Cellsize, double xMin, double yMin, double xMax, double yMax)
232 { return( Create(Cellsize, xMin, yMin, xMax, yMax) ); }
233
Assign(double Cellsize,double xMin,double yMin,int NX,int NY)234 bool CSG_Grid_System::Assign(double Cellsize, double xMin, double yMin, int NX, int NY)
235 { return( Create(Cellsize, xMin, yMin, NX, NY) ); }
236
237
238 ///////////////////////////////////////////////////////////
239 // //
240 ///////////////////////////////////////////////////////////
241
242 //---------------------------------------------------------
is_Valid(void) const243 bool CSG_Grid_System::is_Valid(void) const
244 {
245 return( m_Cellsize > 0. );
246 }
247
248 //---------------------------------------------------------
Get_Name(bool bShort)249 const SG_Char * CSG_Grid_System::Get_Name(bool bShort)
250 {
251 if( is_Valid() )
252 {
253 if( bShort )
254 {
255 m_Name.Printf("%.*f; %dx %dy; %.*fx %.*fy",
256 SG_Get_Significant_Decimals(Get_Cellsize()), Get_Cellsize(),
257 Get_NX(), Get_NY(),
258 SG_Get_Significant_Decimals(Get_XMin ()), Get_XMin (),
259 SG_Get_Significant_Decimals(Get_YMin ()), Get_YMin ()
260 );
261 }
262 else
263 {
264 m_Name.Printf("%s: %f, %s: %dx/%dy, %s: %fx/%fy",
265 _TL("Cell size" ), Get_Cellsize(),
266 _TL("Number of cells" ), Get_NX(), Get_NY(),
267 _TL("Lower left corner"), Get_XMin(), Get_YMin()
268 );
269 }
270 }
271 else
272 {
273 m_Name = _TL("<not set>");
274 }
275
276 return( m_Name );
277 }
278
279
280 ///////////////////////////////////////////////////////////
281 // //
282 ///////////////////////////////////////////////////////////
283
284 //---------------------------------------------------------
operator ==(const CSG_Grid_System & System) const285 bool CSG_Grid_System::operator == (const CSG_Grid_System &System) const
286 {
287 return( is_Equal(System) );
288 }
289
290 //---------------------------------------------------------
operator =(const CSG_Grid_System & System)291 void CSG_Grid_System::operator = (const CSG_Grid_System &System)
292 {
293 Create(System);
294 }
295
296
297 ///////////////////////////////////////////////////////////
298 // //
299 ///////////////////////////////////////////////////////////
300
301 //---------------------------------------------------------
is_Equal(const CSG_Grid_System & System) const302 bool CSG_Grid_System::is_Equal(const CSG_Grid_System &System) const
303 {
304 return( m_Cellsize == System.m_Cellsize
305 && m_NX == System.m_NX
306 && m_NY == System.m_NY
307 && m_Extent.m_rect.xMin == System.m_Extent.m_rect.xMin
308 && m_Extent.m_rect.yMin == System.m_Extent.m_rect.yMin
309 );
310 }
311
312 //---------------------------------------------------------
is_Equal(double Cellsize,const TSG_Rect & Extent) const313 bool CSG_Grid_System::is_Equal(double Cellsize, const TSG_Rect &Extent) const
314 {
315 return( m_Cellsize == Cellsize && m_Extent == Extent );
316 }
317
318
319 ///////////////////////////////////////////////////////////
320 // //
321 // //
322 // //
323 ///////////////////////////////////////////////////////////
324
325 //---------------------------------------------------------
CSG_Grid_Cell_Addressor(void)326 CSG_Grid_Cell_Addressor::CSG_Grid_Cell_Addressor(void)
327 {
328 m_Kernel.Add_Field("X", SG_DATATYPE_Int );
329 m_Kernel.Add_Field("Y", SG_DATATYPE_Int );
330 m_Kernel.Add_Field("D", SG_DATATYPE_Double);
331 m_Kernel.Add_Field("W", SG_DATATYPE_Double);
332 }
333
334 //---------------------------------------------------------
Destroy(void)335 bool CSG_Grid_Cell_Addressor::Destroy(void)
336 {
337 m_Kernel.Del_Records();
338
339 m_Radius = 1.;
340 m_Radius_0 = 0.;
341 m_Direction = 0.;
342 m_Tolerance = 0.;
343
344 return( true );
345 }
346
347
348 ///////////////////////////////////////////////////////////
349 // //
350 ///////////////////////////////////////////////////////////
351
352 //---------------------------------------------------------
Add_Parameters(CSG_Parameters & Parameters,const CSG_String & Parent,int Style)353 bool CSG_Grid_Cell_Addressor::Add_Parameters(CSG_Parameters &Parameters, const CSG_String &Parent, int Style)
354 {
355 CSG_String Types;
356
357 if( (Style & SG_GRIDCELLADDR_PARM_SQUARE ) != 0 )
358 {
359 Types += CSG_String::Format("{%d}%s|", SG_GRIDCELLADDR_PARM_SQUARE , _TL("Square" ));
360 }
361
362 if( (Style & SG_GRIDCELLADDR_PARM_CIRCLE ) != 0 )
363 {
364 Types += CSG_String::Format("{%d}%s|", SG_GRIDCELLADDR_PARM_CIRCLE , _TL("Circle" ));
365 }
366
367 if( (Style & SG_GRIDCELLADDR_PARM_ANNULUS) != 0 )
368 {
369 Types += CSG_String::Format("{%d}%s|", SG_GRIDCELLADDR_PARM_ANNULUS, _TL("Annulus"));
370 }
371
372 if( (Style & SG_GRIDCELLADDR_PARM_SECTOR ) != 0 )
373 {
374 Types += CSG_String::Format("{%d}%s|", SG_GRIDCELLADDR_PARM_SECTOR , _TL("Sector" ));
375 }
376
377 Parameters.Add_Choice(Parent, "KERNEL_TYPE", _TL("Kernel Type"),
378 _TL("The kernel's shape."),
379 Types, 1
380 );
381
382 Parameters.Set_Enabled("KERNEL_TYPE", Parameters("KERNEL_TYPE")->asChoice()->Get_Count() > 1);
383
384 //-----------------------------------------------------
385 CSG_String Unit_Radius((Style & SG_GRIDCELLADDR_PARM_MAPUNIT) == 0 ? _TL("cells") : _TL("map units"));
386
387 if( (Style & SG_GRIDCELLADDR_PARM_SIZEDBL) != 0 )
388 {
389 if( (Style & SG_GRIDCELLADDR_PARM_ANNULUS) != 0 )
390 {
391 Parameters.Add_Double("KERNEL_TYPE", "KERNEL_INNER" , _TL("Inner Radius"), Unit_Radius, 0., 0., true);
392 }
393
394 Parameters .Add_Double("KERNEL_TYPE", "KERNEL_RADIUS", _TL( "Radius"), Unit_Radius, 1., 0., true);
395 }
396 else
397 {
398 if( (Style & SG_GRIDCELLADDR_PARM_ANNULUS) != 0 )
399 {
400 Parameters.Add_Int ("KERNEL_TYPE", "KERNEL_INNER" , _TL("Inner Radius"), Unit_Radius, 0 , 0 , true);
401 }
402
403 Parameters .Add_Int ("KERNEL_TYPE", "KERNEL_RADIUS", _TL( "Radius"), Unit_Radius, 2 , 0 , true);
404 }
405
406 //-----------------------------------------------------
407 if( (Style & SG_GRIDCELLADDR_PARM_SECTOR) != 0 )
408 {
409 Parameters.Add_Double("KERNEL_TYPE", "KERNEL_DIRECTION", _TL("Direction"), _TL("degree"), 0., -360., true, 360., true);
410 Parameters.Add_Double("KERNEL_TYPE", "KERNEL_TOLERANCE", _TL("Tolerance"), _TL("degree"), 5., 0., true, 180., true);
411 }
412
413 if( (Style & SG_GRIDCELLADDR_PARM_WEIGHTING) != 0 )
414 {
415 CSG_Distance_Weighting::Add_Parameters(Parameters,
416 Parameters("KERNEL_TYPE")->is_Enabled() ? CSG_String("KERNEL_TYPE") : Parent
417 );
418 }
419
420 return( true );
421 }
422
423 //---------------------------------------------------------
Set_Parameters(CSG_Parameters & Parameters,int Type)424 bool CSG_Grid_Cell_Addressor::Set_Parameters(CSG_Parameters &Parameters, int Type)
425 {
426 if( Type == 0 && Parameters("KERNEL_TYPE") )
427 {
428 Parameters("KERNEL_TYPE")->asChoice()->Get_Data(Type);
429 }
430
431 switch( Type )
432 {
433 case SG_GRIDCELLADDR_PARM_SQUARE:
434 return( Set_Radius(
435 Parameters("KERNEL_RADIUS" )->asDouble(),
436 true
437 ));
438
439 case SG_GRIDCELLADDR_PARM_CIRCLE:
440 return( Set_Radius(
441 Parameters("KERNEL_RADIUS" )->asDouble(),
442 false
443 ));
444
445 case SG_GRIDCELLADDR_PARM_ANNULUS:
446 return( Set_Annulus(
447 Parameters("KERNEL_INNER" )->asDouble(),
448 Parameters("KERNEL_RADIUS" )->asDouble()
449 ));
450
451 case SG_GRIDCELLADDR_PARM_SECTOR:
452 return( Set_Sector(
453 Parameters("KERNEL_RADIUS" )->asDouble(),
454 Parameters("KERNEL_DIRECTION")->asDouble() * M_DEG_TO_RAD,
455 Parameters("KERNEL_TOLERANCE")->asDouble() * M_DEG_TO_RAD
456 ));
457 }
458
459 return( false );
460 }
461
462 //---------------------------------------------------------
Set_Square(CSG_Parameters & Parameters)463 bool CSG_Grid_Cell_Addressor::Set_Square (CSG_Parameters &Parameters) { return( Set_Parameters(Parameters, SG_GRIDCELLADDR_PARM_SQUARE ) ); }
Set_Circle(CSG_Parameters & Parameters)464 bool CSG_Grid_Cell_Addressor::Set_Circle (CSG_Parameters &Parameters) { return( Set_Parameters(Parameters, SG_GRIDCELLADDR_PARM_CIRCLE ) ); }
Set_Annulus(CSG_Parameters & Parameters)465 bool CSG_Grid_Cell_Addressor::Set_Annulus(CSG_Parameters &Parameters) { return( Set_Parameters(Parameters, SG_GRIDCELLADDR_PARM_ANNULUS) ); }
Set_Sector(CSG_Parameters & Parameters)466 bool CSG_Grid_Cell_Addressor::Set_Sector (CSG_Parameters &Parameters) { return( Set_Parameters(Parameters, SG_GRIDCELLADDR_PARM_SECTOR ) ); }
467
468
469 ///////////////////////////////////////////////////////////
470 // //
471 ///////////////////////////////////////////////////////////
472
473 //---------------------------------------------------------
Enable_Parameters(CSG_Parameters & Parameters)474 bool CSG_Grid_Cell_Addressor::Enable_Parameters(CSG_Parameters &Parameters)
475 {
476 if( Parameters("KERNEL_TYPE") )
477 {
478 int Type = Parameters("KERNEL_TYPE")->asChoice()->Get_Item_Data(Parameters("KERNEL_TYPE")->asInt()).asInt();
479
480 Parameters.Set_Enabled("KERNEL_INNER" , Type == SG_GRIDCELLADDR_PARM_ANNULUS);
481 Parameters.Set_Enabled("KERNEL_DIRECTION", Type == SG_GRIDCELLADDR_PARM_SECTOR );
482 Parameters.Set_Enabled("KERNEL_TOLERANCE", Type == SG_GRIDCELLADDR_PARM_SECTOR );
483 }
484
485 CSG_Distance_Weighting::Enable_Parameters(Parameters);
486
487 return( true );
488 }
489
490
491 ///////////////////////////////////////////////////////////
492 // //
493 ///////////////////////////////////////////////////////////
494
495 //---------------------------------------------------------
_Set_Kernel(int Type,double Radius,double Radius_Inner,double Direction,double Tolerance)496 bool CSG_Grid_Cell_Addressor::_Set_Kernel(int Type, double Radius, double Radius_Inner, double Direction, double Tolerance)
497 {
498 Destroy();
499
500 m_Type = Type;
501 m_Radius = Radius;
502 m_Radius_0 = Radius_Inner;
503 m_Direction = fmod(Direction, M_PI_360); if( Direction < 0. ) Direction += M_PI_360;
504 m_Tolerance = fmod(Tolerance, M_PI_180); if( Tolerance < 0. ) Tolerance += M_PI_180;
505
506 if( m_Radius < 0. || m_Radius < m_Radius_0 )
507 {
508 return( false );
509 }
510
511 CSG_Vector Sector(2);
512
513 if( m_Type == 3 ) // sector
514 {
515 Sector[0] = fmod(Direction - Tolerance, M_PI_360); if( Sector[0] < 0. ) Sector[0] += M_PI_360;
516 Sector[1] = fmod(Direction + Tolerance, M_PI_360); if( Sector[1] < 0. ) Sector[1] += M_PI_360;
517 }
518
519 //-----------------------------------------------------
520 #define ADD_CELL(x, y, Distance) {\
521 CSG_Table_Record &Cell = *Kernel.Add_Record();\
522 Cell.Set_Value(0, x);\
523 Cell.Set_Value(1, y);\
524 Cell.Set_Value(2, Distance);\
525 Cell.Set_Value(3, m_Weighting.Get_Weight(d));\
526 }
527
528 CSG_Table Kernel(&m_Kernel);
529
530 int Size = (int)ceil(m_Radius);
531
532 //-----------------------------------------------------
533 for(int y=-Size; y<=Size; y++)
534 {
535 if( abs(y) > m_Radius )
536 continue;
537
538 for(int x=-Size; x<=Size; x++)
539 {
540 if( abs(x) > m_Radius )
541 continue;
542
543 double d = SG_Get_Length(x, y);
544
545 switch( m_Type )
546 {
547 default: // square
548 ADD_CELL(x, y, d);
549 break;
550
551 case 1: // circle
552 if( d <= m_Radius )
553 {
554 ADD_CELL(x, y, d);
555 }
556 break;
557
558 case 2: // annulus
559 if( d <= m_Radius && d >= m_Radius_0 )
560 {
561 ADD_CELL(x, y, d);
562 }
563 break;
564
565 case 3: // sector
566 if( d <= m_Radius && d >= m_Radius_0 && ((x == 0 && y == 0) || SG_is_Angle_Between(SG_Get_Angle_Of_Direction(x, y), Sector[0], Sector[1], false)) )
567 {
568 ADD_CELL(x, y, d);
569 }
570 break;
571 }
572 }
573 }
574
575 //-----------------------------------------------------
576 if( Kernel.Get_Count() < 1 )
577 {
578 return( false );
579 }
580
581 Kernel.Set_Index(2, TABLE_INDEX_Ascending);
582
583 for(int i=0; i<Kernel.Get_Count(); i++)
584 {
585 m_Kernel.Add_Record(Kernel.Get_Record_byIndex(i));
586 }
587
588 return( true );
589 }
590
591 //---------------------------------------------------------
Set_Radius(double Radius,bool bSquare)592 bool CSG_Grid_Cell_Addressor::Set_Radius(double Radius, bool bSquare)
593 {
594 return( bSquare ? Set_Square(Radius) : Set_Circle(Radius) );
595 }
596
597 //---------------------------------------------------------
Set_Square(double Radius)598 bool CSG_Grid_Cell_Addressor::Set_Square(double Radius)
599 {
600 return( _Set_Kernel(0, Radius, 0., 0., 0.) );
601 }
602
603 //---------------------------------------------------------
Set_Circle(double Radius)604 bool CSG_Grid_Cell_Addressor::Set_Circle(double Radius)
605 {
606 return( _Set_Kernel(1, Radius, 0., 0., 0.) );
607 }
608
609 //---------------------------------------------------------
Set_Annulus(double Radius_Inner,double Radius_Outer)610 bool CSG_Grid_Cell_Addressor::Set_Annulus(double Radius_Inner, double Radius_Outer)
611 {
612 return( _Set_Kernel(2, Radius_Outer, Radius_Inner, 0., 0.) );
613 }
614
615 //---------------------------------------------------------
Set_Sector(double Radius,double Direction,double Tolerance)616 bool CSG_Grid_Cell_Addressor::Set_Sector(double Radius, double Direction, double Tolerance)
617 {
618 return( _Set_Kernel(3, Radius, 0., Direction, Tolerance) );
619 }
620
621
622 ///////////////////////////////////////////////////////////
623 // //
624 // //
625 // //
626 ///////////////////////////////////////////////////////////
627
628 //---------------------------------------------------------
629