Skip to main content

regions - Computing the intersection area of two disks in 3D


Closely related to this question about highlighting intersection of two disks, I am trying to figure out if one can do so similarly for disks embedded in $3D$ (e.g. in a bounding box). The difference is that, in $3D$ the orientation of the disks matters in how much of overlap/orthogonal-projection there is between them. The orientation of a disk is simply the vector normal to its surface and centered at its center. Therefore, each disk has a center vector (for its position) $\mathbf v$ and a normal vector $\mathbf n$ for its orientation. As an example, 2 disks $i,j$ have maximal overlap if $\mathbf n_i \parallel \mathbf n_j$ and the difference vector of their center positions $\mathbf v_j-\mathbf v_i$ also being parallel to their normal, then the overlap area is exactly $\pi r^2,$ $r$ being the radius of the disks.


Intuitively, computing such projection is as if we computed the shadow two drawn particles (here disks) create onto one another when visualizing them.




  • But is there a way we can quantify the overlap area between two $3D$-embedded disks in Mathematica? Can RegionIntersection be made use of for such application?




Additional clarifications after comments:


To clarify how the overlap between the disks is defined or at least what I mean by it, the idea is to compute the orthogonal projection of their respective surfaces onto one another. For instance given $2$ disks $i,j$ with their position and normal vectors $\mathbf v_i,\mathbf n_i$ and $\mathbf v_j,\mathbf n_j$, we can take the average of the orthogonal-surface-projection of disk $i$ onto plane of disk $j$ with that of disk $j$ onto plane of disk $i$ which yields a symmetrized definition of overlap or intersection between the disks, taking into account not only their orientations but also relative positions.




Stealing from J. M.'s answer here (its first part), here's an image of one such disk within its plane and its orientation vector visualised (the normal to the plane centered at center of disk):


circle on a tilted plane




An attempt to visualize DaveH's suggestion which was very briefly put in their answer:



Say we have one disk centered at v1 and with normal vector n1 and another with v2,n2 as given by (both with diameter d):


v1 = {0.5, 0.5, 0.5}
n1 = {1, 1, 1}
v2 = {1, 1.5, 0}
n2 = {1, 1, 0}
d = 4

then we create cylinders out of the disks, with end-points of each ceylinder given by $\pm 5 \mathbf n_i$ to respective center position of disk $i$:


cyl1 = Cylinder[{v1 - 5*n1, v1 + 5*n1}, d/2]
cyl2 = Cylinder[{v2 - 5*n2, v2 + 5*n2}, d/2]


and visualizing Graphics3D[{Opacity[.5], cyl1, cyl2}]:


enter image description here


But I don't know how much this approach helps in computing the overlap area of interest (and if computationally feasible).



Answer



Here's my take on solving it algebraically:


DiskRadius[Disk3D[_, _, radius_]] := radius;
RotateZToNormal[Disk3D[_, n_, _]] := RotationTransform[{{0, 0, 1}, n}];
MoveToDiskCenter[Disk3D[p_, _, _]] := TranslationTransform[p];
TransformUnitDiskTo[d_Disk3D] := RightComposition[RotateZToNormal[d], MoveToDiskCenter[d]]

