Calling a variable name symbol inside a loop

Calling a variable name symbol inside a loop

franciscovHWABV
Contributor Contributor
1,067 Views
13 Replies
Message 1 of 14

Calling a variable name symbol inside a loop

franciscovHWABV
Contributor
Contributor

Hi everyone.

 

I am creating a loop wich sets eleven points in each step (Step 1 from P1 to P11 Step 2: from P12 to P22 an so on) with this routine:

 

(setq count1 (+ count (+ 0 (* 10 (- count 1)))))
(setq count2 (+ count (+ 1 (* 10 (- count 1)))))
(setq count3 (+ count (+ 2 (* 10 (- count 1)))))
(setq count4 (+ count (+ 3 (* 10 (- count 1)))))
(setq count5 (+ count (+ 4 (* 10 (- count 1)))))
(setq count6 (+ count (+ 5 (* 10 (- count 1)))))
(setq count7 (+ count (+ 6 (* 10 (- count 1)))))
(setq count8 (+ count (+ 7 (* 10 (- count 1)))))
(setq count9 (+ count (+ 8 (* 10 (- count 1)))))
(setq count10 (+ count (+ 9 (* 10 (- count 1)))))
(setq count11 (+ count (+ 10 (* 10 (- count 1)))))

(set (read (strcat "p" (itoa count1))) (cadr (assoc inflinenumber pp)))
(set (read (strcat "p" (itoa count2))) (caddr (assoc inflinenumber pp)))
(set (read (strcat "p" (itoa count3))) (cadr (assoc suplinenumber pp)))
(set (read (strcat "p" (itoa count4))) (caddr (assoc suplinenumber pp)))

 

After this, program works perfectly if I call this points from his name like this:

 

(setq p1sup2 (list (car p1) (cadr p1)))
(setq p2sup2 (list (+ (car p2)5) (cadr p2)))
(setq p3sup2 (list (car p3) (cadr p3)))
(setq p4sup2 (list (+ (car p4)5) (cadr p4)))
(setq diam (- (cadr p3) (cadr p1)))
(setq p5sup2 (list (+ (car p1sup2) (* diam 50)) (cadr p1)))
(setq p6sup2 (list (+ (car p3sup2) (* diam 50)) (cadr p3)))

(command "_pline" p1sup2 "_a" "_d" 180 p3sup2 "_l" p4sup2 p2sup2 p1sup2 "_a" "_d" 180 p3sup2 "_l" p6sup2 p5sup2 p1sup2 "")

 

But what I want to achieve is the loop to call in each step its correspondent point. I have tried this way:

 

(setq p1sup2 (list (car (strcat "p" (itoa count1))) (cadr (strcat "p" (itoa count1)))))
(setq p2sup2 (list (+ (strcat "p" (itoa count2))5) (cadr (strcat "p" (itoa count2)))))

 

.... and so on.

But when making this it appears the message:

 

; error: bad argument type: consp "p1"

 

It would be really helpful if you can give a hint of how to solve it. 

Thank you very much!

 

 

0 Likes
1,068 Views
13 Replies
Replies (13)
Message 2 of 14

pbejse
Mentor
Mentor

Do us a favor and at least define the variables count, inflinenumber and pp, saves us time guessing what the are values for those when running a test

 

0 Likes
Message 3 of 14

franciscovHWABV
Contributor
Contributor

Oh sorry.

I thought you didn't need that. I think that is not the problem since the program runs perfectly when I dont try to call the variable with the strcat command.

 

pp is a list formed by the coordinates of the first and last points of a lot of plines.

Inflinenumber and suplinenumber are integers that increases with the counter.

Count is the own counter of the loop.

 

So what the paragraph below is doing is grabbing the coordinates of the list of plines and assigning them to variable names:

 

(set (read (strcat "p" (itoa count1))) (cadr (assoc inflinenumber pp))) ;P1 is the first point of the firts pline
(set (read (strcat "p" (itoa count2))) (caddr (assoc inflinenumber pp))) ;P2 is the last point of the firts pline
(set (read (strcat "p" (itoa count3))) (cadr (assoc suplinenumber pp))) ;P3 is the first point of the superior pline
(set (read (strcat "p" (itoa count4))) (caddr (assoc suplinenumber pp))) ;P4 is the last point of the superior pline

 

