LISP DIVIDED

LISP DIVIDED

tongminh97
Contributor Contributor
1,440 Views
12 Replies
Message 1 of 13

LISP DIVIDED

tongminh97
Contributor
Contributor

I want to divide a dimension into three parts with lengths of L/8 and
3L/4, and round the dimensions to the nearest 50mm, as shown below. Thank you

tongminh97_0-1726633557662.png

 

0 Likes
Accepted solutions (2)
1,441 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant

An existing Dimension that you would select?   Or would you want to pick the definition points within the routine?

 

Do you want both the overall and the subdivided ones, or is your overall just for illustration?

 

Does rounding the Dimensions to the nearest 50mm mean you want the text content overridden, or the actual Dimensions drawn to rounded actual distances?  And since that will often not be possible for all three of the Dimensions, might you want a combination [e.g. the end Dimensions actual-distance rounded and the middle one text-override rounded]?

 

In any direction?  That is, Aligned Dimensions or Linear/Vertical/Horizontal only?

 

Etc., etc.

Kent Cooper, AIA
0 Likes
Message 3 of 13

tongminh97
Contributor
Contributor
Hi Kent1Cooper,
 Thank you for your response. I would like to select an existing dimension, which will then be divided into 3 smaller dimensions. The actual distance of the first and last dimensions will be L/8 and rounded to the nearest 50mm. The middle dimension will be the res1s.pngmaining distance after subtracting the rounded dimensions.
0 Likes
Message 4 of 13

komondormrex
Mentor
Mentor

check this one

 

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

(defun round_up (in_number)
	(if (>= (- in_number (fix in_number)) 0.5) (1+ (fix in_number)) (fix in_number))
)

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

