# ParametricPlot3D coloring based on whether function located inside/outside of another parametric function

I have two parametric shapes: an inclined ring and an elliptic cone whose vertex lies along the x axis.

ring[u_,v_,ψ_,α_]:={v Cos[u] Cos[α] Cos[ψ]-v Sin[u] Sin[α],v Cos[α] Sin[u]+v Cos[u] Cos[ψ] Sin[α],-v Cos[u] Sin[ψ]}

cone[u_,v_,Req_,obl_,r_,ψ_,α_]:={u,(Req (r-u) Cos[v] Cos[ψ Sin[α]])/r+(Req (r-u) Sin[v] Sin[ψ Sin[α]])/(r Sqrt[Cos[ψ Cos[α]]^2/(1-obl)^2+Sin[ψ Cos[α]]^2]),(Req (r-u) Cos[ψ Sin[α]] Sin[v])/(r Sqrt[Cos[ψ Cos[α]]^2/(1-obl)^2+Sin[ψ Cos[α]]^2])-(Req (r-u) Cos[v] Sin[ψ Sin[α]])/r};


when plotted, these two shapes intersect each other something like this (depending on input parameters):

Hopefully it's clear from the image that the cone intersects the ring, leaving part of the ring inside of the cone and part of the ring outside of it.

What I actually want is, instead of displaying both ring and cone, I want to color parts of the ring differently depending on whether it is inside or outside of the cone.

Your answer does not have to be specific to the messy equations I have listed above. What I want boils down to, "how do I set the colors of a parametric plot as a conditional of a different parametric equation?" I have tried all sorts of MeshShading options, but I can't seem to get it to work.

In case it matters: the arguments of ring are: the azimuthal angle u, the radial extent of the ring v, the magnitude of the tilt out of the XY plane psi, and the XY orientation of the ring's normal vector alpha. The unique arguments of cone are: the semimajor axis of the cone at x=0 Req, the distance of the vertex away from the origin r, and the oblateness of a YZ cross-section of the cone obl.

EDIT: as requested, here is the exact code to make the above figure.

Req = 60300000.;
obl = .25;
au = 1.496*10^11;
r = 10*au;
\[Psi] = 27*Pi/180.;
\[Alpha] = 0*Pi/180.;
ringstart = Req + 7000000.;
ringend = Req + 80000000;

lightcone[u_,v_,Req_,obl_,r_,\[Psi]_,\[Alpha]_]:={u,(Req (r-u) Cos[v] Cos[\[Psi] Sin[\[Alpha]]])/r+(Req (r-u) Sin[v] Sin[\[Psi] Sin[\[Alpha]]])/(r Sqrt[Cos[\[Psi] Cos[\[Alpha]]]^2/(1-obl)^2+Sin[\[Psi] Cos[\[Alpha]]]^2]),(Req (r-u) Cos[\[Psi] Sin[\[Alpha]]] Sin[v])/(r Sqrt[Cos[\[Psi] Cos[\[Alpha]]]^2/(1-obl)^2+Sin[\[Psi] Cos[\[Alpha]]]^2])-(Req (r-u) Cos[v] Sin[\[Psi] Sin[\[Alpha]]])/r};

rings[u_,v_,\[Psi]_,\[Alpha]_]:={v Cos[u] Cos[\[Alpha]] Cos[\[Psi]]-v Sin[u] Sin[\[Alpha]],v Cos[\[Alpha]] Sin[u]+v Cos[u] Cos[\[Psi]] Sin[\[Alpha]],-v Cos[u] Sin[\[Psi]]};

lightconeplot[Req_,obl_,r_,\[Psi]_,\[Alpha]_,start_,stop_]:=ParametricPlot3D[lightcone[u,v,Req,obl,r,\[Psi],\[Alpha]],{v,0,2Pi},{u,start,stop},
Mesh->None,
PlotStyle->{Blue,Opacity[0.3]},
PlotPoints->30
];

