Author Topic: Math problem - calculating a volume given points  (Read 6043 times)

0 Members and 1 Guest are viewing this topic.

dgorsman

  • Water Moccasin
  • Posts: 2437
Math problem - calculating a volume given points
« on: November 18, 2009, 12:37:31 PM »
Both my math and my Google-fu is failing me at the moment.  I'm trying to calculate the volume of a shape (see attached file) given the following conditions:

The shape is defined by six points:

PF PG PH
PA PB PC

... where:

PFxy = PAxy
PGxy = PBxy
PHxy = PCxy

PFz != PGz != PHz

PAz < PFz
PBz < PGz
PCz < PHz

Now if the distance between vertically coresponding points was the same for each point, it would be simple area x length, but thats not necessarily the case here.  I can't use (vla-get-Volume...) as the shape doesn't actually exist except for lists of points.

Any suggestions?
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Math problem - calculating a volume given points
« Reply #1 on: November 18, 2009, 01:08:44 PM »
Why not make a temporary shape?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

mjfarrell

  • Seagull
  • Posts: 14444
  • Every Student their own Lesson
Be your Best


Michael Farrell
http://primeservicesglobal.com/

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #3 on: November 18, 2009, 02:04:51 PM »
Why not make a temporary shape?


Given the number of iterations required, I'd rather do this with math.

I'm not sure how to create it given the available information, either.  The non-parallel faces put extrusion out.  If solids could be readily manipulated I could create a single proxy solid and continuously throw sets of coordinates at it, but I don't think that can be done, can it?
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #4 on: November 18, 2009, 02:08:14 PM »
or try http://www.structuralwiki.org/en/Prismoidal_formula

Thanks, I'll give that a try.  Not sure how well it will work as the top and bottom planes aren't parallel, but it might provide a good approximation using the mid-plane averaged from the PAFz PBGz PCHz values.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Math problem - calculating a volume given points
« Reply #5 on: November 18, 2009, 02:31:32 PM »
The formula wont work.
Quote
Prismoid
A solid having two parallel plane bases with sides generated by straight lines.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

mjfarrell

  • Seagull
  • Posts: 14444
  • Every Student their own Lesson
Re: Math problem - calculating a volume given points
« Reply #6 on: November 18, 2009, 02:40:24 PM »
then perhaps follow the link towards  Average End Area....instead...
Be your Best


Michael Farrell
http://primeservicesglobal.com/

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #7 on: November 18, 2009, 03:09:55 PM »
Something else to check on, but I think it again assumes parallel surfaces - there's only a single "perpendicular distance between bases" value.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: Math problem - calculating a volume given points
« Reply #8 on: November 18, 2009, 03:12:39 PM »
this solid is a prism plus two pyramids

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #9 on: November 18, 2009, 03:41:47 PM »
this solid is a prism plus two pyramids

Could you diagram that out please?
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: Math problem - calculating a volume given points
« Reply #10 on: November 18, 2009, 04:19:10 PM »
i hope my drawing skills are not that bad :)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Math problem - calculating a volume given points
« Reply #11 on: November 18, 2009, 08:35:55 PM »
Does this one do you any good?
http://mathworld.wolfram.com/PyramidalFrustum.html

See formula 10,11,12
« Last Edit: November 18, 2009, 08:47:38 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Math problem - calculating a volume given points
« Reply #12 on: November 19, 2009, 11:26:21 AM »
OK, those formulas are no good as any Frustum has parallel planes.
Back to the drawing board. :-P
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Math problem - calculating a volume given points
« Reply #13 on: November 19, 2009, 11:45:10 AM »
Vovka,
I see the pyramid.


I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12917
  • London, England
Re: Math problem - calculating a volume given points
« Reply #14 on: November 19, 2009, 11:46:23 AM »
haha - would you believe I just constructed exactly the picture you just posted  ;-)

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: Math problem - calculating a volume given points
« Reply #15 on: November 19, 2009, 12:15:00 PM »
Alan, it means that my drawing skills are so bad, that no one is going to believe from the first sight :)
« Last Edit: November 19, 2009, 02:42:23 PM by VovKa »

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #16 on: November 19, 2009, 02:26:43 PM »
Taking the easy part first - volume of the middle chunk.