(defun c:divide_dim (/ dim_0 dim_0_point_1 dim_0_point_2 dim_rotation dim_line_point dim_line_point_1 dim_line_point_2 
					   direction dim_1 dim_2 measurement_0 measurement_1 measurement_2 point_1 point_2 
					)
	(setq dim_0 (car (entsel "\nPick dim to divide: "))
		  dim_0_point_1 (cdr (assoc 13 (entget dim_0)))
		  dim_0_point_2 (cdr (assoc 14 (entget dim_0)))
		  dim_rotation (cdr (assoc 50 (entget dim_0)))
		  dim_line_point (cdr (assoc 10 (entget dim_0)))
	)
	(if (equal '(100 . "AcDbRotatedDimension") (last (entget dim_0)))
		(setq dim_line_point_1 (inters dim_line_point (polar dim_line_point dim_rotation 1) 
									   dim_0_point_1 (polar dim_0_point_1 (+ dim_rotation (* 0.5 pi)) 1) nil
							   )
		  	  dim_line_point_2 (inters dim_line_point (polar dim_line_point dim_rotation 1) 
			  						   dim_0_point_2 (polar dim_0_point_2 (+ dim_rotation (* 0.5 pi)) 1) nil
							   )
		)
		(setq dim_line_point_1 (inters dim_line_point (polar dim_line_point (angle dim_0_point_1 dim_0_point_2) 1) 
									   dim_0_point_1 (polar dim_0_point_1 (+ (angle dim_0_point_1 dim_0_point_2) (* 0.5 pi)) 1) nil
							   )
		  	  dim_line_point_2 (inters dim_line_point (polar dim_line_point (angle dim_0_point_1 dim_0_point_2) 1) 
			  						   dim_0_point_2 (polar dim_0_point_2 (+ (angle dim_0_point_1 dim_0_point_2) (* 0.5 pi)) 1) nil
							   )
		)
	)
	(setq direction (angle dim_line_point_1 dim_line_point_2)
		  dim_0 (vlax-ename->vla-object dim_0)
		  dim_1 (vla-copy dim_0)
		  dim_2 (vla-copy dim_0)
		  measurement_1 (vla-get-measurement dim_0)
		  measurement_0 (* 50.0 (round_up (/ measurement_1 8.0 50)))
		  measurement_2 measurement_0
		  measurement_1 (- measurement_1 measurement_0 measurement_2)
		  point_1 (polar dim_line_point_1 direction measurement_0)
		  point_2 (polar dim_line_point_1 direction (+ measurement_0 measurement_1))
	)
	(if (not (zerop measurement_0))
		(progn
			(entmod (subst (cons 13 dim_0_point_1)
						   (assoc 13 (entget (vlax-vla-object->ename dim_0)))
						   (entget (vlax-vla-object->ename dim_0))
					)
			)
			(entmod (subst (cons 14 (inters dim_0_point_1 dim_0_point_2 point_1 (polar point_1 (+ direction (* 0.5 pi)) 1) nil))
						   (assoc 14 (entget (vlax-vla-object->ename dim_0)))
						   (entget (vlax-vla-object->ename dim_0))
					)
			)
			(entmod (subst (cons 13 (inters dim_0_point_1 dim_0_point_2 point_1 (polar point_1 (+ direction (* 0.5 pi)) 1) nil))
						   (assoc 13 (entget (vlax-vla-object->ename dim_1)))
						   (entget (vlax-vla-object->ename dim_1))
					)
			)
			(entmod (subst (cons 14 (inters dim_0_point_1 dim_0_point_2 point_2 (polar point_2 (+ direction (* 0.5 pi)) 1) nil))
						   (assoc 14 (entget (vlax-vla-object->ename dim_1)))
						   (entget (vlax-vla-object->ename dim_1))
					)
			)
			(entmod (subst (cons 13 (inters dim_0_point_1 dim_0_point_2 point_2 (polar point_2 (+ direction (* 0.5 pi)) 1) nil))
						   (assoc 13 (entget (vlax-vla-object->ename dim_2)))
						   (entget (vlax-vla-object->ename dim_2))
					)
			)
			(entmod (subst (cons 14 dim_0_point_2)
						   (assoc 14 (entget (vlax-vla-object->ename dim_2)))
						   (entget (vlax-vla-object->ename dim_2))
					)
			)
		)
		(progn
			(princ "\nThat dimension cannot be divided") 
			(vla-erase dim_1)
			(vla-erase dim_2)
		)
	)
	(princ)
)

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

 

Message 5 of 13

Kent1Cooper
Consultant
Consultant

@tongminh97 wrote:
.... an existing dimension, which will then be divided into 3 smaller dimensions. The actual distance of the first and last dimensions will be L/8 and rounded to the nearest 50mm. ....

Does that mean you want the end Dimensions to be drawn at the actual L/8 distance [981.25 in your example] but display as 1000, or do you want them actually drawn at 1000?  In other words, is the dimension distance rounded, or is the text content rounded?

 

And will the original always be a horizontal/vertical/linear Dimension, or could it be aligned?

Kent Cooper, AIA
0 Likes
Message 6 of 13

tongminh97
Contributor
Contributor

i want them actually drawn at 1000,And i want to round a number up to the nearest multiple of 50, for example, round 951 up to 1000, not 950. Thanks.

0 Likes
Message 7 of 13

tongminh97
Contributor
Contributor

Can you fixed for me:
This ensures that the number is always rounded up to the next multiple of 50, even if the remainder is less than 0.5. For example:
If the input is 951, it will round up to 1000.
If the input is 1025, it will round up to 1050.

0 Likes
Message 8 of 13

marko_ribar
Advisor
Advisor

Consider this sub for rounding...

 

(defun round ( n / d r )
  (if (not (zerop (rem n 50)))
    (progn
      (setq d (fix (/ n 50.0)))
      (setq r (fix (+ 50 (* d 50))))
    )
    (setq r (fix n))
  )
  r
)

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 9 of 13

tongminh97
Contributor
Contributor

Thank you, but it doesn't work.

0 Likes
Message 10 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

Here's my take on it:

(defun C:Dim8thEnds50 ; = Dimension with 1/8th ends rounded to 50 [up]
  (/ *ed dsel ddata defpt1 defpt2 defptdist defptang dimlineang
    dimlinepos dimmeas raw8th dist8th defptdist8th)
  (defun *ed (dxf); = Entity Data value associated with DXF code number
    (cdr (assoc dxf ddata))
  ); defun - *ed
  (if
    (and
      (setq dsel (entsel "\nSelect Dimension to replace with L/8 ends: "))
      (member '(0 . "DIMENSION") (setq ddata (entget (car dsel))))
      (= (logand 6 (cdr (assoc 70 ddata))) 0); linear/rotated/aligned only
    ); and
    (progn ; then
      (setq
        defpt1 (*ed 13)
        defpt2 (*ed 14)
        defptdist (distance defpt1 defpt2)
        defptang (angle defpt1 defpt2)
        dimlineang (*ed 50)
        dimlinepos (*ed 10)
        dimmeas (*ed 42)
        raw8th (/ dimmeas 8)
        dist8th (* (+ (fix (/ raw8th 50)) (if (= (rem raw8th 50) 0) 0 1)) 50)
          ; nearest multiple of 50, rounded up only if not exact
        defptdist8th (* dist8th (/ defptdist dimmeas))
      ); setq
      (cond
        ((= (logand (*ed 70) 33) 33) (command "_dimaligned"))
        ((command"_.dimrotated" (angtos dimlineang (getvar 'aunits) 8))); otherwise
      ); cond
      (command
        "_non" defpt1 "_non" (polar defpt1 defptang defptdist8th) "_non" dimlinepos
        "_.dimcontinue" (polar defpt1 defptang (- defptdist defptdist8th)) "_non" defpt2 "" ""
      )
      (entdel (car dsel)); remove original
    ); progn
    (prompt "\nNo linear/rotated/aligned Dimension selected."); else
  ); if
  (prin1)
)

It accepts selection of only an appropriate type of Dimension [not angular, diameter, radius, ordinate].

It works even if the definition points do not align in direction with the dimension line, placing the new definition points spaced along the path between the old.

It turns, for example, the red ones here into the green ones:

Kent1Cooper_0-1726769537699.png

You can get the text in the middle left-over Dimensions to also show rounded to the nearest multiple of 50, if you want, by setting that in the Dimension Style [but it will round up or down].

It could use the usual enhancements like Undo begin/end wrapping, etc.

Kent Cooper, AIA
Message 11 of 13

tongminh97
Contributor
Contributor
Accepted solution

This is exactly what I was looking for. Thank so much.

0 Likes
Message 12 of 13

kenla12a
Community Visitor
Community Visitor

Please show me how to adjust the code for there cases, for example L/3 L/5. Thank.

0 Likes
Message 13 of 13

Sea-Haven
Mentor
Mentor

Why not have a go ask how many dims, then its a case of get dim pt1, get dim pt2, you can then work out all the dim points using a Polar function in a loop, using a simple dimaligned will give you the answer. Or look at code above where it uses dimcontinue. A good task to start learning lisp. 

0 Likes