eg0n Posted October 27, 2010 Share Posted October 27, 2010 I want to fill an array with the elements of a list. The problem is that when I want to define the dimensions of the array, the upper bound depends on the length of my list so I use the following code: (setq array (vlax-make-safearray vlax-vbDouble '(0 . (- (length newlist) 1)))) and I get a "bad argument type: fixnump: (- (LENGTH NEWLIST) 1)" error. Any ideas would be really helpful. :? Quote Link to comment Share on other sites More sharing options...
Tharwat Posted October 27, 2010 Share Posted October 27, 2010 Sine that you have started and wrote some codes of your desired routine , it's better to post all of them to check them out or may add ours for you to use . Thanks. Tharwat Quote Link to comment Share on other sites More sharing options...
eg0n Posted October 27, 2010 Author Share Posted October 27, 2010 What I'm trying to do is to simplify a polyline by removing not important points. As "not important" I define every point which is inside an angle. At the following image point 3 is not important (inside angle) but point 5 is important. ;(prompt "\nType \"mine\" to run........") (defun c:mine ( / theobj thelist n xval1 yval1 newlist maxdeg amax xval2 yval2 xval3 yval3 d1 d2 d3 z a l anarray mspace myobj) ;load the visual lisp extensions (vl-load-com) ;get the entity and entity name (setq theobj (car (entsel "\nSelect a Polyline: "))) ;convert to vl object (setq theobj (vlax-ename->vla-object theobj)) ;retrieve the coordinates (setq thelist (vlax-get-property theobj 'coordinates)) ;convert to a list (setq thelist (vlax-safearray->list (variant-value thelist))) ;zero the counter (setq n 0) ;make a list of the simplified coordinates (setq xval1 (car thelist)) (setq yval1 (cadr thelist)) (setq newlist '(xval1 yval1)) ;ask for maximum angle (setq maxdeg (getint "\nEnter Maximum Angle (0 - 90 deg) : ")) ;convert degrees to radians using "dtr" routine (setq amax (dtr maxdeg)) ;start the loop and repeat it for (n-2) times (repeat (- (/ (length thelist) 2) 2) ;get the x coordinates (setq xval1 (nth n thelist)) (setq xval2 (nth (+ 2 n) thelist)) (setq xval3 (nth (+ 4 n) thelist)) ;increase the counter (setq n (1+ n)) ;get the y coordinates (setq yval1 (nth n thelist)) (setq yval2 (nth (+ 2 n) thelist)) (setq yval3 (nth (+ 4 n) thelist)) ;calculate distances using "distan" routine (setq d1 (distan xval1 xval2 yval1 yval2)) (setq d2 (distan xval1 xval3 yval1 yval3)) (setq d3 (distan xval2 xval3 yval2 yval3)) ;calculate angle (setq z (/ (- (+ (expt d1 2) (expt d2 2)) (expt d3 2)) (* 2 (* d1 d2)))) (setq a (arccos z)) ;compare the angles (if (> a (/ amax 2)) ;if true do the following (progn ;add the coordinates to the new list (setq newlist (append '(newlist xval3 yval3))) );progn );if ;increase the counter (setq n (1+ n)) );repeat ;add the last point to the simplified list (setq xval1 (nth (- (length thelist) 1) thelist)) (setq yval1 (last thelist)) (setq newlist (append '(newlist xval1 yval1))) ;make an array with the points of the simplified list (setq anarray (vlax-make-safearray vlax-vbDouble '(0 . (- (length newlist) 1)))) ;fill it with x and y values (vlax-safearray-fill anarray newlist) ;reference to model space (setq mspace (vla-get-modelSpace (vla-get-activeDocument (vlax-get-acad-object)))) ;draw the simplified polyline (setq myobj (vla-addLightweightPolyline mspace anarray)) (princ) );defun ;------------------------------------------ ;This function converts Degrees to Radians. (defun dtr (x) ;define degrees to radians function (* pi (/ x 180.0)) ;divide the angle by 180 then ;multiply the result by the constant PI ) ;end of function ;clean loading (princ) ;This function calculates distance (defun distan (x1 x2 y1 y2) ;calculate dx dy (setq pt1 (list x1 y1)) (setq pt2 (list x2 y2)) ;find the distance (distance pt1 pt2) ) ;end of function ;clean loading (princ) ;This function inverse cosine (ArcCos) ;Args: -1 <= x <= 1 (defun arccos (x) (atan (/ (sqrt (- 1 (expt x 2))) x)) ) ;clean loading (princ) ;------------------------------------------- ;End of mine.lsp ;--------------------------- The problem is when I try to draw the simplified polyline by using the values that I have stored at a list, because it cannot accept the following: (setq anarray (vlax-make-safearray vlax-vbDouble '(0 . (- (length newlist) 1)))) thank you for your help Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 27, 2010 Share Posted October 27, 2010 The problem is the use of an apostrophe - meaning that the expressions following the apostrpohe are not evaluated. Read this: http://www.cadtutor.net/forum/showpost.php?p=258390&postcount=20 I haven't looked through your code, but to solve the issue at hand: (setq anarray (vlax-make-safearray vlax-vbDouble (cons 0 (- (length newlist) 1)))) Quote Link to comment Share on other sites More sharing options...
eg0n Posted October 27, 2010 Author Share Posted October 27, 2010 I made the change Lee suggested and it's ok (thank you Lee!!!) but now at the next line of code: (vlax-safearray-fill anarray newlist) i get a "lisp value has no coercion to VARIANT with this type: NEWLIST" error. what does it mean? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 27, 2010 Share Posted October 27, 2010 Look at how you are constructing 'newlist' - are you sure you read my link... Quote Link to comment Share on other sites More sharing options...
eg0n Posted October 27, 2010 Author Share Posted October 27, 2010 proud for making my first lisp. Thank you Lee for your help and for your link (I read it the second time and corrected many errors...). Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.