help request: hatch areas between topographic lines

help request: hatch areas between topographic lines

Anonymous
Not applicable
1,263 Views
4 Replies
Message 1 of 5

help request: hatch areas between topographic lines

Anonymous
Not applicable

Hi all, this is my first post so feel free to ask for more info if it will help you answer my question better.

 

Given:

- a 2D dwg with splines marking topographic contours (1' increments for example)

 

Goal:

- automatically draw lines between two selected splines Spline1 and Spline2 where the distance between the splines is exactly some user-defined value "n" (2' for example)

   - for the sake of consistency, assume that the line is drawn from the "higher elevation" Spline1 to the "lower elevation" Spline2 (although in CAD both of their z coordinates are zero)

- hatch the area between two drawn lines, perhaps by selecting a point just to the left of the midpoint of the second line in each pair (if the lines are drawn left-to-right proceeding across the two splines being compared)

 

Current progress:

- I've tried psuedo-coding a few ideas then attempting them using commands rather than scripting them, but so far it seems like I'm missing something

 

I hope this makes sense!

0 Likes
Accepted solutions (1)
1,264 Views
4 Replies
Replies (4)
Message 2 of 5

Kent1Cooper
Consultant
Consultant

Welcome to these Forums!

 

The concept makes sense, but I think the execution will be more complicated than you expect.  In this example image, the solid red and yellow Splines are arbitrary contours.  The even-dashed ones of the same color are Offset from those, at a target distance [your "n"], to find where the other solid one is exactly "n" away.

 

Contours.png

 

The dashed red Spline is exactly "n" away from the solid red one all the way along, and likewise with the yellow ones.  The magenta Line is where the red Spline thinks the yellow Spline is exactly "n" away from it, and the green Line is where the yellow Spline thinks the red one is exactly "n" away from it.  Both the magenta and green Lines are exactly "n" long.  They obviously represent different opinions about where "being that far apart" actually happens.

 

So as an attempt at a split-the-difference compromise, I put in the solid blue one, which is an averaged path between the solid red and yellow ones [via a routine I have been developing], and I Offset that by half of "n" in both directions to get the dashed blue ones, which are exactly "n" away from each other all along.  The cyan Line runs from where the solid blue path thinks the solid red is half of "n" away from it and where it thinks the yellow one is half of "n" away from it.  Its endpoints are not at the same place relative to the center blue path [if you project from them perpendicular to it].  Also, that cyan Line is not "n" long [in this case it's about 7% longer].

 

I didn't want to clutter up the image too much, so this isn't in it, but I also tried Offsetting the red and yellow Splines by half of "n" toward each other.  That gives intersection points that are half of "n" from both Splines.  But Lines perpendicular from those intersections to each Spline, while the sum of their lengths is "n," are not collinear.  In this vicinity that intersection is even farther to the right than the cyan Line, there's about a 30-degree bend between the two Lines heading perpendicularly to the contours from there, and the straight-line distance between their outer ends [where they meet the contours] is about 4% shorter than "n."  That is also about the length of a bisector between the green and magenta Lines, trimmed to the contour Splines.

 

You would need to come up with some rule whereby the determination of where the contours are, in fact, "n" apart is to be made, and in what way [i.e. to what locations on the contours themselves] the Line marking that location should be drawn.  Maybe you give in to the ambiguity, always Offset the "higher" one only, and just go with where it thinks the next lower one is exactly that far away.  But you may have reason to use other criteria.  In any case, I don't think it would be easy [if even possible] to automate something like that.

 

[But it wouldn't surprise me if the Civil Engineering overlay program has some kind of capability along those lines.]

Kent Cooper, AIA
Message 3 of 5

scot-65
Advisor
Advisor
How about this suggestion?

Playing off the DIVIDE command, predetermine the lengths of each contour
and divide each of them with an equal number of segments. "n" is determined
from each numbered point of the divide.

It's not foolproof, but worth looking in to???

My dividers are not rusted yet.

Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 4 of 5

ВeekeeCZ
Consultant
Consultant
Accepted solution

@Anonymous wrote:

Hi all, this is my first post so feel free to ask for more info if it will help you answer my question better.

 

Given:

- a 2D dwg with splines marking topographic contours (1' increments for example)

 

Goal:

- automatically draw lines between two selected splines Spline1 and Spline2 where the distance between the splines is exactly some user-defined value "n" (2' for example)

   - for the sake of consistency, assume that the line is drawn from the "higher elevation" Spline1 to the "lower elevation" Spline2 (although in CAD both of their z coordinates are zero)

- hatch the area between two drawn lines, perhaps by selecting a point just to the left of the midpoint of the second line in each pair (if the lines are drawn left-to-right proceeding across the two splines being compared)

 

Current progress:

- I've tried psuedo-coding a few ideas then attempting them using commands rather than scripting them, but so far it seems like I'm missing something

 

I hope this makes sense!


 

Something for start... if you meant something else, then draw and post some sample DWG...

 

Spoiler
(vl-load-com)

(defun c:ContourHatchBetween ( / *error* nVAR oVAR adoc LM:intersections :SortPtListByDist
			         en1 ent en2 pt pt1 pt2 pts d enlast enx lst flag)
  
  
  ; ----
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
      (princ (strcat "\nError: " errmsg)))
    (if (and enx (entget enx)) (entdel enx))
    (mapcar 'setvar nVAR oVAR)
    (vla-endundomark adoc)
    (princ))
  
  
  ;; Intersections  -  Lee Mac
  (defun LM:intersections ( ob1 ob2 mod / lst rtn )
    (setq lst (vlax-invoke ob1 'intersectwith ob2 mod))
    (repeat (/ (length lst) 3)
      (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
	    lst (cdddr lst)))
    (reverse rtn))
  
  
  ;By BlackBox, http://www.cadtutor.net/forum/showthread.php?61433-Help-Sort-a-list-point-by-distance
  (defun :SortPtListByDist  (ptList en) ; list of two points
    (mapcar
      (function (lambda (x / ptList2)
		  (setq ptList2 (append (cdr x) ptList2))))
      (vl-sort
	(mapcar
	  (function (lambda (x / pt ptlist2)
		      (setq ptlist2
			     (append
			       (cons
				 (vlax-curve-getDistAtPoint
				   en
				   (vlax-curve-getClosestPointTo en (car x) T))
				 x)
			       ptlist2))))
	  ptList)
	(function (lambda (x y)
		    (< (car x) (car y)))))))
  
  
  ;-----------------------------------------------------------------------------------------------------------
  ;-----------------------------------------------------------------------------------------------------------
  
  (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
  (setq oVAR (mapcar 'getvar (setq nVAR '(CMDECHO OSMODE ORTHOMODE SNAPMODE BLIPMODE))))
  (mapcar 'setvar nVAR 			'(0	  0	 0	   0        0))
  
  
  (if (and (setq en1 (car (entsel "\nSelect the higher spline: ")))
	   (wcmatch (cdr (assoc 0 (entget en1))) "SPLINE,*POLYLINE")
	   (setq ent (entsel "\nSelect the lower spline: "))
	   (setq en2 (car ent)
		 pt (cadr ent))
	   (wcmatch (cdr (assoc 0 (entget en2))) "SPLINE,*POLYLINE")
	   (setq d (getdist "\nDistance: "))
	   (setq enlast (entlast))
	   )
    
    (progn
      (command "_.OFFSET" d en1 pt "")
      (if (not (equal enlast (entlast)))
	(setq enx (entlast)))
      
      (if (setq pts (LM:intersections (vlax-ename->vla-object enx) (vlax-ename->vla-object en2) acextendnone))
	(progn
	  
	  (foreach pt1 pts
	    (if (setq pt2 (vlax-curve-getClosestPointTo en1 pt1))
	      (progn
		(entmake (list (cons 0 "LINE")
			       (cons 10 pt2)
			       (cons 11 pt1)
			       (cons 8 "LINES")
			       (list 210 0.0 0.0 1.0)))
		(setq lst (cons (list pt2 pt1)
				lst)))))
	  
	  (if lst (foreach e (:SortPtListByDist lst en1)
		    (if flag		; flag for every second e...
		      (setq flag nil)
		      (progn
			(setq flag T)
			(command "_.-HATCH"
				 "_none" (trans (polar (polar (car e)
							      (angle (car e) (cadr e))
							      (* 0.5 d))
						       (+ (angle (cadr e) (car e))
							  (* 0.5 pi))
						       (* 0.1 d))
						0 1)
				 ""))))))
	
	(princ "\nFound NO LINES with specified distance!"))))

  (*error* "end")
)

 

Message 5 of 5

Anonymous
Not applicable

Sorry for the very late reply, this works almost perfectly! I added one line to the code to delete the offset spline *before* the hatch operation occurs so that the hatch boundaries follow the true topographic splines. Good trick with the conversion between global and local coordinates to select the hatch point.

 

For anyone who looks up this problem later, some bits of advice for when the user must take over:

- for topographic lines that are parallel/ near parallel to each other for their whole length

- for topo lines with wacky curvature near the ends of their extents

0 Likes