Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given a spatial curve represented by a parametric equation, is it possible in Mathematica 9 to calculate symbolically (or at least numerically) the volume of its convex hull?

share|improve this question
Can you give s a hint about the kind of parametric curve you want to look at, and perhaps some code to work with? – bill s May 24 '13 at 16:59
duplicate : – andre May 24 '13 at 17:01
That doesn't quite seem to be a duplicate, @andre, because there the data are given in a different form. In principle there should be a formula for computing the volume in terms of a suitable integrals over the curve. – whuber May 24 '13 at 17:07
@whuber sorry. Also : related question – andre May 24 '13 at 17:44
It does provide a feasible numerical solution though. – Szabolcs May 24 '13 at 18:48

Here is a way to do it numerically:

Reap the points from a parametric plot:

pf = {Cos[u], Sin[u] + Cos[v], Sin[v]};
data = Reap[
     Sow[pf], {u, 0, 2 \[Pi]}, {v, -\[Pi], \[Pi]}]][[2, 1]];

Get all the numeric values, pack the data and delete the duplicates:

pts = Cases[data, {_?NumericQ, _?NumericQ, _?NumericQ}];
pts = DeleteDuplicates[Developer`ToPackedArray@N[pts]];

To look at the points:

Graphics3D[Point[pts], Boxed -> False]

enter image description here

Load TetGenLink and compute and visualize the convex hull:

ch = TetGenConvexHull[pts];
Graphics3D[GraphicsComplex[ch[[1]], Polygon[ch[[2]]]], Boxed -> False]

enter image description here

Compute the delaunay mesh of the convex hull, write a function to compute the volume of a tetrahedron, apply it and total the volume of the tetrahedra:

dt = TetGenDelaunay[pts];
tetVol = Compile[{{coords, _Real, 2}, {incidents, _Integer, 1}}, 
   Block[{a, b, c, d},
    {a, b, c, d} = coords[[incidents]];
    1/6*Det[Transpose[{a, c, b}] - d]
    ], RuntimeAttributes -> Listable];

Total[tetVol @@ dt]
(* 12.5 *)

Sanity check: for a sphere we get:

pf = {Sin[u]*Sin[v], Cos[u]*Sin[v], Cos[v]};
4.138` - 4./3*\[Pi]*1^3

which seams reasonable.


As suggested by Daniel Lichtblau, this also works for parametric curves:

pf = {(t^2 - 1)/(t^2 + 1), 
   2 t/(t^2 + 1), ((t^2 - 1)/(t^2 + 1))^2 - (2 t/(t^2 + 1))^2};
data = Reap[ParametricPlot3D[Sow[pf], {t, -10, 10}]][[2, 1]];
pts = Cases[data, {_?NumericQ, _?NumericQ, _?NumericQ}];
pts = DeleteDuplicates[Developer`ToPackedArray@N[pts]];
Graphics3D[Point[pts], Boxed -> False]

enter image description here

<< TetGenLink`
ch = TetGenConvexHull[pts];
Graphics3D[GraphicsComplex[ch[[1]], Polygon[ch[[2]]]], Boxed -> False]

enter image description here

And what I find most amazing is the suggestion from george2079:

shoelace3rd = Compile[{{coords, _Real, 2}, {tris, _Integer, 2}},
   -Total[Det[coords[[#]]] & /@ tris]/6
shoelace3rd @@ ch
(* 3.12 *)
share|improve this answer
I voted this up because it is quite useful, but I remark that it applies to a parametric surface, not curve. To do similarly with a curve one would perhaps take points thereon, and also convex combinations of (many) pairs of points. Then proceed as above. Example (saddle curve) to test with: ParametricPlot3D[{(t^2 - 1)/(t^2 + 1), 2 t/(t^2 + 1), ((t^2 - 1)/(t^2 + 1))^2 - (2 t/(t^2 + 1))^2}, {t, -10, 10}, PlotRange -> All] – Daniel Lichtblau May 28 '13 at 17:53
@DanielLichtblau, I added the extension, thanks. – user21 May 28 '13 at 19:43

Following ruebenko's approach, after computing the convex hull you can much faster directly get the volume without triangulating the volume as 1/6 Sum[ Det [ triangle vertices ] ]:

Do[ -Total[
    Det[{ch[[1, #[[1]]]], ch[[1, #[[2]]]], ch[[1, #[[3]]]]}] & /@ 
       ch[[2]]]/6 , {10}]
(* 12.5077 *)

This is the 3d shoelace formula:

I must say I've searched pretty good for a link to derivation/proof of this useful thing and come up empty.

Ok the derivation was not so hard to work out.. Note implict here is an assumption that the vertices of each triangle are ordered consistantly CW or CCW. Also this does not require convexity, only whatever connectivity restrictions follow from the divergance theorem.

enter image description here

share|improve this answer
+1 this is quite impressive, if you do find a deviation, I'd be very interested to hear about it. – user21 May 28 '13 at 19:26
@gerrge2079, thanks for the deviation. Very useful indeed. – user21 May 29 '13 at 5:50

In Version 10, once the points have been obtained as per user21's approach, we can tetrahedralize them directly using DelaunayMesh

pf = {Cos[u], Sin[u] + Cos[v], Sin[v]};
pp = ParametricPlot3D[pf, {u, 0, 2 Pi}, {v, -Pi, Pi}]

Mathematica graphics

data = Reap[ParametricPlot3D[Sow[pf], {u, 0, 2 Pi}, {v, -Pi, Pi}]][[2, 1]];
pts = Cases[data, {_?NumericQ, _?NumericQ, _?NumericQ}];


del = DelaunayMesh[pts]

Mathematica graphics

And the volume is computed easily using RegionMeasure



share|improve this answer

Here is another way that uses the Graphics object directly:

gr = ParametricPlot3D[{Cos[u], Sin[u] + Cos[v], Sin[v]}, {u, 0, 2 Pi}, {v, -Pi, Pi}]

Mathematica graphics

We discretize the graphics using DiscretizeGraphics

mr = DiscretizeGraphics[Normal[gr /. (Lighting -> _) :> Lighting -> Automatic]]

Mathematica graphics

We compute the convex hull

hull = ConvexHullMesh[MeshCoordinates[mr]]

Mathematica graphics

And finally, we get the volume using RegionMeasure



OR Volume



As a bonus we can get the surface area of the ParametricPlot object:

RegionMeasure[mr, 2]


Same result can be obtained using Area



share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.