;+ ; NAME: ; PlotDashes ; CALLING SEQUENCE: PRO PlotDashes, x, y, $ dashes = dashes , $ absolute = absolute , $ _extra = _extra ; INCLUDE: @compile_opt.pro ;- InitVar, absolute, /key InitVar, dashes, [0.05,0.05] ; Normal units ; Convert data coordinates to normalized coordinates. pp = (convert_coord( transpose( [ [x], [y] ] ), /data, /to_normal))[0:1,*] ; Start with pen-down in first point pen_down = 1 pen = pp[*,0] plot_points = pp[*,0] iseg = 0 nseg = n_elements(dashes) dash_to_draw = dashes[iseg mod nseg] CASE absolute OF 0: BEGIN FOR i=1,n_elements(pp)/2-1 DO BEGIN ; Distance from pen position to next point on line ; We're going to move the pen to this point from the ; current pen position. distance_to_next_point = sqrt( total((pp[*,i]-pen)^2) ) IF distance_to_next_point EQ 0 THEN continue ; Determine direction to next point alfa = atan(pp[1,i]-pp[1,i-1],pp[0,i]-pp[0,i-1]) cos_alfa = cos(alfa) sin_alfa = sin(alfa) ; If dash_to_draw <= distance_to_next_point then the pen ; position needs to be changed before the next point is reached. WHILE dash_to_draw LE distance_to_next_point DO BEGIN ; Finish the current dash pen += [cos_alfa,sin_alfa]*dash_to_draw IF pen_down THEN plot_points = [ [plot_points], [pen] ] ; Update distance to next point distance_to_next_point -= dash_to_draw ; Change pen position pen_down = 1-pen_down IF pen_down THEN BEGIN plot_points = pen ENDIF ELSE BEGIN plots, /normal, plot_points[0,*], plot_points[1,*], _extra=_extra destroyvar, plot_points ; Not necessary, but makes me feel better ENDELSE dash_to_draw = dashes[++iseg mod nseg] ENDWHILE ; Now dash_to_draw > distance_to_next_point. This dash will be ; completed past the next point. Draw the part up to the point IF distance_to_next_point GT 0 THEN BEGIN IF pen_down THEN plot_points = [ [plot_points], [pp[*,i]] ] pen = pp[*,i] dash_to_draw -= distance_to_next_point ENDIF ENDFOR END 1: BEGIN FOR i=1,n_elements(pp)/2-1 DO BEGIN ; Distance from pen position to next point on line ; We're going to move the pen to this point from the ; current pen position. distance_to_next_point = sqrt( total((pp[*,i]-pen)^2) ) IF distance_to_next_point LT dash_to_draw THEN BEGIN IF pen_down THEN plot_points = [ [plot_points], [pp[*,i]] ] continue ENDIF ; Now distance_to_next_point >= dash_to_draw ; Find point between pp[*,i-1] and pp[*,i] where distance is equal to ; dash_to_draw. We use linear interpolation (not exact! so probably ; will backfire someday). ; distance_to_previous_point is less than dash_to_draw distance_to_previous_point = sqrt( total((pp[*,i-1]-pen)^2) ) fraction = (distance_to_next_point-dash_to_draw)/(distance_to_next_point-distance_to_previous_point) pen = (1-fraction)*pp[*,i]+fraction*pp[*,i-1] IF pen_down THEN plot_points = [ [plot_points], [pen] ] pen_down = 1-pen_down IF pen_down THEN BEGIN plot_points = pen ENDIF ELSE BEGIN plots, /normal, plot_points[0,*], plot_points[1,*], _extra=_extra destroyvar, plot_points ; Not necessary, but makes me feel better ENDELSE dash_to_draw = dashes[++iseg mod nseg] ENDFOR END ENDCASE RETURN & END