Minimum (single axis) distance between two 2D polylines

Minimum (single axis) distance between two 2D polylines

Dalephilip93
Explorer Explorer
3,433 Views
24 Replies
Message 1 of 25

Minimum (single axis) distance between two 2D polylines

Dalephilip93
Explorer
Explorer

Hey everyone, I'm looking for a function to get the minimum distance between two polylines on a single axis (Y-axis in this case).

 

Does anyone have a suggestion on how to create a LISP for this?

The function would produce a line that indicates the location where the two lines are closest on the Y-Axis. It's not difficult to do this manually but need to automate it as I need to do it frequently.

 

Example:

The function produces the white line automatically between the red & blue line below

Dalephilip93_0-1680474972584.png

 

Thanks for any help.

 

0 Likes
3,434 Views
24 Replies
Replies (24)
Message 21 of 25

komondormrex
Mentor
Mentor

hey,

you are seemingly more in need than the op is)

 

here you go)

 

 

 

;**********************************************************************************************************************************

;	komondormrex, apr 2023

;**********************************************************************************************************************************

(defun arc_segment_center (bulge start_point end_point / arc_segment_direction half_included_angle
														 center_position center_distance arc_segment_center
						  )
	(setq arc_segment_direction (/ bulge (abs bulge))
		  half_included_angle (* 2.0 (atan (abs bulge)))
		  center_position (cond
								(
									(< pi (* 2.0 half_included_angle))
										(setq center_distance (/ (* 0.5 (distance start_point end_point))
																 (/ (sin (- pi half_included_angle))
																 	(cos (- pi half_included_angle))
																  )
															  )
										)
										-1.0			;	center point inside arc
								)
								(
									(> pi (* 2.0 half_included_angle))
										(setq center_distance (/ (* 0.5 (distance start_point end_point))
																 (/ (sin half_included_angle)
																 	(cos half_included_angle)
																 )
															  )
										)
										+1.0            ;	center point outside arc
								)
								(
									t
										(setq center_distance 0.0)
										 0.0            ;	center point halfway from arc start poit to arc end point
								)
						  )
		  arc_segment_center (polar (polar start_point (angle start_point end_point) (* 0.5 (distance start_point end_point)))
		  							(+ (angle start_point end_point) (* arc_segment_direction center_position 0.5 pi))
									center_distance
							 )
	)
)

;**********************************************************************************************************************************

(defun get_pline_arc_x_center_list (pline_object / center_x_list bulge_index)
	(setq bulge_index -1)
	(repeat (fix (vlax-curve-getendparam pline_object))
		(if (not (zerop (setq bulge (vla-getbulge pline_object (setq bulge_index (1+ bulge_index))))))
				(setq center_x_list (append center_x_list
											(list (car (arc_segment_center bulge
																	(trans (vlax-curve-getpointatparam pline_object bulge_index) 0 1)
																	(trans (vlax-curve-getpointatparam pline_object (1+ bulge_index)) 0 1)
												 	   )
												  )
											)
									)
				)
		)
	)
	center_x_list
)

;**********************************************************************************************************************************

(defun get_y_fartherst_intersection (probe curve_object / raw_intersection_point_list intersection_point_list )
	(if (< 3 (length (setq raw_intersection_point_list (vlax-invoke probe 'intersectwith curve_object acextendnone))))
			(progn
				(repeat (/ (length raw_intersection_point_list) 3)
					(setq intersection_point_list (append intersection_point_list (list (list (car raw_intersection_point_list)
																							  (cadr raw_intersection_point_list)
																							  (caddr raw_intersection_point_list)
																						)
																				  )
												  )
						  raw_intersection_point_list (cdddr raw_intersection_point_list)
					)
				)
				(car (vl-sort intersection_point_list '(lambda (point_1 point_2) (> (cadr point_1) (cadr point_2)))))
			)
			raw_intersection_point_list
	)
)

;**********************************************************************************************************************************

(defun c:Y_most_proximity ( / 1st_curve_object 2nd_curve_object y_list min_Y max_Y min_proximity probe_line_object both_curves_x_list
            probe_intersection_1 probe_intersection_2 probe_proximity proximity_point_1 proximity_point_2
        )
	(setq 1st_curve_object (vlax-ename->vla-object (setq 1st_curve_ename (car (entsel "\nPick 1st pline: "))))
	      2nd_curve_object (vlax-ename->vla-object (setq 2nd_curve_ename (car (entsel "\nPick 2nd pline: "))))
	)
    (vla-getboundingbox 1st_curve_object 'llc 'ruc)
    (setq y_list (list (cadr (vlax-safearray->list llc)) (cadr (vlax-safearray->list ruc))))
    (vla-getboundingbox 2nd_curve_object 'llc 'ruc)
    (setq y_list (append y_list (list (cadr (vlax-safearray->list llc)) (cadr (vlax-safearray->list ruc))))
          min_Y (- (apply 'min y_list) 5)
          max_Y (+ (apply 'max y_list) 5)
		  min_proximity (- (apply 'max y_list) (apply 'min y_list))
		  probe_line_object (vla-addline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
                  						 (vlax-3d-point (list 0 min_Y))
                  						 (vlax-3d-point (list 0 max_Y))
         					)
          both_curves_x_list (append (mapcar 'cadr (vl-remove-if '(lambda (group) (/= 10 (car group))) (entget 1st_curve_ename)))
                  					 (mapcar 'cadr (vl-remove-if '(lambda (group) (/= 10 (car group))) (entget 2nd_curve_ename)))
									 (get_pline_arc_x_center_list 1st_curve_object)
									 (get_pline_arc_x_center_list 2nd_curve_object)
         					 )
	)
    (foreach x both_curves_x_list
		(vla-move probe_line_object (vla-get-startpoint probe_line_object) (vlax-3d-point (list x min_Y)))
      	(if (and (setq probe_intersection_1 (get_y_fartherst_intersection probe_line_object 1st_curve_object))
       			 (setq probe_intersection_2 (get_y_fartherst_intersection probe_line_object 2nd_curve_object))
        	)
      			(if (> min_proximity (setq probe_proximity (distance probe_intersection_1 probe_intersection_2)))
        		    (setq min_proximity probe_proximity
        		      	  x_proximity x
        		      	  proximity_point_1 probe_intersection_1
        		      	  proximity_point_2 probe_intersection_2
        			)
        		)
    	)
  	)
    (vla-put-startpoint probe_line_object (vlax-3d-point proximity_point_1))
    (vla-put-endpoint probe_line_object (vlax-3d-point proximity_point_2))
    (princ)
)

;**********************************************************************************************************************************

 

0 Likes
Message 22 of 25

hosneyalaa
Advisor
Advisor

@komondormrex 

 

Cool code
He works as required

 

 

3.jpg

0 Likes
Message 23 of 25

komondormrex
Mentor
Mentor

however if both plines have arc segments in their most proximity the code will miss it.

0 Likes
Message 24 of 25

komondormrex
Mentor
Mentor

and otherwise too

0 Likes
Message 25 of 25

Kent1Cooper
Consultant
Consultant

@JoseMandirigma wrote:

this isn't mine, I just found this somewhere I forgot and I works for me. 


[It does the minimum distance in any direction, not the vertical-only distance.]

Kent1Cooper_0-1681212273854.png

 

Kent Cooper, AIA
0 Likes