So in the next loop step it will do the same with the next two plines thanks to inflinenumber and suplinenumber counters, and assigne them their correspondent "p"number names.

 

 

0 Likes
Message 4 of 14

pbejse
Mentor
Mentor

@franciscovHWABV wrote:

Oh sorry.

I thought you didn't need that. I think that is not the problem since the program runs perfectly when I dont try to call the variable with the strcat command

Yes but probably from your end only, but for us  not privy to that information need those values to at least test the snippets code you posted. Our crystal ball is experiencing  technical difficulties now 

 


@franciscovHWABV wrote:

pp is a list formed by the coordinates of the first and last points of a lot of plines.


 Is pp variable similar to this?

(((-66.2312 348.055 0.0) (219.865 30.9935 0.0))
   ((-30.631 384.938 0.0) (193.327 139.053 0.0))
   ((75.5225 403.703 0.0) (260.644 100.877 0.0))
   ((185.487 487.028 0.0) (471.583 169.966 0.0))
   ((203.067 515.82 0.0) (427.025 269.935 0.0))
   ((309.22 534.584 0.0) (494.342 231.758 0.0))
	 )

What are the values of Inflinenumber, suplinenumber and count in relation to pp?

 

Honestly, Its not that hard to post the values here as per varaible name, also need to see the desired result.

If you really need a speedy resolution help us help you.

 

0 Likes
Message 5 of 14

franciscovHWABV
Contributor
Contributor

Ok. I didnt wanna digg deeper into those values because they are not really important.

Im gonna expose the same question with much simple program:

 

(defun c:testvariablenames ()

(setq idx 1)
(repeat 5

(set (read (strcat "p" (itoa idx))) (list (+ 0 (* idx 100)) (+ 0 (* idx 100))))
(set (read (strcat "p" (itoa (+ idx 1)))) (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100))))

(command "_pline" p1 p2 "")

(setq idx (1+ idx))
)

(princ)
)

 

This program works, but will make me 5 times a pline between p1 and p2.

What I want is to make in the first loop a pline between p1 and p2, and in the next step a pline between p2 and p3 and so on.

If I want the command pline to be a variabe call I would need something like:

 

(command "_pline" (strcat "p" (itoa idx)) (strcat "p" (itoa (+ idx 1))) "")

 

I've tried this among a few more solutions but it keeps appearing the "consp" error.

 

Of course, this solution look dumb for this programm, but extrapolating this to the first program I mentioned on this post will open up a lot of possibilities, like comparing the values of certain points to their similars on previous loop steps.

 

Sorry for the inconvenience, I should have started with this more simple explanation.

And thanks again!

0 Likes
Message 6 of 14

Kent1Cooper
Consultant
Consultant

@franciscovHWABV wrote:

....

This program works, but will make me 5 times a pline between p1 and p2.

What I want is to make in the first loop a pline between p1 and p2, and in the next step a pline between p2 and p3 and so on.

If I want the command pline to be a variabe call I would need something like:

 

(command "_pline" (strcat "p" (itoa idx)) (strcat "p" (itoa (+ idx 1))) "")

....


Try this:

 

(defun c:testvariablenames ()

  (setq idx 1)
  (repeat 5

    (set (read (strcat "p" (itoa idx))) (list (+ 0 (* idx 100)) (+ 0 (* idx 100))))
    (set (read (strcat "p" (itoa (+ idx 1)))) (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100))))

    (command "_pline" (eval (read (strcat "p" (itoa idx)))) (eval (read (strcat "p" (itoa (+ idx 1))))) "")

    (setq idx (1+ idx))
  ); repeat

  (princ)

); defun

Kent Cooper, AIA
0 Likes
Message 7 of 14

ronjonp
Advisor
Advisor

Here's another that stores the points in a list.

(defun c:foo (/ idx r)
  (setq idx 1)
  (repeat 5
    ;; Store your points in a list rather than setting each one to a var?
    (setq r (cons (list (+ 0 (* idx 100)) (+ 0 (* idx 100))) r))
    (setq r (cons (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100))) r))
    (command "_.pline" (cadr r) (car r) "")
    (setq idx (1+ idx))
  )					; repeat
  (princ)
)					; defun
Message 8 of 14

