Hi,
I have a lot of polylines like the one in the attachment and I use a lisp to calculate sum of multiple polylines. My problem is that the area is misscalculated, and for this given problem I have a bad area sum.
I tried with both Autocad 2014 and Autocad Map 2014 to get a right calc, but i can't figure it out. On any other PC, the area of this specificaly type of polyline is different (as it needs to be).
For me, the area of the polyline in the attached dwg is 2724.1378. If I try to find/calculate the area of this polyline on other PC it will show me 2461.4879, wich is with exactly 262.6499 less (the area I need to extrude withing a polyline).
Note that the lisp is good, is not giving any problems.
Please help me with a solution for this. I need it to be right, I can't go and make change 1 by 1 for each polyline because I have thousands of them. I need a bunch of different calculations of the areas and I can't get it right.
Solved! Go to Solution.
I doubt anyone can solve your problem with the drawing alone -- if "the area is miscalculated," it would be necessary to see how the calculation is made. It would seem that "the lisp ... is not giving any problems" contradicts the fact of the miscalculation -- isn't that a problem? Post the code.
Well, there was 2-3 times when I got the right area. I don't know how or why, just started my CAD and tried to calculate and got it right.
Here is the lisp:
(defun c:SAL (/ m ss clist temp) ;;command SAL - Sum Area by Layer ;;posted Vladimir Azarko (VVA) ;;http://www.cadtutor.net/forum/showthread.php?t=28604 (defun sort (lst predicate) (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst predicate)) ) ;_ end of defun (defun combine (inlist is-greater is-equal / sorted current result) (setq sorted (sort inlist is-greater)) (setq current (list (car sorted))) (foreach item (cdr sorted) (if (apply is-equal (list item (car current))) (setq current (cons item current)) (progn (setq result (cons current result)) (setq current (list item)) ) ;_ end of progn ) ;_ end of if ) ;_ end of foreach (cons current result) ) ;_ end of defun (defun marea (lst / sum_len) (setq sum_len 0) (foreach item (mapcar 'car lst) (setq sum_len (+ sum_len (if (vlax-property-available-p item 'Area) (vla-get-area item) ) ;_ if ) ;_ + ) ;_ end of setq ) ;_ end of foreach (if (not (zerop sum_len)) (princ (strcat "\n\t" (cdar lst) " = " (rtos (* sum_len m) 2 4)) ) ;_ end of princ ) ;_ end of if ) ;_ end of defun (vl-load-com) (if (null *M*) (setq *M* 1) ) ;_ end of if (initget 6) (and (princ "\nEnter scale factor <") (princ *M*) (princ ">: ") (or (setq m (getreal)) (setq m *M*)) (setq *M* m) (setq ss (ssget '((0 . "*POLYLINE,SPLINE,CIRCLE,ELLIPSE")))) (setq ss (mapcar (function vlax-ename->vla-object) (vl-remove-if (function listp) (mapcar (function cadr) (ssnamex ss) ) ;_ mapcar ) ;_ vl-remove-if ) ;_ end of mapcar ) ;_ end of setq (mapcar '(lambda (x) (setq temp (cons (cons x (vla-get-layer x)) temp)) ) ;_ end of lambda ss ) ;_ end of mapcar (setq clist (combine temp '(lambda (a b) (> (cdr a) (cdr b)) ) ;_ end of lambda '(lambda (a b) (eq (cdr a) (cdr b)) ) ;_ end of lambda ) ;_ end of combine ) ;_ end of setq (princ "\n\n Total area by layer :" ) ;_ end of princ (mapcar 'marea clist) ) ;_ end of and (princ) ) ;_ defun
I'm sure the problem is not in the routine, but in your polyline. I fill your polyline with hatch and renewed boundary with HATCHGENERATEBOUNDARY command . The are in the detailed listing shows slight differences in points... it might result in the wrong area computed curve. Even AutoCAD it computed differently. I recommend such curves draw with tiny gaps... or recreate from hatch.
LWPOLYLINE Layer: "0"
Space: Model space
Handle = 2dd
Closed
Constant width 0.00000000
area 2461.48782400
perimeter 329.46769942
at point X=55.82956778 Y=28.53957826 Z=0.00000000
at point X=56.90956778 Y=28.52957826 Z=0.00000000
at point X=67.44956778 Y=17.50957826 Z=0.00000000
at point X=67.47791378 Y=17.11058390 Z=0.00000000
at point X=58.75956778 Y=4.67957827 Z=0.00000000
at point X=57.68956778 Y=4.47957826 Z=0.00000000
at point X=50.29383742 Y=-22.56504816 Z=0.00000000
at point X=70.93360425 Y=23.60267777 Z=0.00000000
at point X=18.11116885 Y=43.53448852 Z=0.00000000
at point X=0.00000000 Y=0.00000000 Z=0.00000000
at point X=50.29383742 Y=-22.56504816 Z=0.00000000
at point X=57.68956778 Y=4.47957827 Z=0.00000000
at point X=47.06791378 Y=15.66058390 Z=0.00000000
at point X=47.03956778 Y=16.05957827 Z=0.00000000
at point X=55.82956778 Y=28.53957826 Z=0.00000000
LWPOLYLINE Layer: "TEREN_REZERVA"
Space: Model space
Handle = 1e3
Closed
Constant width 0.00000000
area 2724.13776576
perimeter 329.46769942
at point X=55.82956778 Y=28.53957826 Z=0.00000000
at point X=56.90956778 Y=28.52957826 Z=0.00000000
at point X=67.44956778 Y=17.50957826 Z=0.00000000
at point X=67.47791378 Y=17.11058390 Z=0.00000000
at point X=58.75956778 Y=4.67957827 Z=0.00000000
at point X=57.68956778 Y=4.47957826 Z=0.00000000
at point X=50.29383742 Y=-22.56504816 Z=0.00000000
at point X=70.93360425 Y=23.60267777 Z=0.00000000
at point X=18.11116885 Y=43.53448852 Z=0.00000000
at point X=0.00000000 Y=0.00000000 Z=0.00000000
at point X=50.29383742 Y=-22.56504816 Z=0.00000000
at point X=57.68956778 Y=4.47957826 Z=0.00000000
at point X=47.06791378 Y=15.66058390 Z=0.00000000
at point X=47.03956778 Y=16.05957827 Z=0.00000000
I also tried other things ... AutoCAD it counts with different results. The only advice is to do it with a small gap - as I do (like 0,5 mm). Restoring the border does not (always) help.
Restoring the border helps, but I have thousands of such polylines. I can't understand why this problem occure since it happend 2-3 times to get a right answer. If I use another AutoCAD on another PC it works.
My work is verified with ArcGIS topology tool if I have overlaping polylines and the areas of diffrent layers, and there I get the right answer too. Still, can't figure it out why this problem still persist.
Interesting ... Despite the fact that it was very difficult to replicate the problem ... I have tried four ways to calculate the area ... as shown.
Properties, List command - both wrong
Routine using (Vlax-property-available-p Order 'Area), therefore the same approach as your routine, also wrong.
On statusbar - this routine uses (Vlax-curve-getArea (ssname ss i))... gives the correct result.
I don't know if (Vlax-property-available-p Order 'Area) is for some reason better, but I would use (vlax-curve-getArea) at least as verification.
Changed your routine.
(defun c:SAL (/ m ss clist temp) ;;command SAL - Sum Area by Layer ;;posted Vladimir Azarko (VVA) ;;http://www.cadtutor.net/forum/showthread.php?t=28604 (defun sort (lst predicate) (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst predicate)) ) ;_ end of defun (defun combine (inlist is-greater is-equal / sorted current result) (setq sorted (sort inlist is-greater)) (setq current (list (car sorted))) (foreach item (cdr sorted) (if (apply is-equal (list item (car current))) (setq current (cons item current)) (progn (setq result (cons current result)) (setq current (list item)) ) ;_ end of progn ) ;_ end of if ) ;_ end of foreach (cons current result) ) ;_ end of defun (defun marea (lst / sum_len) (setq sum_len 0) (foreach item (mapcar 'car lst) (setq sum_len (+ sum_len (if (vlax-property-available-p item 'Area) ;(vla-get-area item) (vlax-curve-getArea item) ) ;_ if ) ;_ + ) ;_ end of setq ) ;_ end of foreach (if (not (zerop sum_len)) (princ (strcat "\n\t" (cdar lst) " = " (rtos (* sum_len m) 2 4)) ) ;_ end of princ ) ;_ end of if ) ;_ end of defun (vl-load-com) (if (null *M*) (setq *M* 1) ) ;_ end of if (initget 6) (and (princ "\nEnter scale factor <") (princ *M*) (princ ">: ") (or (setq m (getreal)) (setq m *M*)) (setq *M* m) (setq ss (ssget '((0 . "*POLYLINE,SPLINE,CIRCLE,ELLIPSE")))) (setq ss (mapcar (function vlax-ename->vla-object) (vl-remove-if (function listp) (mapcar (function cadr) (ssnamex ss) ) ;_ mapcar ) ;_ vl-remove-if ) ;_ end of mapcar ) ;_ end of setq (mapcar '(lambda (x) (setq temp (cons (cons x (vla-get-layer x)) temp)) ) ;_ end of lambda ss ) ;_ end of mapcar (setq clist (combine temp '(lambda (a b) (> (cdr a) (cdr b)) ) ;_ end of lambda '(lambda (a b) (eq (cdr a) (cdr b)) ) ;_ end of lambda ) ;_ end of combine ) ;_ end of setq (princ "\n\n Total area by layer :" ) ;_ end of princ (mapcar 'marea clist) ) ;_ end of and (princ) ) ;_ defun
There was an area calculation error introduced in AutoCAD 2011 that wasn't fixed until the 2014 version. The situation that causes the problem is when a segment of the polyline follows a return path across a previous portion of the polyline. The AREA command can return an invalid number, while the underlying APIs returns the correct value.
I don't know if this is part of the problem but it appears that the polyline in your drawing was created by drawing an open shape and then using PEDIT C to close the shape rather than explicitly specify that the last vertex is at the same location as the first. You can tell this by using PEDIT E (edit vertex) and then repeatedly hitting Enter. The X on the selected vertex will walk around the shape and end at the vertex prior to the end (shy of closing). For polylines that were created with an explicit vertex to close the shape the X will go all around and end at the beginning. Perhaps this affects the lisp function as your polyline has one less vertex as it should in its properties.
Managed to redraw the borders for all my polylines and now I get a correct result. It took me 2 days, but it worth it.
Thank you for your solutions, you guys gave me new perspectives about this issue and learned some new things with this occasion.
Ta upravená rutina by stála za vyzkoušení, zdá se že dává správné řešení i bez nutnosti překreslení.
That changed routine worth to try. It looks that gives correct result without need to redraw.
Agreed. If the modified routine didn't work for some reason, it would have been good to say why instead of seemingly disregarding your efforts.
Can't find what you're looking for? Ask the community or share your knowledge.