Skip to main content
clean code
Source Link
Nasser
  • 150.5k
  • 12
  • 161
  • 374

This works by making an interpolation function in initialization, which represents the surface. ThenEach time the prob is moved, it finds the Euclidean distance between the current tip position and the surface at the x-coordinates at the time.

It checks that this distance is not smaller than some crash tolerance constant value set in the initialization. (This tolerance can also be added as control variable if needed).

This also prevents the crash to occur, by forcing the slider forthat controls the tip positiony-position to bego back above the surface at that x-coordinate. Hence it is no possible to hit the surface. It also makes a Beep[] also(just in case :).

Manipulate[
 
 Module[{d, ys},
 ys = surfaceFun[x];
 d = EuclideanDistance[{x, y}, {x, surfaceFun[x]ys}];
  If[y <= surfaceFun[x]ys, y = surfaceFun[x]ys + crashTol];
  (*reset slider to stay above surface*)      
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Beep[]; Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]

This works by making an interpolation function which represents the surface. Then it finds the Euclidean distance between the tip and the surface at the x-coordinates.

This also prevents the crash to occur, by forcing the slider for the tip position to be above the surface at that x-coordinate. It makes a Beep[] also.

Manipulate[
 
 Module[{d},
  d = EuclideanDistance[{x, y}, {x, surfaceFun[x]}];
  If[y <= surfaceFun[x], y = surfaceFun[x] + crashTol];
   
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Beep[]; Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]

This works by making an interpolation function in initialization, which represents the surface. Each time the prob is moved, it finds the Euclidean distance between the current tip position and the surface at the x-coordinates at the time.

It checks that this distance is not smaller than some crash tolerance constant value set in the initialization. (This tolerance can also be added as control variable if needed).

This also prevents the crash to occur, by forcing the slider that controls the tip y-position to go back above the surface. Hence it is no possible to hit the surface. It also makes a Beep[] (just in case :).

Manipulate[
 Module[{d, ys},
 ys = surfaceFun[x];
 d = EuclideanDistance[{x, y}, {x, ys}];
 If[y <= ys, y = ys + crashTol]; (*reset slider to stay above surface*)      
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Beep[]; Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }, PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]
added beep
Source Link
Nasser
  • 150.5k
  • 12
  • 161
  • 374

This also prevents the crash to occur, by forcing the slider for the tip position to be above the surface at that x-coordinate. I needed to add soundIt makes a Beep[] also for the warning. May be later.

Manipulate[
 
 Module[{d},
  d = EuclideanDistance[{x, y}, {x, surfaceFun[x]}];
  If[y <= surfaceFun[x], y = surfaceFun[x] + crashTol];
  
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Beep[]; Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]

This also prevents the crash to occur, by forcing the slider for the tip position to be above the surface at that x-coordinate. I needed to add sound also for the warning. May be later.

Manipulate[
 
 Module[{d},
  d = EuclideanDistance[{x, y}, {x, surfaceFun[x]}];
  If[y <= surfaceFun[x], y = surfaceFun[x] + crashTol];
  
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]

This also prevents the crash to occur, by forcing the slider for the tip position to be above the surface at that x-coordinate. It makes a Beep[] also.

Manipulate[
 
 Module[{d},
  d = EuclideanDistance[{x, y}, {x, surfaceFun[x]}];
  If[y <= surfaceFun[x], y = surfaceFun[x] + crashTol];
  
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Beep[]; Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]
Source Link
Nasser
  • 150.5k
  • 12
  • 161
  • 374

This works by making an interpolation function which represents the surface. Then it finds the Euclidean distance between the tip and the surface at the x-coordinates.

This also prevents the crash to occur, by forcing the slider for the tip position to be above the surface at that x-coordinate. I needed to add sound also for the warning. May be later.

Manipulate[
 
 Module[{d},
  d = EuclideanDistance[{x, y}, {x, surfaceFun[x]}];
  If[y <= surfaceFun[x], y = surfaceFun[x] + crashTol];
  
  Graphics[
   {
    box,
    surface,
    GeometricTransformation[
     GeometricTransformation[tip[rg], TranslationTransform[{x, y}]],
     RotationTransform[t Degree, 0.5 + {x, y}]],
    Text[If[d <= crashTol, Style["WARNING !!", Red, 18], ""], {x, y}, {0, 1}]
    }
   ,
   PlotRange -> {{-3, 3.1}, {-1.1, 3}}]
  ],
 
 {{x, 0, "Left/Right"}, -3, 2, Appearance -> "Labeled"},
 {{y, 2, "Up/Down"}, -0.5, 2, 2 crashTol, Appearance -> "Labeled"},
 {{t, 0, "UME tilt"}, -15, 15, Appearance -> "Labeled"},
 {{rg, 0.4, "UME sharpness"}, 0.11, 0.5, Appearance -> "Labeled"},
 ControlPlacement -> Above,
 ContinuousAction -> True,
 Alignment -> Center,
 ImageMargins -> 5,
 FrameMargins -> 5,
 Paneled -> True,
 Frame -> False,
 AutorunSequencing -> {1},
 Initialization :>
  (
   crashTol = 0.01; (*change as needed*)
   surfaceData = Table[BezierFunction[{{-3, 0}, {0, 1}, {2, -1}, {3, 0}}][x], {x, 
      1, 0, -0.05}];

   surfaceFun = Interpolation[surfaceData];
   tip[rg_] := {
     EdgeForm[Thin], FaceForm[White],
     Polygon[{{0, 4}, {0, 0.2}, {0.5 - rg, 0}, {0.5 + rg, 0}, {1, 
        0.2}, {1, 4}}], FaceForm[Black], Rectangle[{0.4, 0}, {0.6, 1}]
     };
   
   box = {EdgeForm[Thin], FaceForm[Blue], Rectangle[{-3, -1}, {3, 3}]};
   
   surface = {FaceForm[Green],
     Polygon@Partition[Flatten@{{-3, -1}, {3, -1}, surfaceData}, 2]}
   )     
 ]

enter image description here