Project2D = Most;(*leave out z component to project into 2D*)
CartesianFromPolar = (# /. {r -> Sqrt[x^2 + y^2], \[Phi] -> ArcTan[x, y]} &);
UnitDiskToProjectedEllipseTransform[to_Disk3D] := Function[from,
Composition[
AffineTransform[Reverse[##]] &, (*construct 2d affine transform unitdisk -> projected disk/ellipse*)
CoefficientArrays[#, {x, y}] &, (*extract 2d ellipse linear transformation coefficients*)
Simplify, CartesianFromPolar, Project2D,
InverseFunction[TransformUnitDiskTo[to]],
TransformUnitDiskTo[from]
][r {Cos[\[Phi]], Sin[\[Phi]], 0}]

]
ProjectDiskOnto[to_Disk3D] := Function[from,
Composition[
#.# <= DiskRadius[from]^2 &,
InverseFunction[UnitDiskToProjectedEllipseTransform[to][from]]
][{x, y}]
]
ProjectedDiskRegion[to_Disk3D] := Function[from,
RegionIntersection[
(ImplicitRegion[#, {x, y}] & @* ProjectDiskOnto[to]) /@ {to, from}

]
]
DiskIntersectionArea[disk1_Disk3D, disk2_Disk3D] :=
Mean[Area /@ {ProjectedDiskRegion[disk1][disk2],
ProjectedDiskRegion[disk2][disk1]}]

Let's have a look at an example:


d1 = Disk3D[{-2, 3, -3}, {2, -3, 6}/7, 1]
d2 = Disk3D[{-1, 1, 1}, {-1, 2, -2}/3, 4/5]


Here we encoded the disks by their center point, their normal and their radius with a custom Disk3D head. We can plot these to get an idea


PlotDisk3D[d_Disk3D] := ParametricPlot3D[
TransformUnitDiskTo[d][r {Cos[\[Phi]], Sin[\[Phi]], 0}],
{r, 0, DiskRadius[d]}, {\[Phi], 0, 2 \[Pi]}, Mesh -> None
]
Show[PlotDisk3D /@ {d1, d2}]

Plot of both disks together in 3D


The idea of the solution is to first get an implicit 2d equation of each disk transformed into the reference frame of the other disk and then project it into the xy plane. We do that by creating the function TransformUnitDiskTo which produces an AffineTransform that would transform a unit disk sitting in the xy-plane into any given to disk. Next we start with a parametric polar representation of a unit disk, which we first transform into our (from) disk which we want to project, and then follow it by an inverse affine transform to get it into the reference frame of our to disk. In this reference frame we can project it into 2D and after that convert back to cartesian coordinates and into an implicit representation instead of parametric. Our two example disks in the other reference frame now look like this:


ProjectDiskOnto[d1][d2]


$$\left(\frac{43 x}{52}-\frac{8 y}{13}+\frac{1}{4}\right)^2+\left(\frac{37 x}{65}+\frac{11 y}{13}+\frac{1}{5}\right)^2\leq \frac{16}{25}$$


ProjectDiskOnto[d2][d1]

$$\left(\frac{11 x}{13}-\frac{8 y}{13}+\frac{18}{13}\right)^2+\left(\frac{37 x}{65}+\frac{43 y}{52}-\frac{47}{65}\right)^2\leq 1$$


Projecting a disk onto itself naturally always gives back the disk unaltered:


ProjectDiskOnto[d1][d1]

$$x^2+y^2\leq 1$$


ProjectDiskOnto[d2][d2]


$$x^2+y^2\leq \frac{16}{25}$$


Now we can perform the region intersection inside ImplicitRegions


Resulting projected and intersected disk regions.


and finally take the average of the Region Areas, which Mathematica happily performs for us symbolically and we end up with an exact expression, which we can either simplify a bit via RootReduce on the algebraic parts or just get a numeric approximation with desired accuracy:


DiskIntersectionArea[d1, d2] // N
(* 0.9875 *)




  • Added support for arbitrary disk radii.

  • Fixed a bug in the construction of the implicit ellipse representation.


Comments

Popular posts from this blog

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Adding a thick curve to a regionplot

Suppose we have the following simple RegionPlot: f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}] Now I'm trying to change the curve defined by $y=g[x]$ into a thick black curve, while leaving all other boundaries in the plot unchanged. I've tried adding the region $y=g[x]$ and playing with the plotstyle, which didn't work, and I've tried BoundaryStyle, which changed all the boundaries in the plot. Now I'm kinda out of ideas... Any help would be appreciated! Answer With f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 You can use Epilog to add the thick line: RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}, PlotPoints -> 50, Epilog -> (Plot[g[x], {x, 0, 2}, PlotStyle -> {Black, Thick}][[1]]), PlotStyle -> {Directive[Yellow, Opacity[0.4]], Directive[Pink, Opacity[0.4]],