TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: ronjonp on May 26, 2011, 11:58:18 AM

Title: Average of Numbers in a Area (for you mathies :) )
Post by: ronjonp on May 26, 2011, 11:58:18 AM
Let me preface this with math has never been my strong point and I'm most likely way over my head with this.  :-)

Ok..... so I've been trying to figure out how to create a smooth mesh of weighted averaged numbers between the values within an area as shown below (although the area could be any shape) without any success. Could someone help steer me in the right direction of steps to achieve this? I thought I could grab a point, sort the list closest and use the next closest weighted average (which works great for linear stuff) ... but sometimes I need to use the average of more than just 2 points to get the correct averaged number and for the life of me I cannot figure this out  :oops:.

Thanks,

Ron
Title: Re: Average of Numbers in a Area (for you mathies :) )
Post by: alanjt on May 26, 2011, 01:44:47 PM
I'm sure I'm not fully understanding it myself but, would this help?

Code: [Select]
(defun AT:MidOfPoints (lst / l)
  ;; Middle point of list of points
  ;; lst - list of points
  ;; Alan J. Thompson, 03.23.11
  (if (>= (setq l (length lst)) 2)
    (mapcar (function (lambda (i) (/ i l))) (apply (function mapcar) (cons (function +) lst)))
  )
)

return:
Code: [Select]
Command: (at:midofpoints '( (1. 1. 1.) (2. 2. 2.) (3. 3. 3.)(5. 5. 5.)))
(2.75 2.75 2.75)
Title: Re: Average of Numbers in a Area (for you mathies :) )
Post by: Keith™ on May 26, 2011, 01:49:18 PM
Well, wouldn't an average merely be a+b+c / 3 ?

To that end:
Point1.X + Point2.X + Point3.X = AvgPoint.X
Point1.Y + Point2.Y + Point3.Y = AvgPoint.Y

I guess Alan and I have the same question about exactly what you are looking for.
Title: Re: Average of Numbers in a Area (for you mathies :) )
Post by: alanjt on May 26, 2011, 01:52:38 PM
I guess Alan and I have the same question about exactly what you are looking for.

Good to know I'm not the only one.
Title: Re: Average of Numbers in a Area (for you mathies :) )
Post by: gile on May 26, 2011, 02:47:09 PM
Hi

I'm not sure to understand the question, but the following expression returns the average of ponderate points.
Assuming points is the point list and weights is the correspoinding 'weights' list.

Code: [Select]
((lambda (sum)
   (mapcar
     '(lambda (x) (/ x sum))
     (apply 'mapcar
    (cons '+
  (mapcar
    '(lambda (h p)
       (mapcar '(lambda (x) (* h x)) p)
     )
    weights
    points
  )
    )
     )
   )
 )
  (apply '+ weights)
)
Title: Re: Average of Numbers in a Area (for you mathies :) )
Post by: ronjonp on May 26, 2011, 04:00:47 PM
Thanks for the reply guys. I guess I didn't explain myself well ... perhaps because even I don't know what I need  :lol:

Here is an example of what I'm working with (select some points to test). I don't want the the total average to be calculated over the entire area, just the weighted average for the closest relevant points (which is the problem I'm having).

Code: [Select]
(defun c:xx (/ avg d e n out p sort_near ss x y)
  (defun maketext (pt value)
    (entmake (list '(0 . "TEXT")
  '(100 . "AcDbEntity")
  '(67 . 0)
  '(8 . "text")
  '(100 . "AcDbText")
  (cons 10 pt)
  (cons 40 (* (getvar 'viewsize) 0.1))
  (cons 1 value)
    )
    )
  )
  (and (setq ss (ssget '((0 . "point"))))
       (setq n -1)
       ;;Data points associated with a value
       (while (setq e (ssname ss (setq n (1+ n))))
(setq out (cons (list (cdr (assoc 10 (entget e))) n) out))
       )
       ;;Add the text to the point (for reference)
       (foreach x out (maketext (car x) (itoa (cadr x))))
       (while (and (setq p (grread 5)) (= (car p) 5))
(redraw)
(setq n 0
      p (cadr p)
)
;;Get distances from p to data points and tag value at end
(setq sort_near (mapcar '(lambda (x)
   (grdraw p (car x) (setq n (1+ n)))
   (list (setq d (distance p (car x))) (cadr x))
 )
out
)
)
;;Sort data list closest to point
(setq sort_near (vl-sort sort_near (function (lambda (a b) (<= (car a) (car b))))))
(setq sort_near (mapcar '(lambda (x y)
   ;;Total of distance between the two points
   (setq d (+ (car x) (car y)))
   ;;perhaps this is where I'm going wrong??
   ;;Add the two values below
   ;;PT1 distance / Total distance * ValuePT2
   ;;PT2 distance / Total distance * ValuePT1
   (+ (* (/ (car x) d) (cadr y)) (* (/ (car y) d) (cadr x)))
 )
;;List
sort_near
;;Same list stepped
(append (cdr sort_near) (list (car sort_near)))
)
      avg (/ (apply '+ sort_near) (length sort_near))
)
(princ (strcat "\nTotal Weighted Average: "
(vl-princ-to-string avg)
"\n2 Point Weighted Average (closest): "
(vl-princ-to-string (car sort_near))
)
)
       )
  )
  (princ)
)

Using the closest 2 points and weighted average yields a picture below. I'd like the values to be more "blended" so there are not any hard lines between the colors. I might just be going about this the completely wrong way  :?