5
$\begingroup$

Here is my approach, for an example surface function:

surface[x_, y_] := Sin[x y];

The normal vector of a point in the surface is computed as:

NormalVector[a_, b_] := {D[surface[xx, yy], xx], D[surface[xx, yy], yy],1} /. {xx -> a, yy -> b};

Then the plot is as follows:

Plot3D[surface[x, y], {x, 0, 3}, {y, 0, 3}, ColorFunction -> Function[{x, y, z}, 
RGBColor[0, 0, VectorAngle[NormalVector[x, y], {0, 0, 1}]]]]

However it fails, why?

$\endgroup$
0

2 Answers 2

8
$\begingroup$

To be honest, I'm not really sure why you need ColorFunctionScaling since there aren't any outlayers that could make the rest of the plot flat, nevertheless:

Plot3D[surface[x, y], {x, 0, 3}, {y, 0, 3}, ColorFunctionScaling -> False, 
          Lighting -> "Neutral", ColorFunction -> Function[{x, y, z}, 
          Blend[{Blue, White}, 2 #/Pi] &@ VectorAngle[NormalVector[x, y], {0, 0, 1}]]]

enter image description here

Update

Plot3D[surface[x, y], {x, 0, 3}, {y, 0, 3}, ColorFunctionScaling -> False, 
         ColorFunction -> Function[{x, y, z}, Blend["Rainbow", Rescale[#, {0, Pi/2}]
                                  ] & @ VectorAngle[NormalVector[x, y], {0, 0, 1}]], 
         PlotLegends -> BarLegend[{"Rainbow", {0, 90}},  ColorFunctionScaling -> True,  
                                  LegendLabel -> "normal vs zenith [\[Degree]]"]
      ]

enter image description here

$\endgroup$
6
  • $\begingroup$ @Kuba.Aha! But is there a way to assign more color to the different slope values. It looks a bit dull. $\endgroup$
    – novice
    Commented Dec 16, 2013 at 8:23
  • $\begingroup$ @novice Of course, take a look at Blend or Color Schemes. Try for example Blend["Rainbow", #] &@ $\endgroup$
    – Kuba
    Commented Dec 16, 2013 at 8:27
  • $\begingroup$ @KubaThank you, I tried and made it. $\endgroup$
    – novice
    Commented Dec 16, 2013 at 8:33
  • $\begingroup$ @KubaAnother small problem is that PlotLegends -> Automatic fails. $\endgroup$
    – novice
    Commented Dec 16, 2013 at 8:50
  • $\begingroup$ @novice ok, see my edit. $\endgroup$
    – Kuba
    Commented Dec 16, 2013 at 9:56
9
$\begingroup$

Just for variety: Note also outward normal to surface $z=f(x,y)$: $\nabla(z-f(x,y))=<-f_x,-f_y,1>$ (inward negative)...not same as "NormalVector" function listed (apologies if I have misinterpreted or made error). I have rewritten taking into account:

f[x_, y_] := Sin[x y];
n[x_, y_] := {-D[f[a, b], a], -D[f[a, b], b], 1} /. {a -> x, b -> y};
va[x_, y_] := VectorAngle[n[x, y], {0, 0, 1}];
Manipulate[
 Show[Plot3D[f[x, y], {x, 0, 3}, {y, 0, 3}, 
   ColorFunction -> 
    Function[{x, y, z}, 
     ColorData["Rainbow"][Rescale[va[x, y], {0, 1.4}]]], 
   ColorFunctionScaling -> False, PlotRange -> {-2, 2}, 
   PerformanceGoal -> "Quality"], 
  Graphics3D[{Red, Thick, 
    Arrow[{{s[[1]], s[[2]], 
       f[s[[1]], s[[2]]]}, {s[[1]], s[[2]], f[s[[1]], s[[2]]]} + 
       Normalize@n[s[[1]], s[[2]]]}, 0.03]}],
  ContourPlot3D[{x - s[[1]], y - s[[2]], z - f[s[[1]], s[[2]]]}.n[
      s[[1]], s[[2]]] == 0, {x, s[[1]] - 0.2, 
    0.2 + s[[1]]}, {y, -0.2 + s[[2]], 0.2 + s[[2]]}, {z, -2, 2}, 
   Mesh -> False]], {s, {0.1, 0.1}, {3, 3}}]

The graphic illustrates color of surface based on angle between normal and $\vec{k}$ (which seems to be intended color function). I show the unit normal and tangent plane.

enter image description here

$\endgroup$
2
  • $\begingroup$ @ubpdqn__Yes, it is my fault. The upward normal should be ∇(z−f(x,y)). Thanks for reminding. Nice illustration. $\endgroup$
    – novice
    Commented Dec 17, 2013 at 23:35
  • $\begingroup$ @novice...just wanted to clarify...thanks $\endgroup$
    – ubpdqn
    Commented Dec 20, 2013 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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