Show[{
ParametricPlot3D[rings[u, v, \[Psi], \[Alpha]], {u, 0, 2 Pi}, {v,ringstart,ringend},PlotStyle -> White, PlotPoints -> 30],
lightconeplot[Req, obl, 8*Req, \[Psi], \[Alpha], -4*Req, 4*Req]
},
ViewPoint -> 10*{0, 1, 1},
Axes -> False,
Boxed -> False
]


I am working in Mathematica 10. This code should be directly pastable.

• Can you please share all the code you are using to make that plot? – rhermans May 31 '18 at 21:38

A simpler example is that of two spheres intersecting, so I'll use that:

sphere1[u_, v_] := {Sin[u] Cos[v], Sin[u] Sin[v], Cos[u]}
sphere2[u_, v_] := {0.8, 0, 0} + {Sin[u] Cos[v], Sin[u] Sin[v], Cos[u]}

ParametricPlot3D[{
sphere1[u, v],
sphere2[u, v]
}, {u, 0, Pi}, {v, 0, 2 Pi}]


A trick that can be used for this case and for your case is to plot the region that intersects separately from the region that doesn't intersect. Like this:

Show[
ParametricPlot3D[
sphere1[u, v], {u, 0, Pi}, {v, 0, 2 Pi},
RegionFunction -> (Norm[{0.8, 0, 0} - {#, #2, #3}] > 1 &),
Mesh -> {Subdivide[Pi, 15], Subdivide[2 Pi, 30]}
],
ParametricPlot3D[
sphere1[u, v], {u, 0, Pi}, {v, 0, 2 Pi},
RegionFunction -> (Norm[{0.8, 0, 0} - {#, #2, #3}] < 1 &),
PlotStyle -> Red,
Mesh -> {Subdivide[Pi, 15], Subdivide[2 Pi, 30]}
],
PlotRange -> All
]


All that is needed is to be able to write a function that says whether a point should be considered part of the region being plotted or not.

The purpose of using the Mesh option is to make sure that the meshes in the two different regions align.

If you can't find a region function for the region you're interested in then you may resort to creating the corresponding regions (e.g. with ImplicitRegion) and then using the RegionMember function.

• Thanks for the reply, this is a huge step in the right direction. I was unaware that those functions exist. I don't think a single inequality can describe the boundary set by my intersection. How would I actually use ImplicitRegion and RegionMember in a ParametricPlot3D environment? I am only seeing them be used as setup functions for RegionPlot. – ahle6481 May 31 '18 at 22:21
• @ahle6481 In this particular case it would work to replace the given RegionFunction with (RegionMember[Ball[{0.8, 0, 0}, 1], {#, #2, #3}] &). This is because Ball can be used as a region. I mentioned ImplicitRegion, which can take the place of Ball, just to point out that the region functionality offers a very general solution. As long as you can write down inequalities to describe the region, it will work. – C. E. May 31 '18 at 22:48
• Apologies for still not getting it. This approach makes sense to me, but I am struggling with the syntax. With ImplicitRegion, I tried to make one of the above spheres only partially display with the option RegionFunction -> (RegionMember[ ImplicitRegion[#1^2 + #2^2 + #3^2 == 1 && #1 < 0. && #2 > 0.0, {#1, #2, #3}]] &) but I a get an error stating that it is not a boolean. What is the correct syntax? – ahle6481 May 31 '18 at 23:32
• First define reg = Region@ImplicitRegion[x^2 + y^2 + z^2 <= 1 && x < 0. && y > 0, {x, y, z}]; and then use (RegionMember[reg, {#, #2, #3}] &). – C. E. May 31 '18 at 23:52
• Great that worked! Note for other users: I am using Mathematica 10, which does not include Region. However, simply removing the Region function (reg=ImplicitRegion...) it worked exactly how I expected it to. – ahle6481 Jun 1 '18 at 0:09