Vmiddle = A * L, where

L = min (PFz PGz PHz) - max ( PAz PBz PCz)


Area is bit trickier, we need to create a set of intermediary points.  Using the three points at the lower end we get

Iz = max ( PAz PBz PCz)

PAM = (PAx, PAy, Iz)
PBM = (PBx, PBy, Iz)
PCM = (PCx, PCy, Iz)

Area of a triangle is 0.5 * base * perpendicular height.  We can use any of the three sides as the base, but the height needs to be trig'd.  So using line PAM PBM as the base, the distance d is perpendicular from line PAM PBM to PCM:

A = 0.5 * | PAM PBM | * ( | PBM PCM | * sin PAM-PBM-PCM )


( LISP to come next week, unless somebody is feeling industrious )
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: Math problem - calculating a volume given points
« Reply #17 on: November 20, 2009, 12:25:13 PM »
my 3d experience equals to zero, so i had to spend a couple of hours restudying stereometry
here's what i got so far
Code: [Select]
(defun vk_GetArea (CoordsList)
  (abs
    (/ (apply '+
     (mapcar (function
(lambda (p1 p2)
 (* (+ (car p1) (car p2)) (- (cadr p1) (cadr p2)))
)
     )
     CoordsList
     (cons (last CoordsList) CoordsList)
     )
       )
       2.0
    )
  )
)
(defun vk_IsPointOnLine (p1 p2 p / r)
  (equal (+ (distance p p1) (distance p p2))
(distance p1 p2)
1e-8
  )
)
(defun vk_GetOrt (v / k)
  (setq k (/ 1.0 (distance '(0 0 0) v)))
  (mapcar (function (lambda (c) (* c k))) v)
)
(defun vk_GetCrossProduct (v1 v2)
  (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
(- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
(- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
  )
)
(defun vk_Get3pNormal (p1 p2 p3 /)
;;;  (c:cal "nor ('p1','p2','p3')")
  (vk_GetOrt
    (vk_GetCrossProduct (mapcar '- p1 p2) (mapcar '- p3 p2))
  )
)
(defun vk_GetPlaneNormal (PlaneLst / p1 p2 p3)
  (setq p1 (car PlaneLst)
p2 (cadr PlaneLst)
PlaneLst (cddr PlaneLst)
  )
  (while (and (setq p3 (car PlaneLst)) (vk_IsPointOnLine p1 p3 p2))
    (setq PlaneLst (cdr PlaneLst))
  )
  (if p3
    (vk_Get3pNormal p1 p2 p3)
  )
)
(defun vk_TransPlane (PlaneLst N / pn)
  (setq pn (vk_GetPlaneNormal PlaneLst))
  (mapcar (function (lambda (c) (trans c N pn))) PlaneLst)
)
(defun vk_GetPointToPlaneDist (p PlaneLst / n)
;;;(c:cal "dpp ('p','p1','p2','p3')")
  (setq n (vk_GetPlaneNormal PlaneLst))
  (abs (- (last (trans (car PlaneLst) '(0 0 1) n))
 (last (trans p '(0 0 1) n))
       )
  )
)
(defun vk_GetFrustumVolume (BottomLst TopLst)
  ((lambda (s1 s2)
     (/ (* (vk_GetPointToPlaneDist (car TopLst) BottomLst)
  (+ s1 s2 (sqrt (* s1 s2)))
)
3.0
     )
   )
    (vk_GetArea (vk_TransPlane BottomLst '(0 0 1)))
    (if (cdr TopLst)
      (vk_GetArea (vk_TransPlane TopLst '(0 0 1)))
      0.0
    )
  )
)
(defun vk_GetPyramidVolume (BaseLst apex)
  (vk_GetFrustumVolume BaseLst (list apex))
)
(defun vk_GetPrismVolume (BottomLst TopLst)
  (vk_GetFrustumVolume BottomLst TopLst)
)
all functions are meant to be generic
still to be done: split the solid into three frustums. one of them will be a prism and two other - pyramids

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Math problem - calculating a volume given points
« Reply #18 on: November 20, 2009, 06:59:37 PM »
Taking the easy part first - volume of the middle chunk.

Vmiddle = A * L, where

L = min (PFz PGz PHz) - max ( PAz PBz PCz)


< ..... >

This assumes that the body is vertical.

Is this a given for your problem.

Regards
Kerry
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #19 on: November 23, 2009, 05:09:48 PM »
Taking the easy part first - volume of the middle chunk.

Vmiddle = A * L, where

L = min (PFz PGz PHz) - max ( PAz PBz PCz)


< ..... >

This assumes that the body is vertical.

Is this a given for your problem.

Regards
Kerry


Yup.  From the first post, PAxy = PFxy, PBxy = PGxy, and PCxy = PDxy.  If this wasn't a case, then an arbitrary coordinate system could be set up to make it so, with all initial points converted to that system.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Math problem - calculating a volume given points
« Reply #20 on: December 01, 2009, 02:59:29 PM »
Never fails - I get started on something and three other things pop up which need doing *now*.


Code: [Select]
;;
;; math_lib:volumeOfSolid4
;;
;; arguments: plane1 - list of three points (as list) describing the lower
;;   plane
;;   plane2 - list of three points (as list) describing the upper
;;   plane
;;
;; return value: real with shape volume
;;
;; comments: calculates the volume of shape defined by two triangular planes.
;; This function is intented to work in consistent metric units i.e.
;; if the drawing is in millimeters the volume will be in mm^3.
;;

(defun math_lib:volumeOfSolid4 ( plane1
                                       plane2 / return_volume
                                      vol_middle vol_lower vol_upper
                                      PA PB PC PF PG PH
                                      Iz1 Iz2
                                      PAM PBM PCM
                                      area_section )

;; Local defun: x value of a coordinate

   (defun |x| ( input ) (car input))

;; Local defun: y value of a coordinate

   (defun |y| ( input ) (cadr input))

;; Local defun: z value of a coordinate

   (defun |z| ( input ) (caddr input))

;; Local defun: angle from three points, as interior and exterior values

   (defun get< ( pt1 vertex pt2 / return_angle angle1 angle2 )
(if
         (<
            (setq return_angle (- (angle vertex pt1) (angle vertex pt2)))
            0
         )
      (setq return_angle (+ (* pi 2) return_angle))
   )

      (list
         (max (- (* pi 2) return_angle) return_angle)
         (min (- (* pi 2) return_angle) return_angle)
       )
)


   
;; Split up the arguments into the lower plane coordinates (PA PB PC) and the
;; upper plane coordinates (PF PG PH)

   (setq
      PA (car plane1)
      PB (cadr plane1)
      PC (caddr plane1)
   )

   (setq
      PF (car plane2)
      PG (cadr plane2)
      PH (caddr plane2)
   )

;; We break the solid into three parts - a triangular solid with parallel end
;; faces and two pyramids.

;; Step 1: getting the volume of the triangular solid

;; Construct a plane based on the max z of the lower plane

   (setq Iz1 (max (|z| PA) (|z| PB) (|z| PC)))
   (setq PAM (list (|x| PA) (|y| PA) Iz1))
   (setq PBM (list (|x| PB) (|y| PB) Iz1))
   (setq PCM (list (|x| PC) (|y| PC) Iz1))

;; Get the area of the end planes, using 0.5 * base * height, or
;; 0.5 * |PAM PBM| * (|PBM PCM| * sin < PAM-PBM-PCM)

   (setq
      area_section
        (*
           0.5
           (distance PAM PBM)
           (distance PBM PCM)
           (sin (cadr (get< PAM PBM PCM)))
        )
   )

;; Calculate the volume using the distance from the max z of the lower plane
;; and the min z of the upper plane

   (setq Iz2 (min (|z| PF) (|z| PG) (|z| PH)))

   (setq
      vol_middle
        (*
           area_section
           (distance
              PAM
              (list (|x| PF) (|y| PF) Iz2)
           )
        )
   )

;; Step 2: get the volume of the lower pyramid

;; This is just a placeholder for the moment
   
   (setq vol_lower 0)

;; Step 2: get the volume of the upper pyramid

;; This is just a placeholder for the moment
   
   (setq vol_upper 0)

   (+ vol_middle vol_lower vol_upper)
)

Apologies for the gibbled formatting - I'm a little tight on time.   :oops:
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}