+<html>
+ <head>
+ <title>Serrated</title>
+ <script type="text/javascript" src="nt3d.js"></script>
+ <script type="text/javascript">
+ function serrated(length, thickness, depth, serration_count, arc, steps_per_serration, edge_bevel_angle) {
+ var tau = 2 * Math.PI;
+ var path_length = serration_count * steps_per_serration;
+ var path = [];
+ for (var i = 0; i <= path_length; i++) {
+ path[i] = [length*i/path_length,0,0];
+ }
+ var serration_length = length / serration_count;
+ var serration_half_length = serration_length / 2;
+ var serration_radius = serration_half_length / Math.sin(tau * arc / 2);
+ var serration_max_height = Math.sqrt(serration_radius*serration_radius - serration_half_length*serration_half_length);
+ // This emits a Sabre Grind. TODO: Support a double bevel.
+ // http://en.wikipedia.org/wiki/Grind#Typical_grinds
+ // http://www.allaboutpocketknives.com/images/aapk_content/blade_bevel.JPG
+ var edge_height = thickness / (2 * Math.tan(tau * edge_bevel_angle));
+ function shape(i) {
+ var serration_progress = (i % steps_per_serration) / steps_per_serration;
+ var serration_x = serration_progress * serration_length - serration_half_length;
+ var serration_height = serration_max_height - Math.sqrt(serration_radius*serration_radius - serration_x*serration_x);
+ if (arc < 0) serration_height *= -1;
+ var blade_height = depth + serration_height;
+ return [[0, 0, 0],
+ [blade_height - edge_height, 0, 0],
+ [blade_height, thickness/2, 0],
+ [blade_height - edge_height, thickness, 0],
+ [0, thickness, 0]];
+ }
+ return nt3d.extrude(path, shape, [1,0,0], [0,0,1]);
+ }
+ var params = [["Blade length", 100],
+ ["Blade thickness", 2],
+ ["Blade depth", 8],
+ ["Number of serrations", 10],
+ ["Arc of each serration (in turns)", .2],
+ ["Steps per serration", 11],
+ ["Edge bevel angle (in turns)", .05]];
+ </script>
+ </head>
+ <body onload="nt3d.framework(serrated, params)">
+ <h1>Serrated</h1>
+ <p>Make a serrated blade.</p>
+ </body>
+</html>