@@ -197,23 +197,40 @@ public void DrawPeriodicPoint(LocalCS cs, Geometry.Point point, Geometry.Box box
197197 PointF p = cs . Convert ( point ) ;
198198 DrawPoint ( p ) ;
199199
200- double pi2 = 2 * Geometry . HalfAngle ( unit ) ;
200+ double twoPi = Geometry . FullAngle ( unit ) ;
201201 Pen pen = drawDots ? this . penDot : this . pen ;
202- // draw points on the west
203- double x_tmp = point [ 0 ] - pi2 ;
204- while ( x_tmp >= box . Min [ 0 ] )
202+
203+ // NOTE: Use AssignChanged becasue for big coordinates subtracting/adding
204+ // twoPi doesn't change the value of x_tmp which causes infinite loop
205+
206+ float x = Math . Min ( Math . Max ( p . X , 0.0f ) , cs . Width ) ;
207+ double nPeriodsWest = ( point [ 0 ] - box . Min [ 0 ] ) / twoPi ;
208+ float pixelsWest = x ;
209+ double nPeriodsEast = ( box . Max [ 0 ] - point [ 0 ] ) / twoPi ;
210+ float pixelsEast = cs . Width - x ;
211+
212+ if ( nPeriodsWest <= pixelsWest / 5 )
205213 {
206- p . X = cs . ConvertX ( x_tmp ) ;
207- DrawPoint ( p , pen ) ;
208- x_tmp -= pi2 ;
214+ // draw points on the west
215+ double x_tmp = point [ 0 ] ;
216+ while ( Util . Assign ( ref x_tmp , x_tmp - twoPi )
217+ && x_tmp >= box . Min [ 0 ] )
218+ {
219+ p . X = cs . ConvertX ( x_tmp ) ;
220+ DrawPoint ( p , pen ) ;
221+ }
209222 }
210- // draw points on the east
211- x_tmp = point [ 0 ] + pi2 ;
212- while ( x_tmp <= box . Max [ 0 ] )
223+
224+ if ( nPeriodsEast <= pixelsEast / 5 )
213225 {
214- p . X = cs . ConvertX ( x_tmp ) ;
215- DrawPoint ( p , pen ) ;
216- x_tmp += pi2 ;
226+ // draw points on the east
227+ double x_tmp = point [ 0 ] ;
228+ while ( Util . Assign ( ref x_tmp , x_tmp + twoPi )
229+ && x_tmp <= box . Max [ 0 ] )
230+ {
231+ p . X = cs . ConvertX ( x_tmp ) ;
232+ DrawPoint ( p , pen ) ;
233+ }
217234 }
218235 }
219236
@@ -359,7 +376,7 @@ private static PointF[] DensifyAndConvert(LocalCS cs, Geometry.Point p0, Geometr
359376 {
360377 double distNorm = Geometry . NormalizedAngleSigned ( p1 [ 0 ] - p0 [ 0 ] , unit ) ;
361378 bool intersPole = IsAntipodal ( distNorm , unit ) ;
362- double halfPi = Geometry . HalfAngle ( unit ) / 2 ;
379+ double halfPi = Geometry . RightAngle ( unit ) ;
363380 double poleLat = p1 [ 1 ] - p0 [ 1 ] >= 0 ? halfPi : - halfPi ;
364381 int intersPoleIndex = - 1 ;
365382
@@ -400,7 +417,7 @@ private static PointF[] DensifyAndConvert(LocalCS cs, Geometry.Point p0, Geometr
400417
401418 public static bool IsAntipodal ( double distNorm , Geometry . Unit unit )
402419 {
403- double pi = Geometry . HalfAngle ( unit ) ;
420+ double pi = Geometry . StraightAngle ( unit ) ;
404421 return Math . Abs ( Math . Abs ( distNorm ) - pi ) < double . Epsilon * pi ;
405422 }
406423
@@ -609,8 +626,8 @@ public void DrawPeriodic(LocalCS cs,
609626 IPeriodicDrawable drawer ,
610627 bool fill , bool drawDirs , bool drawDots )
611628 {
612- double pi = Geometry . HalfAngle ( unit ) ;
613- float periodf = cs . ConvertDimensionX ( 2 * pi ) ;
629+ double twoPi = Geometry . FullAngle ( unit ) ;
630+ float periodf = cs . ConvertDimensionX ( twoPi ) ;
614631 float box_minf = cs . ConvertX ( box . Min [ 0 ] ) ;
615632 float box_maxf = cs . ConvertX ( box . Max [ 0 ] ) ;
616633
@@ -624,22 +641,24 @@ public void DrawPeriodic(LocalCS cs,
624641 float minf_i = minf ;
625642 float maxf_i = maxf ;
626643 float translationf = 0 ;
627- while ( maxf_i >= box_minf )
644+ while ( maxf_i >= box_minf
645+ && Util . Assign ( ref maxf_i , maxf_i - periodf ) )
628646 {
629647 translationf -= periodf ;
630648 minf_i -= periodf ;
631- maxf_i -= periodf ;
649+ // maxf_i -= periodf; // subtracted above
632650 if ( maxf_i >= box_minf && minf_i <= box_maxf )
633651 drawer . DrawOne ( this , translationf , fill , drawDirs , drawDots ) ;
634652 }
635653 // east
636654 minf_i = minf ;
637655 maxf_i = maxf ;
638656 translationf = 0 ;
639- while ( minf_i <= box_maxf )
657+ while ( minf_i <= box_maxf
658+ && Util . Assign ( ref minf_i , minf_i + periodf ) )
640659 {
641660 translationf += periodf ;
642- minf_i += periodf ;
661+ // minf_i += periodf; // added above
643662 maxf_i += periodf ;
644663 if ( maxf_i >= box_minf && minf_i <= box_maxf )
645664 drawer . DrawOne ( this , translationf , fill , drawDirs , drawDots ) ;
@@ -694,7 +713,7 @@ public static bool DrawAxes(Graphics graphics, Geometry.Box box, Geometry.Unit u
694713 Pen anti_pen = new Pen ( colors . AxisColor , 1 ) ;
695714 anti_pen . DashStyle = DashStyle . Custom ;
696715 anti_pen . DashPattern = new float [ ] { 5 , 5 } ;
697- double pi = Geometry . HalfAngle ( unit ) ;
716+ double pi = Geometry . StraightAngle ( unit ) ;
698717 double anti_mer = Geometry . NearestAntimeridian ( box . Min [ 0 ] , - 1 , unit ) ;
699718 double prime_mer = anti_mer + pi ;
700719 double next_anti_mer = anti_mer + 2 * pi ;
@@ -706,21 +725,34 @@ public static bool DrawAxes(Graphics graphics, Geometry.Box box, Geometry.Unit u
706725 float prime_mer_step = cs . ConvertX ( next_prime_mer ) - prime_mer_f ;
707726
708727 // Antimeridians
709- for ( ; anti_mer_f <= w ; anti_mer_f += anti_mer_step )
728+ while ( anti_mer_f <= w
729+ // NOTE: For bug coordinates anti_mer_step may be 0 which results in infinite loop
730+ && Util . Assign ( ref anti_mer_f , anti_mer_f + anti_mer_step ) )
710731 {
711732 if ( anti_mer_f >= 0 )
712733 {
713734 graphics . DrawLine ( anti_pen , anti_mer_f , 0 , anti_mer_f , h ) ;
714735 }
715736 }
716737 // Prime meridians
717- for ( ; prime_mer_f <= w ; prime_mer_f += prime_mer_step )
738+ bool primeMeridiansDrawn = false ;
739+ while ( prime_mer_f <= w
740+ // NOTE: For bug coordinates anti_mer_step may be 0 which results in infinite loop
741+ && Util . Assign ( ref prime_mer_f , prime_mer_f += prime_mer_step ) )
718742 {
719743 if ( prime_mer_f >= 0 )
720744 {
721745 graphics . DrawLine ( prime_pen , prime_mer_f , 0 , prime_mer_f , h ) ;
746+ primeMeridiansDrawn = true ;
722747 }
723748 }
749+ // Prime meridian
750+ float p = cs . ConvertX ( 0.0 ) ;
751+ if ( ! primeMeridiansDrawn
752+ && 0 <= p && p <= w )
753+ {
754+ graphics . DrawLine ( prime_pen , p , 0 , p , h ) ;
755+ }
724756 // Equator
725757 float e = cs . ConvertY ( 0.0 ) ;
726758 if ( 0 <= e && e <= h )
@@ -1192,6 +1224,9 @@ public Geometry.Box ViewBox()
11921224 new Geometry . Point ( InverseConvertX ( dst_orig_w ) , InverseConvertY ( 0 ) ) ) ;
11931225 }
11941226
1227+ public float Width { get { return dst_orig_w ; } }
1228+ public float Height { get { return dst_orig_h ; } }
1229+
11951230 float dst_orig_w , dst_orig_h ;
11961231 float dst_x0 , dst_y0 ;
11971232 double src_x0 , src_y0 ;
0 commit comments