// title : Fingerboard Mold V2 // author : Beau Trifiro // description: Fingerboard Mold Design Tool // file : 210818-FB-MOLD-V2 // (C) 2020 - present function getParameterDefinitions() { return ([ { name: 'mold_design', caption: 'Mold Design', type: 'group'}, { name: 'resolution', type: 'slider', class: 'paramSlider', initial: 10, step: 1, min: 1, max:20, caption: 'Model Resolution'}, { name: 'mold_width', type: 'slider', class: 'paramSlider', initial: 4, step: 0.1, min: 1, max: 6, caption: 'Mold Width, cm'}, { name: 'mold_length', type: 'slider', class: 'paramSlider', initial: 12, step: 0.1, min: 8, max: 15, caption: 'Mold Length, cm'}, { name: 'mold_height', type: 'slider', class: 'paramSlider', initial: 3, step: 0.1, min: 1, max: 4, caption: 'Mold Height (Core), cm'}, { name: 'wheelbase', type: 'slider', class: 'paramSlider', initial: 45, step: 1, min: 30, max: 100, caption: 'Wheelbase, mm'}, { name: 'deck_width', type: 'slider', class: 'paramSlider', initial: 30, step: 1, max: 50, min: 20, caption: 'Deck Width, mm'}, { name: 'concave_drop', type: 'float', initial: 2.0, step: 0.1, caption: 'Concave Drop, mm'}, { name: 'transition_length', type: 'slider', class: 'paramSlider', initial: 15, step: 1, min: 10, max: 22, caption: 'Transition Length, mm'}, { name: 'kick_gap', type: 'slider', class: 'paramSlider', initial: 2, step: 0.5, min: 1, max: 4, caption: 'Kick Gap, mm'}, // { name: 'nose_transition_length', type: 'slider', initial: 15, step: 1, min: 10, max: 22, caption: 'Nose Transition Length, mm'}, // { name: 'tail_transition_length', type: 'slider', initial: 15, step: 1, min: 10, max: 22, caption: 'Tail Transition Length, mm'}, //{ name: 'offset', type: 'float', initial: 0.0, step: 0.1, caption: 'Extend Tail, inches'}, { name: 'kicknose_angle', type: 'slider', class: 'paramSlider', initial: 20, step: 1, min: 0, max: 30, caption: 'Kicknose, deg.'}, { name: 'kicktail_angle', type: 'slider', class: 'paramSlider', initial: 20, step: 1, min: 0, max: 30, caption: 'Kicktail, deg.'}, // { name: 'nose_flatness', type: 'float', initial: 0.75, step: 0.05, max: 1.00, min: 0.00, caption: 'Nose Shape (max: 1, min: 0)'}, // { name: 'tail_flatness', type: 'float', initial: 0.75, step: 0.05, max: 1.00, min: 0.00, caption: 'Tail Shape (max: 1, min: 0)'}, { name: 'nose_radius', type: 'slider', class: 'paramSlider', initial: 20, step: 1, min: 1, max: 100, caption: 'Nose Radius, mm'}, { name: 'tail_radius', type: 'slider', class: 'paramSlider', initial: 20, step: 1, min: 1, max: 100, caption: 'Tail Radius, mm'}, //{ name: 'transition_resolution', type: 'float', initial: .05, step: .03125, caption: 'Transition Resolution, in. (smaller=smoother)'}, //{ name: 'make_notches', type: 'checkbox', checked: false, caption: 'Make alignment notches'}, { name: 'make_holes', type: 'checkbox', checked: false, caption: 'Make truck holes'}, //{ name: 'hole_depth', type: 'float', initial: 0.25, step: 0.125, caption: 'Truck hole depth, in.'}, { name: 'hole_diameter', type: 'float', initial: 1.7, step: 0.05, caption: 'Truck hole diameter, mm'}, { name: 'hole_pattern_length', type: 'float', initial: 7.5, step: 0.05, caption: 'Truck hole pattern length, mm'}, { name: 'hole_pattern_width', type: 'float', initial: 5.5, step: 0.05, caption: 'Truck hole pattern width, mm'}, /*{ name: 'board_color', type: 'color', initial: "#00aadd", caption: 'Color!'}*/ /*{ name: 'nose_x_adjust', type: 'float', initial: 0.25, caption: 'Nose X Adjustment (0 to 1)'}, { name: 'nose_y_adjust', type: 'float', initial: 0.67, caption: 'Nose Y Adjustment (0 to 1)'}, { name: 'tail_x_adjust', type: 'float', initial: 0.25, caption: 'Tail X Adjustment (0 to 1)'}, { name: 'tail_y_adjust', type: 'float', initial: 0.67, caption: 'Tail Y Adjustment (0 to 1)'} */ {name: 'thickness', type: 'float', initial: 3.0, step: 0.5, min: 0, max: 6, caption: 'Mold Offset, mm'}, {name: 'negHeight', type: 'slider', class: 'paramSlider', initial: 2, step: 0.5, min: 1, max: 6, caption: 'Cavity Minimum Thickness'}, {name: 'invert', type: 'checkbox', checked: false, caption: 'Show Opposite Mold (Cavity)'}, { name: 'template_design', caption: 'Template Design', type: 'group'}, { name: 'showTemplate', type: 'checkbox', checked: false, caption: 'Show Template'}, { name: 'show_profile', type: 'checkbox', checked: false, caption: 'Show Profile, Only?'}, { name: 'nose_length', type: 'slider', class: 'paramSlider', initial: 20, step: 1, max: 30, min: 5, caption: 'Nose Length, mm'}, { name: 'tail_length', type: 'slider', class: 'paramSlider', initial: 20, step: 1, max: 30, min: 5, caption: 'Tail Length, mm'}, { name: 'taperN', type: 'slider', class: 'paramSlider', initial: 37, step: 1, max: 45, min: 5, caption: 'Nose Taper Point, mm'}, { name: 'taperT', type: 'slider', class: 'paramSlider', initial: 37, step: 1, max: 45, min: 5, caption: 'Tail Taper Point, mm'}, { name: 'nose_flatness', type: 'slider', class: 'paramSlider', initial: 75, step: 5, max: 100, min: 50, caption: 'Nose Shape'}, { name: 'tail_flatness', type: 'slider', class: 'paramSlider', initial: 75, step: 5, max: 100, min: 50, caption: 'Tail Shape'}, { name: 'shift', type: 'float', initial: 0, step: 0.125, caption: 'Shift Profile, in.
(Single kick molds only!)'}, { name: 'cutout_specs', caption: '
Wheel Cutouts ', type: 'group'}, { name: 'make_cutouts', type: 'checkbox', checked: false, caption: 'Make Cutouts'}, { name: 'noseLipX', type: 'slider', class: 'paramSlider', min: 5, max: 50, step: 0.25, initial: 45, caption: 'Nose Cutout Depth'}, { name: 'noseLipY', type: 'slider', class: 'paramSlider', min: -10, max: 20, step: 0.25, initial: 8, caption: 'Nose Cutout Width'}, { name: 'noseY', type: 'slider', class: 'paramSlider', min: 1, max: 20, initial: 11, step: 0.25, caption: 'Nose Width'}, { name: 'tailLipX', type: 'slider', class: 'paramSlider', min: 5, max: 50, step: 0.25, initial: 39, caption: 'Tail Cutout Depth'}, { name: 'tailLipY', type: 'slider', class: 'paramSlider', min: -10, max: 20, step: 0.25, initial: 11, caption: 'Tail Cutout Width'}, { name: 'tailY', type: 'slider', class: 'paramSlider', min: 1, max: 20, initial: 20, step: 0.25, caption: 'Tail Width'}, ]); } /* Interactive parametric models It is possible to make certain parameters editable in the browser. This allows users not familiar with JavaScript to create customized STL files. To do so, add a function getParameterDefinitions() to your .jscad source. This function should return an array with parameter definitions. Currently 6 parameters types are supported: float, int, text, longtext, bool and choice. The user edited values of the parameters will be supplied as an object parameter to the main() function of your .jscad file. */ function main (parameters) { var width = parseFloat(parameters.mold_width); // var deck_width = parameters.width; var wheelbase = parseFloat(parameters.wheelbase/10); var thickness = parseFloat(parameters.thickness)/10; //how many decks to be pressed at once var negHeight = parseFloat(parameters.negHeight); var inverse = parameters.invert; var showTemplate = parameters.showTemplate; var deck_width = parseFloat(parameters.deck_width)/10; var concave_radius, kicknose_radius, kicktail_radius; var concave_drop = parseFloat(parameters.concave_drop)/10; var taperN = parseFloat(parameters.taperN)/10; var taperT = parseFloat(parameters.taperT)/10; if (inverse == false) { concave_radius = (Math.pow((deck_width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop); kicknose_radius = parseFloat(parameters.nose_radius)/10; kicktail_radius = parseFloat(parameters.tail_radius)/10; } else { concave_radius = ((Math.pow((deck_width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop)) + thickness; kicknose_radius = parseFloat(parameters.nose_radius/10) + thickness; kicktail_radius = parseFloat(parameters.tail_radius/10) + thickness; } var nose_transition_length = parseFloat(parameters.transition_length)/10; var tail_transition_length = parseFloat(parameters.transition_length)/10; var mold_width = parseFloat(parameters.mold_width); var mold_length = parseFloat(parameters.mold_length); var mold_height = parseFloat(parameters.mold_height); var show_profile = parameters.show_profile; var shift = parameters.shift; var make_cutouts = parameters.make_cutouts; var noseLipX = parameters.noseLipX/10; var noseLipY = parameters.noseLipY/10; var noseY = parameters.noseY/10; var tailLipX = parameters.tailLipX/10; var tailLipY = parameters.tailLipY/10; var tailY = parameters.tailY/10; var bolt_pattern_width = parameters.hole_pattern_width/10; // 5mm - not to scale var bolt_pattern_length = parameters.hole_pattern_length/10; // 8mm - not to scale //var bolt_diameter = 0.24; //not to scale //var hole_diameter = bolt_diameter; var hole_depth = mold_height*10; //var hole_depth = parameters.hole_depth; var hole_diameter = parseFloat(parameters.hole_diameter)/10; var make_holes = parameters.make_holes; var kick_gap = parseFloat(parameters.kick_gap)/10; var concave_length = wheelbase + (bolt_pattern_length*2) + (kick_gap*2) - nose_transition_length - tail_transition_length; //var concave_length = length - (kicktail_length + kicknose_length + nose_transition_length + tail_transition_length); var offset = 0; // parameters.offset; var tail_length = (mold_length - (concave_length + nose_transition_length + tail_transition_length))/2; var nose_length = (mold_length - (concave_length + nose_transition_length + tail_transition_length))/2; if (showTemplate == true) { tail_length = parseFloat(parameters.tail_length)/10; nose_length = parseFloat(parameters.nose_length)/10; } var kicktail_length = tail_length-kick_gap; var kicknose_length = nose_length-kick_gap; var kicknose_angle = parameters.kicknose_angle; var kicktail_angle = parameters.kicktail_angle; var nose_shape = parseFloat(parameters.nose_flatness)/100; var tail_shape = parseFloat(parameters.tail_flatness)/100; /* var board_color = parameters.board_color;*/ var mold_offset = thickness; var thickness = mold_height; var slice_thickness = parseFloat(parameters.resolution)/100; //var slice_thickness = 0.02; var min_radius = concave_radius; var length = wheelbase + (bolt_pattern_length*2) + tail_length + nose_length; //var concave_length = length - (kicktail_length + kicknose_length + nose_transition_length + tail_transition_length); var flat_concave_length = concave_length + nose_transition_length + tail_transition_length; //find kicknose translation parameters var kicknose_hypotenuse = 2*(kicknose_radius*sin(kicknose_angle/2)); var kicknose_radius_length = kicknose_hypotenuse*cos(kicknose_angle/2); var kicknose_radius_height = kicknose_hypotenuse*sin(kicknose_angle/2); //find kicktail translation parameters var kicktail_hypotenuse = 2*(kicktail_radius*sin(kicktail_angle/2)); var kicktail_radius_length = kicktail_hypotenuse*cos(kicktail_angle/2); var kicktail_radius_height = kicktail_hypotenuse*sin(kicktail_angle/2); var number_of_segments = 10; //for transition section resolution var skateboard = make_concave(concave_radius, thickness, concave_length, width,flat_concave_length).translate([0,0,thickness]); kicknose = make_kicknose_curve(kicknose_radius, width, kicknose_angle, nose_transition_length, concave_length, kicknose_length, mold_height); kicktail = make_kicktail_curve(kicktail_radius, width, kicktail_angle, tail_transition_length, concave_length, kicktail_length, mold_height); var mold = color([0.7,0.7,0.7],make_concave(concave_radius, thickness, concave_length, width, flat_concave_length)); mold = mold.union(color([.5,.5,.5],kicknose)); mold = mold.union(color([.5,.5,.5],kicktail)); if (concave_radius !== 0) { var nose_transition = make_transition_section(nose_transition_length, thickness+2, slice_thickness, width, min_radius, number_of_segments); var tail_transition = mirror([1,0,0], make_transition_section(tail_transition_length, thickness+2, slice_thickness, width, min_radius, number_of_segments)); mold = mold.union(color([0.2,0.2,0.2],nose_transition.translate([concave_length/2+nose_transition_length,0,0]))); mold = mold.union(color([0.2,0.2,0.2],tail_transition.translate([-concave_length/2-tail_transition_length,0,0]))); } mold = mold.intersect(color([0.7,0.7,0.7], cube({size: [mold_length, mold_width, mold_height], center: true}).translate([(nose_transition_length-tail_transition_length)/2-offset,0,-mold_height/2]))); var bolt_pattern = make_bolt_pattern(bolt_pattern_length, bolt_pattern_width, -hole_depth, hole_diameter).translate([(bolt_pattern_length/2)+(wheelbase/2),0,0]); bolt_pattern = bolt_pattern.union(make_bolt_pattern(bolt_pattern_length, bolt_pattern_width, -hole_depth, hole_diameter).translate([-((bolt_pattern_length/2)+(wheelbase/2)),0,0])); var mDia = 0.5; //notch diameter var make_notches = parameters.make_notches; if (make_notches == true) { mold = mold.subtract(make_markers(mold_width, wheelbase, nose_length, tail_length, bolt_pattern_length, mDia, kick_gap, nose_transition_length, tail_transition_length)); } mold = mold.translate([0,0,mold_height]); var neg_mold_height = mold_height + negHeight; if (inverse == false) { var mold_copy = mold; mold = mold.union(color([0.4,0.4,0.4],(cube({size: ([mold_length+2.4, mold_width-2.02, mold_height])}).translate([-(mold_length+2.4)/2,-(mold_width-2.02)/2,0])).subtract(cube({size: [mold_length, mold_width, mold_height+mold_offset+2]}).translate([-mold_length/2,-mold_width/2,0])))); var clearance1 = cube({size: [2,(mold_width-(mold_width-2.02))/2,mold_height]}).translate([mold_length/2-0.02,(mold_width/2)-((mold_width-(mold_width-2.02))/2),0]); clearance1 = clearance1.union(cube({size: [2,(mold_width-(mold_width-2.02))/2,mold_height]}).translate([-(mold_length/2-0.02)-2,(mold_width/2)-((mold_width-(mold_width-2.02))/2),0])); var clearance2 = clearance1; clearance1 = mirror([0,1,0], clearance1); mold = mold.subtract(clearance1); mold = mold.subtract(clearance2); var logo = rotate([0,0,90],make_logo()).translate([mold_length/2+0.6,0,mold_height]); mold = mold.subtract(logo); //uncomment below for reference size //mold = mold.union(cube({size: [0.1,0.1,0.1], center: true}).translate([mold_length/2+0.05,0,mold_height+mold_offset+1])); } if (inverse == true) { mold = mold.intersect(cube({size: [mold_length-0.02, mold_width, mold_height]}).translate([-(mold_length-0.02)/2, -mold_width/2, 0])); mold = (color([0.4,0.4,0.4],cube({size: [mold_length-0.02, mold_width, neg_mold_height], center: true}).translate([0,0,(neg_mold_height)/2])).subtract(mold)); mold = rotate([180,0,0],mold); mold = mold.translate([0,0,neg_mold_height]); var slots = (color([0.4,0.4,0.4],(cube({size: ([1.1, mold_width, negHeight+1.5+mold_offset])}).translate([-(mold_length-0.02)/2-1.1,-(mold_width)/2,0])))); slots = slots.union(color([0.4,0.4,0.4],(cube({size: ([1.1, mold_width, negHeight+1.5+mold_offset])}).translate([((mold_length-0.02)/2),-(mold_width)/2,0])))); slots = color([0.4,0.4,0.4],slots.subtract(cube({size: [mold_length+3, mold_width-2, negHeight+2]}).translate([-(mold_length+3)/2, -(mold_width-2)/2,0]))); mold = mold.union(slots); } if (showTemplate == true) { if (show_profile == true) { var profile;// = (((make_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, 5)))); if (make_cutouts == false) { profile = make_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, 0.1).translate([shift,0,0]); } else { profile = make_lb_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, 0.1, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY).translate([shift,0,0]); } var mold = profile; //var skateboard = make_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, 0.1); } else { var depth = mold_height+10; var profile; if (make_cutouts == false) { profile = make_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, depth).translate([shift,0,0]); } else { profile = make_lb_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, depth, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY).translate([shift,0,0]); } mold = mold.intersect(profile);//(make_profile(deck_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, depth)); } } if (make_holes == true) { mold = mold.subtract(bolt_pattern); } return color([0.7,0.7,0.7],mold); } function make_markers(width, wheelbase, nose_length, tail_length, boltL, mDia, kick_gap, noseT, tailT) { var result = new CSG(); result = sphere({r: mDia/2, center: true}); result = result.translate([(wheelbase/2+boltL+kick_gap+((noseT-tailT)/2)),(width/2),0]); result = result.union(sphere({r: mDia/2, center: true}).translate([(wheelbase/2+boltL+kick_gap+((noseT-tailT)/2)),-(width/2),0])); result = result.union(sphere({r: mDia/2, center: true}).translate([-(wheelbase/2+boltL+kick_gap-((noseT-tailT)/2)),-(width/2),0])); result = result.union(sphere({r: mDia/2, center: true}).translate([-(wheelbase/2+boltL+kick_gap-((noseT-tailT)/2)),(width/2),0])); return result; } function make_concave(concave_radius, thickness, concave_length, width, flat_concave_length) { var result = new CSG(); if(concave_radius==0){ result = cube({size:[flat_concave_length,width,thickness]}); result = result.translate([-flat_concave_length/2,-width/2,-thickness]); return result; } else{ result = rotate([90,0,90],cylinder({r: concave_radius, h: concave_length, center: true, fn: 500})).translate([0,0,-concave_radius]); return result; /*result= difference( difference( difference( (rotate([90,0,90], difference( cylinder({r: (concave_radius + thickness), h: concave_length, center: true, fn: 100}), cylinder({r: concave_radius, h:concave_length+2, center: true, fn: 100}).translate([0,0,1]))) ).translate([-concave_length/2,0,concave_radius]), cube({size: [concave_length*2, concave_radius*4, concave_radius*4]}).translate([-concave_length, -concave_radius * 2 + 10, concave_radius]) ), cube({size: [concave_length*4, concave_radius*2, concave_radius*2], center: false}).translate([-concave_length*2, width/2, 0]) ), mirror([0,1,0], cube({size: [concave_length*4, concave_radius*2, concave_radius*2], center: false}).translate([-concave_length*2, width/2, 0])) ); return result.translate([concave_length/2,0,0]);*/ } } function make_bolt_pattern(bolt_pattern_length, bolt_pattern_width, hole_depth, hole_diameter) { var result = new CSG(); result = (cylinder({d: hole_diameter, h: hole_depth, center: false}).translate([bolt_pattern_length/2,bolt_pattern_width/2,0])).union(cylinder({d: hole_diameter, h: hole_depth, center: false}).translate([bolt_pattern_length/2,-bolt_pattern_width/2,0])); result = result.union(cylinder({d: hole_diameter, h: hole_depth, center: false}).translate([-bolt_pattern_length/2,-bolt_pattern_width/2,0])); result = result.union(cylinder({d: hole_diameter, h: hole_depth, center: false}).translate([-bolt_pattern_length/2,bolt_pattern_width/2,0])); result = result.translate([0,0,-hole_depth/2]); return result; } function make_kicknose_curve(kicknose_radius, width, kicknose_angle, nose_transition_length, concave_length, kicknose_length, mold_height) { var result = new CSG(); result = rotate([90,0,0],cylinder({r: kicknose_radius, h:width, center: false, fn: 500})); result = difference(result,cube({size: [kicknose_radius*2, width*4, kicknose_radius*4]}).translate([-kicknose_radius*2, -width*2, -kicknose_radius-2])) result = result.subtract((rotate([0,kicknose_angle,0], cube({size: [kicknose_length+kicknose_radius, width, kicknose_radius], center: false}).translate([0,-width,0])))); result = result.subtract(cube({size: [kicknose_radius+2,width,kicknose_radius], center: false}).translate([0,-width,-kicknose_radius])); // result = result.union(rotate([0,kicknose_angle,0],cube({size:[kicknose_length+10,width,kicknose_radius]})).translate([0,-width,0])); result = result.union(rotate([0,kicknose_angle,0],cube({size:[kicknose_length+10,width,kicknose_radius*4]}).translate([0,0,-kicknose_radius*3])).translate([0,-width,0])); // result = result.union(cube({size:[kicknose_length*2,width,mold_height], center: false}).translate([0,-width,-kicknose_radius-(mold_height/2)])); result = result.subtract(cube({size: ([kicknose_length*2,width*2,mold_height*4]), center: false}).translate([-kicknose_length*2,-width*1.5,-mold_height*4+kicknose_radius])); result = result.translate([(concave_length/2+nose_transition_length),width/2,-kicknose_radius]); // result = result.intersect((rotate([0,kicknose_angle,0], cube({size: [kicknose_length+10, width, kicknose_radius*4], center: false}))).translate([-(kicknose_length+10)/2,0,0])); //result = result.union((rotate([0,kicknose_angle,0], cube({size: [kicknose_length+10, width, kicknose_radius*2], center: false}))).translate([-(kicknose_length+10)/2,0,0])); return result; } function make_kicktail_curve(kicktail_radius, width, kicktail_angle, tail_transition_length, concave_length, kicktail_length, mold_height) { var result = new CSG(); result = rotate([90,0,0],cylinder({r: kicktail_radius, h:width, center: false, fn: 500})); result = difference(result,cube({size: [kicktail_radius*2, width*4, kicktail_radius*4]}).translate([-kicktail_radius*2, -width*2, -kicktail_radius-2])) result = result.subtract((rotate([0,kicktail_angle,0], cube({size: [kicktail_length+kicktail_radius, width, kicktail_radius], center: false}).translate([0,-width,0])))); result = result.subtract(cube({size: [kicktail_radius+2,width,kicktail_radius], center: false}).translate([0,-width,-kicktail_radius])); result = result.union(rotate([0,kicktail_angle,0],cube({size:[kicktail_length+10,width,kicktail_radius*4]}).translate([0,0,-kicktail_radius*3])).translate([0,-width,0])); result = result.subtract(cube({size: ([kicktail_length*2,width*2,mold_height*4]), center: false}).translate([-kicktail_length*2,-width*1.5,-mold_height*4+kicktail_radius])); result = mirror([1,0,0], result); result = result.translate([(-(concave_length/2+tail_transition_length)),width/2,-kicktail_radius]); //result = result.intersect((rotate([0,kicktail_angle,0], cube({size: [kicktail_length+10, width, kicktail_radius*4], center: false}))).translate([-(kicktail_length+10)/2,0,0])); //result = result.union((rotate([0,kicktail_angle,0], cube({size: [kicktail_length+10, width, kicktail_radius*2], center: false}))).translate([-(kicktail_length+10)/2,0,0])); return result; } function make_transition_section(transition_length, thickness, slice_thickness, width, min_radius, number_of_segments) { var result = new CSG(); var number_of_steps = transition_length/slice_thickness; var concave_depth = (2*min_radius-sqrt(pow(2*min_radius,2)-(4*1*pow(width,2)/4)))/(2*1); var mid_depth = concave_depth/2; var mid_radius = (pow(mid_depth,2)+(pow(width,2)/4))/(2*mid_depth); // var max_radius = pow(mid_radius,2); //if poor transition, uncomment the following and comment the above: var max_radius = 6*mid_radius; var correction = mid_radius; var radius_range = max_radius - min_radius; var radius_offset = min_radius; var sub_radius_range = (max_radius+thickness) - (min_radius+thickness); var sub_radius_offset = min_radius+thickness; //y values for edges of arc var normal_y = ((2*min_radius)-Math.sqrt(Math.pow(2*min_radius,2)-(4*Math.pow((width/2),2))))/(2); var flat_y = 0; //for start and end tangency, plot hollow cylindrical arcs as a sigmoid function... y = 1/(1+e^x). Adjust for the radius size (multiply by the range), then offset for the minimum (add min_radius) //1/16/21 EDIT: change to cubic Bezier curve // B(t) = [(1-t)^3]P0 + 3[(1-t)^2]tP1 + 3[(1-t)t^2]P2 + (t^3)P3 var i_range = 1; //range for t, which must be 0 <= t <= 1 var i_size = i_range/number_of_steps; //change in x value per change in step //console.log('# steps = ' +number_of_steps); //console.log('i_size = '+i_size); var origin_x = 0; var origin_y = 0; var a = 0; //initial t value of Bezier a = a+i_size; //prevent dividing by 0 var x0 = 0; var x1 = transition_length/4; var x2 = transition_length*(2/3); var x3 = transition_length; var y0 = 0; var y1 = 0; var y2 = concave_depth; var y3 = concave_depth; var slice_adj = 0; var x_val_last = 0; for (var i = a; i < (i_range+i_size); i=i+i_size) //starting at 0, going until 1, increment at i_size { /*if (i < 0) { var y_val = normal_y+((flat_y-normal_y)/(1+Math.exp(i*1.25))); } else { var y_val = normal_y+((flat_y-normal_y)/(1+Math.exp(i))); }*/ //(x - h)^2 + (y - k)^2 = R^2, where (h,k) is the center of the concave circle //we know h = 0, since it is in line with the bottom of the circle //we know two points: (0,0) and (width/2,y_val) //Two equations: //(0 - 0)^2 + (0 - k)^2 = R^2 // ---> k = R //(width/2 - 0)^2 + (y_val - R)^2 = R^2 //(width/2)^2 + y_val^2 - 2R*y_val = 0 //2R*y_val = (width/2)^2 + y_val^2 // 1/16/21 EDIT: Bezier curve: var t = i; var x_val = ((Math.pow((1-t),3))*x0)+(3*(Math.pow((1-t),2))*t*x1)+(3*((1-t))*Math.pow(t,2)*x2)+(Math.pow(t,3)*x3); var y_val = ((Math.pow((1-t),3))*y0)+(3*(Math.pow((1-t),2))*t*y1)+(3*((1-t))*Math.pow(t,2)*y2)+(Math.pow(t,3)*y3); var reg_radius = (Math.pow((width/2),2) + Math.pow(y_val,2))/(2*y_val); // console.log("reg_radius is "); //var reg_radius = radius_offset+(radius_range/(1+Math.exp(i))); var reg_half_angle = asin((width/2)/reg_radius); var reg_segment_angle = reg_half_angle/number_of_segments; //console.log("half angle is "); // console.log(reg_half_angle); result = result.union( linear_extrude({height: x_val-x_val_last, center: false}, polygon({ //currently set up for 20 segments per full arc: points: [ [(reg_radius*sin(reg_segment_angle*10)),(reg_radius*cos(reg_segment_angle*10))], [(reg_radius*sin(reg_segment_angle*9)),(reg_radius*cos(reg_segment_angle*9))], [(reg_radius*sin(reg_segment_angle*8)),(reg_radius*cos(reg_segment_angle*8))], [(reg_radius*sin(reg_segment_angle*7)),(reg_radius*cos(reg_segment_angle*7))], [(reg_radius*sin(reg_segment_angle*6)),(reg_radius*cos(reg_segment_angle*6))], [(reg_radius*sin(reg_segment_angle*5)),(reg_radius*cos(reg_segment_angle*5))], [(reg_radius*sin(reg_segment_angle*4)),(reg_radius*cos(reg_segment_angle*4))], [(reg_radius*sin(reg_segment_angle*3)),(reg_radius*cos(reg_segment_angle*3))], [(reg_radius*sin(reg_segment_angle*2)),(reg_radius*cos(reg_segment_angle*2))], [(reg_radius*sin(reg_segment_angle*1)),(reg_radius*cos(reg_segment_angle*1))], [(reg_radius*sin(reg_segment_angle*0)),(reg_radius*cos(reg_segment_angle*0))], [(reg_radius*sin(reg_segment_angle*0)),(reg_radius*cos(reg_segment_angle*0))-5], [(reg_radius*sin(reg_segment_angle*10)),(reg_radius*cos(reg_segment_angle*10))-5] ] })).translate([0,-reg_radius,x_val_last]) //each slice is slice_thickness wide, so move that much each time ); x_val_last = x_val; slice_adj = slice_adj + slice_thickness; //console.log("i is " + i); } result = result.union(mirror([1,0,0],result)); result = rotate([90,0,-90],result); result = result.translate([0,0,0]); return result; } function make_profile(width, wheelbase, boltL, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, depth) { var profile = new CSG.Path2D([[0,(width/2)],[(((wheelbase/2)+boltL+nose_length)-taperN),(width/2)]]); profile = profile.appendBezier([[((((wheelbase/2)+boltL+nose_length)-taperN)+(nose_shape*(taperN))),(width/2)],[((wheelbase/2)+boltL+nose_length),(nose_shape*(width/2))],[((wheelbase/2)+boltL+nose_length),0]], {resolution: 100}); profile = profile.appendBezier([[((wheelbase/2)+boltL+nose_length),(-(nose_shape*(width/2)))],[((((wheelbase/2)+boltL+nose_length)-taperN)+(nose_shape*(taperN))),(-(width/2))],[(((wheelbase/2)+boltL+nose_length)-taperN),(-(width/2))]], {resolution: 100}); profile = profile.appendPoint([0,(-(width/2))]); profile = profile.appendPoint([-(((wheelbase/2)+boltL+tail_length)-taperT),-(width/2)]); profile = profile.appendBezier([[-((((wheelbase/2)+boltL+tail_length)-taperT)+(tail_shape*(taperT))),-(width/2)],[-((wheelbase/2)+boltL+tail_length),-(tail_shape*(width/2))],[-((wheelbase/2)+boltL+tail_length),0]], {resolution: 100}); profile = profile.appendBezier([[-((wheelbase/2)+boltL+tail_length),((tail_shape*(width/2)))],[-((((wheelbase/2)+boltL+tail_length)-taperT)+(tail_shape*(taperT))),((width/2))],[-(((wheelbase/2)+boltL+tail_length)-taperT),((width/2))]], {resolution: 100}); profile = profile.appendPoint([0,(width/2)]); profile = profile.close(); var skateboard = profile.innerToCAG(); skateboard = linear_extrude({height: depth}, skateboard); return skateboard; } function make_lb_profile(width, wheelbase, boltL, nose_length, tail_length, length, taperN, taperT, depth, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY) { var res = 100; //resolution of bezier curves var profile = new CSG.Path2D([[0,(width/2)],[(((wheelbase/2)+boltL+nose_length)-taperN),(width/2)]]); profile = profile.appendBezier([[(noseLipX),(width/2)],[(noseLipX),(noseLipY)],[((wheelbase/2)+boltL+nose_length),(noseY)],[((wheelbase/2)+boltL+nose_length),0]], {resolution: res}); profile = profile.appendBezier([[((wheelbase/2)+boltL+nose_length),(-noseY)],[noseLipX,(-noseLipY)],[noseLipX,(-(width/2))],[(((wheelbase/2)+boltL+nose_length)-taperN),-(width/2)]], {resolution: res}); profile = profile.appendPoint([0,(-(width/2))]); profile = profile.appendPoint([-(((wheelbase/2)+boltL+tail_length)-taperT),-(width/2)]); profile = profile.appendBezier([[(-tailLipX),-(width/2)],[(-tailLipX),(-tailLipY)],[-(((wheelbase/2)+boltL+tail_length)),-(tailY)],[-(((wheelbase/2)+boltL+tail_length)),0]], {resolution: res}); profile = profile.appendBezier([[-(((wheelbase/2)+boltL+tail_length)),(tailY)],[-tailLipX,(tailLipY)],[-tailLipX,((width/2))],[-((((wheelbase/2)+boltL+tail_length))-taperT),(width/2)]], {resolution: res}); profile = profile.appendPoint([0,(width/2)]); profile = profile.close(); var skateboard = profile.innerToCAG(); skateboard = linear_extrude({height: depth}, skateboard); return skateboard; } function make_logo() { var cag0 = new CAG(); var cag1 = new CAG(); var cag2 = new CAG(); var cag3 = new CAG(); var cag20 = cag3; cag2 = cag2.union(cag20); var cag3 = new CAG(); var cag21 = cag3; cag2 = cag2.union(cag21); var cag3 = new CAG(); var cag30 = new CAG(); var cag301 = new CSG.Path2D([[272.73907,-885.95367]],false); cag301 = cag301.appendBezier([[265.95745000000005,-885.13183],[259.51701,-882.76426],[253.92006000000003,-879.0355999999999]]); cag301 = cag301.appendBezier([[241.10355000000004,-870.4972999999999],[233.81635000000003,-856.41487],[234.32472000000004,-841.1678499999999]]); cag301 = cag301.appendBezier([[234.59822000000005,-832.96485],[237.00109000000003,-825.3881499999999],[241.47632000000004,-818.61758]]); cag301 = cag301.appendBezier([[246.36129000000005,-811.2271],[253.20178000000004,-805.61239],[261.55103,-802.1401599999999]]); cag301 = cag301.appendBezier([[264.76976,-800.80158],[269.38961,-799.6299899999999],[273.15364000000005,-799.1977499999999]]); cag301 = cag301.appendBezier([[275.23095000000006,-798.95921],[280.60429000000005,-798.95921],[282.68160000000006,-799.1977499999999]]); cag301 = cag301.appendBezier([[301.1161400000001,-801.31468],[316.05948000000006,-814.5449699999999],[320.41098000000005,-832.6019799999999]]); cag301 = cag301.appendBezier([[321.69828000000007,-837.94373],[321.8970100000001,-844.4969899999999],[320.9390000000001,-850.0139699999999]]); cag301 = cag301.appendBezier([[318.86692000000005,-861.9467799999999],[311.97881000000007,-872.4241099999998],[301.8055100000001,-879.1174499999998]]); cag301 = cag301.appendBezier([[296.1110700000001,-882.8639899999998],[289.7736000000001,-885.1590499999999],[282.9032400000001,-885.9627099999999]]); cag301 = cag301.appendBezier([[280.4519000000001,-886.2494699999999],[275.1409900000001,-886.2447399999999],[272.7390700000001,-885.9537099999999]]); cag301 = cag301.close(); switch (cag301.getTurn()) { default: case "clockwise": cag301 = cag301.innerToCAG(); cag30 = cag30.union(cag301); break; case "counter-clockwise": cag301 = cag301.innerToCAG(); cag30 = cag30.subtract(cag301); break; } var cag302 = new CSG.Path2D([[255.63449,-851.00316]],false); cag302 = cag302.appendPoint([255.63449,-843.473]); cag302 = cag302.appendPoint([251.48519,-843.473]); cag302 = cag302.appendPoint([247.33593,-843.473]); cag302 = cag302.appendPoint([247.33593,-851.00316]); cag302 = cag302.appendPoint([247.33593,-858.53333]); cag302 = cag302.appendPoint([251.48519,-858.53333]); cag302 = cag302.appendPoint([255.63449,-858.53333]); cag302 = cag302.close(); switch (cag302.getTurn()) { default: case "clockwise": cag302 = cag302.innerToCAG(); cag30 = cag30.union(cag302); break; case "counter-clockwise": cag302 = cag302.innerToCAG(); cag30 = cag30.subtract(cag302); break; } var cag303 = new CSG.Path2D([[308.4993,-851.00316]],false); cag303 = cag303.appendPoint([308.4993,-843.473]); cag303 = cag303.appendPoint([304.35002000000003,-843.473]); cag303 = cag303.appendPoint([300.20076,-843.473]); cag303 = cag303.appendPoint([300.20076,-851.00316]); cag303 = cag303.appendPoint([300.20076,-858.53333]); cag303 = cag303.appendPoint([304.35002000000003,-858.53333]); cag303 = cag303.appendPoint([308.4993,-858.53333]); cag303 = cag303.close(); switch (cag303.getTurn()) { default: case "clockwise": cag303 = cag303.innerToCAG(); cag30 = cag30.union(cag303); break; case "counter-clockwise": cag303 = cag303.innerToCAG(); cag30 = cag30.subtract(cag303); break; } var cag304 = new CSG.Path2D([[297.43458,-850.9263599999999]],false); cag304 = cag304.appendPoint([297.43458,-847.16127]); cag304 = cag304.appendPoint([293.22109,-847.16127]); cag304 = cag304.appendPoint([289.00762000000003,-847.16127]); cag304 = cag304.appendPoint([285.8217,-844.43351]); cag304 = cag304.appendPoint([282.63577000000004,-841.70574]); cag304 = cag304.appendPoint([283.54233000000005,-841.59662]); cag304 = cag304.appendBezier([[284.04093000000006,-841.5366200000001],[285.8665500000001,-841.34099],[287.5992600000001,-841.16192]]); cag304 = cag304.appendBezier([[293.51664000000005,-840.55035],[299.6444400000001,-839.36307],[305.40607000000006,-837.71184]]); cag304 = cag304.appendBezier([[307.03138000000007,-837.2460500000001],[308.3922600000001,-836.8649300000001],[308.43025000000006,-836.8649300000001]]); cag304 = cag304.appendBezier([[308.46825000000007,-836.8649300000001],[308.49935000000005,-835.0669],[308.49935000000005,-832.86932]]); cag304 = cag304.appendBezier([[308.49935000000005,-830.67175],[308.4444500000001,-828.87373],[308.37725000000006,-828.87373]]); cag304 = cag304.appendBezier([[308.31005000000005,-828.87373],[306.90970000000004,-829.31683],[305.26529000000005,-829.85839]]); cag304 = cag304.appendBezier([[287.52269000000007,-835.70163],[268.38804000000005,-835.7007199999999],[250.56528000000006,-829.8553899999999]]); cag304 = cag304.appendBezier([[248.91825000000006,-829.3152399999999],[247.51786000000007,-828.8733199999999],[247.45333000000005,-828.8733199999999]]); cag304 = cag304.appendBezier([[247.38883000000004,-828.8733199999999],[247.33598000000006,-830.66086],[247.33598000000006,-832.84565]]); cag304 = cag304.appendPoint([247.33598000000006,-836.81797]); cag304 = cag304.appendPoint([250.67844000000005,-837.76284]); cag304 = cag304.appendBezier([[256.66209000000003,-839.4543],[262.38624000000004,-840.56304],[268.23603,-841.16363]]); cag304 = cag304.appendBezier([[269.96873000000005,-841.34153],[271.79176,-841.53619],[272.28718000000003,-841.5962000000001]]); cag304 = cag304.appendPoint([273.18795000000006,-841.7053300000001]); cag304 = cag304.appendPoint([270.0222800000001,-844.4330900000001]); cag304 = cag304.appendPoint([266.85660000000007,-847.1608500000001]); cag304 = cag304.appendPoint([262.6286600000001,-847.1608500000001]); cag304 = cag304.appendPoint([258.40071000000006,-847.1608500000001]); cag304 = cag304.appendPoint([258.40071000000006,-850.9259300000001]); cag304 = cag304.appendPoint([258.40071000000006,-854.6910200000001]); cag304 = cag304.appendPoint([277.91767000000004,-854.6910200000001]); cag304 = cag304.appendPoint([297.43463,-854.6910200000001]); cag304 = cag304.close(); switch (cag304.getTurn()) { default: case "clockwise": cag304 = cag304.innerToCAG(); cag30 = cag30.union(cag304); break; case "counter-clockwise": cag304 = cag304.innerToCAG(); cag30 = cag30.subtract(cag304); break; } cag3 = cag3.union(cag30); var cag22 = cag3; cag22 = cag22.translate([37.375645,-55.558391]); cag2 = cag2.union(cag22); var cag10 = cag2; cag1 = cag1.union(cag10); var cag00 = cag1; cag0 = cag0.union(cag00); cag0 = scale(0.01,cag0); var solid = linear_extrude({height: 10, center: true}, cag0); solid = cube({size: [20,20,0.2], center: true}).subtract(solid); return solid; }

Fingerboard length: mm

Length = Wheelbase + Nose Length + Tail Length +
(Hole Pattern Length x 2)

...

Two-piece Fingerboard Mold

$39.95

Your specs:
*Size and color varies

Your mold will be made to produce the board you just designed. Use this to press five 1/42" veneers into a deck.


Template

$19.95

Your template:
*Size and color varies

Your template will be made to the board shape you designed. Use this to trace your board shape on the pressed veneers.


Veneers

40mm x 115mm x 0.6mm (1.57" x 4.72" x 1/42") maple veneer

Pack Size

Each set contains 3 vertical grain veneers and 2 cross grain veneers. Contact us for larger quantities.


Fingerboard Parts Kit

Each set includes 2 trucks (30mm), 4 wheels, 8 screws, and tool. *Colors vary*

Kit Size
*Colors vary

Each fingerboard parts kit comes with the parts you need to assemble a complete fingerboard. Grip tape is not included.


3D Printed Fingerboard (Deck Only)

$9.95

Your Board:
*Color varies

For bulk pricing or special requests, please contact us.