@@ -716,50 +716,85 @@ def tri_area2(x, y, i0, i1, i2):
716716def visvalingam (x , y , fixed_size = 18 ):
717717 """Polygon simplification with visvalingam algorithm
718718
719+ X, Y are considered like a polygon, the next point after the last one is the first one
719720 :param array x:
720721 :param array y:
721722 :param int fixed_size: array size of out
722- :return: New (x, y) array
723+ :return:
724+ New (x, y) array, last position will be equal to first one, if array size is 6,
725+ there is only 5 point.
723726 :rtype: array,array
727+
728+ .. plot::
729+
730+ import matplotlib.pyplot as plt
731+ import numpy as np
732+ from py_eddy_tracker.poly import visvalingam
733+
734+ x = np.array([1, 2, 3, 4, 5, 6.75, 6, 1])
735+ y = np.array([-0.5, -1.5, -1, -1.75, -1, -1, -0.5, -0.5])
736+ ax = plt.subplot(111)
737+ ax.set_aspect("equal")
738+ ax.grid(True), ax.set_ylim(-2, -.2)
739+ ax.plot(x, y, "r", lw=5)
740+ ax.plot(*visvalingam(x,y,6), "b", lw=2)
741+ plt.show()
724742 """
743+ # TODO : in case of original size lesser than fixed size, jump at the end
725744 nb = x .shape [0 ]
726- i0 , i1 = nb - 3 , nb - 2
745+ nb_ori = nb
746+ # Get indice of first triangle
747+ i0 , i1 = nb - 2 , nb - 1
748+ # Init heap with first area and tiangle
727749 h = [(tri_area2 (x , y , i0 , i1 , 0 ), (i0 , i1 , 0 ))]
750+ # Roll index for next one
728751 i0 = i1
729752 i1 = 0
730- i_previous = empty (nb - 1 , dtype = numba_types .int32 )
731- i_next = empty (nb - 1 , dtype = numba_types .int32 )
753+ # Index of previous valid point
754+ i_previous = empty (nb , dtype = numba_types .int64 )
755+ # Index of next valid point
756+ i_next = empty (nb , dtype = numba_types .int64 )
757+ # Mask of removed
758+ removed = zeros (nb , dtype = numba_types .bool_ )
732759 i_previous [0 ] = - 1
733760 i_next [0 ] = - 1
734- for i in range (1 , nb - 1 ):
761+ for i in range (1 , nb ):
735762 i_previous [i ] = - 1
736763 i_next [i ] = - 1
764+ # We add triangle area for all triangle
737765 heapq .heappush (h , (tri_area2 (x , y , i0 , i1 , i ), (i0 , i1 , i )))
738766 i0 = i1
739767 i1 = i
740768 # we continue until we are equal to nb_pt
741- while len ( h ) >= fixed_size :
769+ while nb >= fixed_size :
742770 # We pop lower area
743771 _ , (i0 , i1 , i2 ) = heapq .heappop (h )
744772 # We check if triangle is valid(i0 or i2 not removed)
745- i_p , i_n = i_previous [i0 ], i_next [i2 ]
746- if i_p == - 1 and i_n == - 1 :
747- # We store reference of delete point
748- i_previous [i1 ] = i0
749- i_next [i1 ] = i2
773+ if removed [i0 ] or removed [i2 ]:
774+ # In this cas nothing to do
750775 continue
751- elif i_p == - 1 :
752- i2 = i_n
753- elif i_n == - 1 :
754- i0 = i_p
755- else :
756- # in this case we replace two point
757- i0 , i2 = i_p , i_n
758- heapq .heappush (h , (tri_area2 (x , y , i0 , i1 , i2 ), (i0 , i1 , i2 )))
776+ # Flag obs like removed
777+ removed [i1 ] = True
778+ # We count point still valid
779+ nb -= 1
780+ # Modify index for the next and previous, we jump over i1
781+ i_previous [i2 ] = i0
782+ i_next [i0 ] = i2
783+ # We insert 2 triangles which are modified by the deleted point
784+ # Previous triangle
785+ i_1 = i_previous [i0 ]
786+ if i_1 == - 1 :
787+ i_1 = (i0 - 1 ) % nb_ori
788+ heapq .heappush (h , (tri_area2 (x , y , i_1 , i0 , i2 ), (i_1 , i0 , i2 )))
789+ # Previous triangle
790+ i3 = i_next [i2 ]
791+ if i3 == - 1 :
792+ i3 = (i2 + 1 ) % nb_ori
793+ heapq .heappush (h , (tri_area2 (x , y , i0 , i2 , i3 ), (i0 , i2 , i3 )))
759794 x_new , y_new = empty (fixed_size , dtype = x .dtype ), empty (fixed_size , dtype = y .dtype )
760795 j = 0
761- for i , i_n in enumerate (i_next ):
762- if i_n == - 1 :
796+ for i , flag in enumerate (removed ):
797+ if not flag :
763798 x_new [j ] = x [i ]
764799 y_new [j ] = y [i ]
765800 j += 1
@@ -872,34 +907,6 @@ def poly_indexs(x_p, y_p, x_c, y_c):
872907 return indexs
873908
874909
875- @njit (cache = True )
876- def poly_indexs_old (x_p , y_p , x_c , y_c ):
877- """
878- index of contour for each postion inside a contour, -1 in case of no contour
879-
880- :param array x_p: longitude to test
881- :param array y_p: latitude to test
882- :param array x_c: longitude of contours
883- :param array y_c: latitude of contours
884- """
885- nb_p = x_p .shape [0 ]
886- nb_c = x_c .shape [0 ]
887- indexs = - ones (nb_p , dtype = numba_types .int32 )
888- for i in range (nb_c ):
889- x_ , y_ = reduce_size (x_c [i ], y_c [i ])
890- x_c_min , y_c_min = x_ .min (), y_ .min ()
891- x_c_max , y_c_max = x_ .max (), y_ .max ()
892- v = create_vertice (x_ , y_ )
893- for j in range (nb_p ):
894- if indexs [j ] != - 1 :
895- continue
896- x , y = x_p [j ], y_p [j ]
897- if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max :
898- if winding_number_poly (x , y , v ) != 0 :
899- indexs [j ] = i
900- return indexs
901-
902-
903910@njit (cache = True )
904911def insidepoly (x_p , y_p , x_c , y_c ):
905912 """
0 commit comments