pbejse
Mentor
Mentor

@franciscovHWABV wrote:

What I want is to make in the first loop a pline between p1 and p2, and in the next step a pline between p2 and p3 and so on.

 

 


 

(defun c:testvariablenames (/ idx p n pp)
  (setq idx 1)
  (repeat 5

    (set (setq p (read (strcat "p" (itoa idx))))
	 (list (+ 0 (* idx 100)) (+ 0 (* idx 100)))
    )
    (set (setq n (read (strcat "p" (itoa (+ idx 1)))))
	 (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100)))
    )
    (command "_pline" (Eval p) (eval n) "")
    (setq idx (1+ idx))
    (setq pp (cons p pp))
  )
  (print (reverse pp))
  (princ)
)

 

Command: TESTVARIABLENAMES

(P1 P2 P3 P4 P5)

 

or plainly a list

(defun c:testvariablenames2 ( / idx pts pp)
  (setq idx 1)
  (repeat 5
    (setq pts
	   (list
	     (list (+ 0 (* idx 100)) (+ 0 (* idx 100)))
	     (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100)))
	   )
    )
    (command "_pline" (Car pts) (Cadr pts) "")
    (setq pp (cons (Car pts) pp))
    (setq idx (1+ idx))
  )
(print (reverse pp))
  (princ)
)

Command: TESTVARIABLENAMES2

((100 100) (200 200) (300 300) (400 400) (500 500))

 

Message 9 of 14

Kent1Cooper
Consultant
Consultant

If there's any benefit to having the end result as one Polyline of 5 segments, rather than separate single-segment Polylines for each step:

 

(defun c:test2 ()
  (setq idx 1)
  (repeat 5
    (set (read (strcat "p" (itoa idx))) (list (+ 0 (* idx 100)) (+ 0 (* idx 100))))
    (set (read (strcat "p" (itoa (+ idx 1)))) (list (+ 0 (* (+ idx 1) 100)) (+ 0 (* (+ idx 1) 100))))
    (setq idx (1+ idx))
  ); repeat
  (setq idx 1)
  (command "_.pline" p1)
  (repeat 5 (command (eval (read (strcat "p" (itoa (setq idx (1+ idx))))))))
  (command "")
  (princ)
); defun

Kent Cooper, AIA
0 Likes
Message 10 of 14

franciscovHWABV
Contributor
Contributor

Thank you all very much for the responses!

I really appreciate it.

I have tried with first code from Kent and it really works as I wanted.

 

Thank you very much!

0 Likes
Message 11 of 14

john.uhden
Mentor
Mentor

This is an ancient but often told story.

Rather than making a dozen or more separate variables for separate points, do what AutoLisp is made for... lists.

For example, if you

(setq plist (list (x1 y1)(x2 y2)...(xn yn)))

then you can

(command ".pline")(mapcar 'command plist)(command "")

John F. Uhden

0 Likes
Message 12 of 14

hencoop
Advisor
Advisor

Sorry!  I just saw that @Kent1Cooper  already suggested this.  My bad!

Try (setq p1sup2 (list (car (EVAL (READ (strcat "p" (itoa count1))))) (cadr (EVAL (READ (strcat "p" (itoa count1)))))))

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 13 of 14

ronjonp
Advisor
Advisor

@franciscovHWABV 

Here's a simpler version projecting polylines from 0,0 @ 45 degrees. It stores the points in a list 'R' which is more common practice than setting a bunch of variables. LISt Processing. 🙂

(defun c:foo (/ p r)
  (setq r (cons (setq p '(0 0 0)) r))
  (repeat 5
    ;; Store your points in a list rather than setting each one to a var?
    (setq r (cons (setq p (mapcar '+ p '(100 100))) r))
    (command "_.pline" (cadr r) (car r) "")
  )					; repeat
  (princ)
)					; defun

 

0 Likes
Message 14 of 14

Sea-Haven
Mentor
Mentor

Just a sideways question is this for like a Insulation type pline lines and curves made from a start to end points. 

 

SeaHaven_0-1629867168408.png

 

0 Likes