Very weird behaviour by loop

Very weird behaviour by loop

Anonymous
Not applicable
1,564 Views
10 Replies
Message 1 of 11

Very weird behaviour by loop

Anonymous
Not applicable

Hello to all,

 

sorry I couldn't be more specific in the subject - that's why I'll go straight to the point here. I have the following piece of code:

 

		(repeat N_pts
			(setq current_curve (nth j offset_list))
			(setq closestpt_i (vlax-curve-getclosestpointto current_curve pt_i))			
			(command "circle" closestpt_i "0.25")
			(princ closestpt_i)
			(setq j (+ j 1))
		)

What is weird about this piece of code is that the command "circle" draws the points in the correct places, but the next command "princ" always

displays the same point. The circle command I actually used for testing and noticed this weird behaviour.

 

Background: this is a part of a bigger loot, which gives different values of pt_i to this loop. offset_list is a list of curve (polyline) entity names. Of course

there is also a (setq j 0) before the loop, but I omitted this.

 

Any help is highly appreciated, since I can't explain this problem.

0 Likes
Accepted solutions (1)
1,565 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant
Nothing obvious. Post the entire code to see... and some dwg sample file to test.
0 Likes
Message 3 of 11

Anonymous
Not applicable

The code is a bit longish (100 lines), I'm not sure if it's a good idea. The point is that whenever I use this specific vlax command, for some reason the assigned point the command returns is treated differently, depending on if it's used in "command" or treated as a variable. I'm basically looking at this for the last 5 hours, and find it completely uncomprehensible. P.S. There are no global variables causing problems, I also checked that.

0 Likes
Message 4 of 11

marko_ribar
Advisor
Advisor

I don't see how variable pt_i is changing inside your loop... It may be different outside of loop in outer loop, but inside loop where (command "_.CIRCLE" ...) is used it's the same point... The difference of creation of circles by command is product of only different current_curve variable which differs in each iteration of (repeat) loop... However like you stated circles are different meaning that variable closestpt_i is changing each time... This means that next (princ closestpt_i) should give different prompts each time, but maybe CAD is unable to print it correctly on text screen of cycle and gives the result of only single output of inner loop as something is preventing execution of (princ) statements for every different value of variable... You may try to insert blank (princ) statement before (princ closestpt_i) and after (command) and also ensure after (command) that variable CMDACTIVE is equal to 0, eliminating the fact that CIRCLE command is finished before (princ) is issued... My suggestion is something like this :

...

(command "_.CIRCLE" "_non" (trans closestpt_i 0 1) 0.25)

(while (< 0 (getvar 'cmdactive))

  (command "")

)

(princ)

(princ closestpt_i)

...

;;; "_non" syntax in (command) function is for ensuring routine is omitting current OSNAP setting and (trans ... 0 1) for ensuring command call is performed using translated point variable into active coordinate system in which all (command) calls operate instead of WCS point variable obtained from using (vlax-curve-*) functions, and lastly 0.25 is real number specification which is likely more adequate than "0.25" string input as during CIRCLE command you input radius by typing number not enclosed in " ... " quotations...

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 5 of 11

Anonymous
Not applicable

I have just inspected the coordinates printed out by princ (always the same!), and compared them with the coordinates of the circles which the program draws correctly. It turns out that this seems to be a rounding error! For example, in the princ output, after 4 decimal places, an exponential notation is added. Indeed, the coordinates in the dwg are huge. Still, the program should be immune to this! 

 

Probably I should do something with the "units" variable, I'll try it out now...

0 Likes
Message 6 of 11

marko_ribar
Advisor
Advisor

Then you may simple change this :

(princ closestpt_i)

To this :

(princ (strcat "(" (rtos (car closestpt_i) 2 50) " " (rtos (cadr closestpt_i) 2 50) " " (rtos (caddr closestpt_i) 2 50) ")"))

 

HTH

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 7 of 11

Anonymous
Not applicable

Indeed, this works nicely. However, the problem is that the points stored as variables still have the "low" precision. Obviously, I could write a function which converts the coordinates to strings with arbitraty precision, and then converts them back to floats. But, is there a shorter way to do this?

 

Edit: in addition to this, it would be nice to match the actual precision with the ACAD units precision setting.

0 Likes
Message 8 of 11

Anonymous
Not applicable

Just to make it 100 % clear, here is how princ displays a specific point:

 

(7.5169e+006 4.69006e+006 0.0)

 

However, the ACAD coordinates (i.e. the center of the circle in the properties bar) are:

 

7516904.1214

4690061.7603

0

 

 

0 Likes
Message 9 of 11

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

Indeed, this works nicely. However, the problem is that the points stored as variables still have the "low" precision. Obviously, I could write a function which converts the coordinates to strings with arbitraty precision, and then converts them back to floats. But, is there a shorter way to do this?

 

Edit: in addition to this, it would be nice to match the actual precision with the ACAD units precision setting.


Are you chasing ghosts. This is just visual thing... the precise of point coords are as hight as possible - just you can see that.

 

Try this line... and pick same point for pt1 and pt2. Same principle...

 

(progn (setq pt1 (getpoint "pt1: ")) (princ pt1) (equal pt1 (getpoint "pt2: ")))

 

Message 10 of 11

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

... (rtos (car closestpt_i) 2 50) ...


As an aside, it won't disclose to you anywhere near that many decimal places.  I've never known (rtos) to be able to return more than 16 significant figures, for example with pi:

 

Command: (rtos pi 2 20)
"3.141592653589793"

 

[only 15 decimal places despite my asking for 20].  Similar results with the square root of 2:

 

Command: (rtos (sqrt 2) 2 20)
"1.414213562373095"

 

and with some things with more figures before the decimal point:

 

Command: (rtos (sqrt 22222) 2 20)
"149.0704531421300"

 

Command: (rtos (getvar 'cdate) 2 20)
"20160624.16473896"

 

All 16 sig-figs.

Kent Cooper, AIA
0 Likes
Message 11 of 11

Anonymous
Not applicable
Accepted solution

Issue finally resolved. The answer is terrifyingly trivial.

 

One of the later functions I used on the points mentioned above had an error in the definition. I.e., its arguments were *separated by commas* (also working in Python) instead by blank spaces. Now everything is working perfectly.

 

Anyway, thanks to all for your efforts.

 

P.S. What is bizzare (and one of the reasons why I didn't notice this mistake earlier) is that the function was working in a different module, one where I pick the points by hand and then let the function act on them.

0 Likes