I have an old lisp routine that has an error I cannot figure out. I must doing something wrong. Maybe someone here can give me some clues.
Snipit from the lisp ...
(setq L:P1 (list 5000.0 5200.0 0.0))
(setq L:QUADRANT (list 5015.2 5234.9 0.0))
((= (type L:QUADRANT) 'list)
(cond ((and (>= (angle L:P1 L:QUADRANT) 0) (< (angle L:P1 L:QUADRANT) 1.5708)) (setq L:QUADRANT 1))
((and (>= (angle L:P1 L:QUADRANT) 1.5708) (< (angle L:P1 L:QUADRANT) 3.14159)) (setq L:QUADRANT 4))
((and (>= (angle L:P1 L:QUADRANT) 3.14159) (< (angle L:P1 L:QUADRANT) 4.71239)) (setq L:QUADRANT 3))
((and (>= (angle L:P1 L:QUADRANT) 4.71239) (< (angle L:P1 L:QUADRANT) 6.27613)) (setq L:QUADRANT 2))
)
)
(setq L:P1 (list 5000.0 5200.0 0.0))
returns: (5000.0 5200.0 0.0)
(setq L:QUADRANT (list 5015.2 5234.9 0.0))
returns: (5015.2 5234.9 0.0)
(and (>= (angle L:P1 L:QUADRANT) 0) (< (angle L:P1 L:QUADRANT) 1.5708))
returns: T
((and (>= (angle L:P1 L:QUADRANT) 0) (< (angle L:P1 L:QUADRANT) 1.5708)) (setq L:QUADRANT 1))
returns: ; error: bad argument type: 2D/3D point: 1
So, what is the bad point?
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Since you only posted partial code, it's hard to say for sure, but I assume the error is not coming from your last-quoted line, but from later on, where something is looking to be given a point as the L:QUADRANT variable [again -- it was originally a point] , but that has been set to a number [1 in this case] instead.
I suggest you distinguish the point variable that you start with from the quadrant variable for the direction from the base point, using different variable names. Then after you have determined that the direction is in quadrant 1, you still have the point that the direction is toward available, as a point.
(setq L:P2 (list 5015.2 5234.9 0.0))
(if (= (type L:P2) 'list)
(cond ((and (>= (angle L:P1 L:P2) 0) (< (angle L:P1 L:P2) 1.5708)) (setq L:QUADRANT 1))
Then use L:P2 as the point later when that is expected.
EDIT: The code portions as posted need something like the if above added, in order to do anything, or line 4 and following need to be inside another (cond) function, or lines 4 & 10 need to be removed, or something.
Kent,
I thought that also. I did try changing the variable but it still failed, so I changed it back. The error IS actually right there in that cond function. I provided all the code needed to see the error. If you paste each line I provided into Autocad, you too will see the error (or at least should see it).
I once had a bad lisp because of hidden characters not seen in the editors. That was a tough one to track down. But that does not seem to be the case here.
Am I missing parenthesis? Are there too many? I just don't see it.
See my edit to Message 2. When I put that in, and keep your variable names, there is no error -- L:QUADRANT ends up set to 1. Without it, you have a function that returns T being fed in as though it's a function name.
Kent,
Thank you so much.
Turns out you were correct with changing the name of the variable. I had been only changing it in that one line of the cond function for tests. When I changed it in all the lines and ran it in Autocad as a whole (the complete cond function), it worked. I then had to add the statement to set the L:QUADRANT variable outside the cond function (as the rest of the lisp needs the integer).
Oh, by the way, that line 4 is from a nested cond function.
@dvertz wrote:
((and (>= (angle L:P1 L:QUADRANT) 0) (< (angle L:P1 L:QUADRANT) 1.5708)) (setq L:QUADRANT 1))
returns: ; error: bad argument type: 2D/3D point: 1
So, what is the bad point?
When you ran that line on its own, the interpreter will evaluate second item before anything else, by the time the statement wrapped with and evaluates, the value of L:P1 L:QUADRANT will be 1 and not a point list. hence the message bad point
but using the correct function like cond, the test will evaluate before the result, only then setting the value of 1 to L:P1 L:QUADRANT will be be invoked..
HTH
Just a comment if you want more accuracy can use (/ pi 2.) for 1.5708 = 1.5707963267949 same with other values (* 1.5 pi), pi=3.14159265358979 etc.
On the subject of tweaking the code:
I would set the directional angle into a variable, rather than calculate it separately within each (cond)itional test.
And in the (cond) function determining the quadrant direction, once you have established in the first condition that the direction is not less than 90°, it is not necessary in the next condition to check whether it's both more than 90° and less than 180°, because you already know it's more than 90°. And once it has not qualified for the first three quadrants, it's not necessary to test for the fourth quadrant, because it can be only that.
And if you put that (cond) function inside the setting of the quadrant variable, you can do the whole thing with code for only one (setq) function:
(setq
dir (angle L:P1 L:P2); [or whatever variable name you're using]
L:QUADRANT
(cond
((and (>= dir 0) (< dir (/ pi 2))) 1)
((< dir pi) 4)
((< dir (* pi 1.5)) 3)
(2); none-of-the-above condition
); cond & L:QUADRANT
); setq
Can't find what you're looking for? Ask the community or share your knowledge.