Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers 2

up vote 6 down vote accepted

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

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

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

share|improve this answer
    
@ubpdqn__Yes, it is my fault. The upward normal should be ∇(z−f(x,y)). Thanks for reminding. Nice illustration. –  novice Dec 17 '13 at 23:35
    
@novice...just wanted to clarify...thanks –  ubpdqn Dec 20 '13 at 0:44
add comment

Your Answer

 
discard

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.