//NOTE: DO NOT EDIT THIS CODE IF YOU ARE PLACING AN ORDER. // OUR SYSTEM WILL NOT SEE YOUR UPDATES. // IF YOU NEED A CUSTOM ORDER, PLEASE CONTACT US. // title : Strawberry - LB // author : Beau Trifiro // license : Copyright 2020, Open Source Skateboards // description: Longboard customizer // version : 0.1.1 - added molds, rearranged wheelbase and profile operations // : 0.1.0 // last edit : 6/24/22 include('jscad/barracuda.js'); include('jscad/mroz.js'); include('jscad/rockerFlare.js'); include('jscad/spark.js'); include('jscad/tribute.js'); include('jscad/flowstylev2.js'); include('jscad/medtub.js'); function getParameterDefinitions() { return ([ { name: 'mold', type: 'choice', caption: 'Select <a href="https://v1.opensourceboards.com/molds.html" target="_blank" class="paramLink">Mold<a>', values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], captions: ['None - Flat', '1) Asymm. - Small (13-16-11A22-05)', '2) Asymm. - Mid (14-23-16A19-06A08)', '3) Freestyle - Ouija (14-20-21-05)', '4) Freestyle - SF (14-34-15-06)', '5) Freestyle - Sweden (14-62-14-09)', '6) Freestyle - RadRat (14-33-18-10)', '7) Mellow Symmetrical (14-20-18-09)', '8) Medium Symmetrical (14-20-20-05)', '9) Mellow/Medium Symm. (14-20-19-06)', '10) Steep Symm. 21 (14-18-21-05)', '11) Shark (15-19-20-09)', '12) XL Medium (16-25-20-09)', '13) Mellow Single Kick (X-45-0A12-09)', '14) Steep Single Kick (X-85-0A20-08)', '15) Rocker/Flare (15-24F19-18-05-R25)', '16) Steep Asymm. M (14-21-16A20-08A06)', '17) Steep Symm. 22 (22 14-17-22-06)', '18) Flat Single Kick (X-0-0A20-05)', '19) Medium Asymm. (14-28-20A22-06A07)', '20) Mooky (15-24-23A21-07A06)', '21) Steep Asymm. L (15-18-22A21-05)', '22) Big Mellow (18-31-05A10-06)', '23) Barracuda (18-27F15-20-09)', '24) Dancer (31-54-12-05)', '25) Small Freestyle (12-22-10A20-06)', '26) Mellow Asymm. (14-36-21A20-07A05)', '27) Tiny Dancer (12-17-20-05)', '28) The Mroz', '29) The OSS Original (14-20-20-09)', '30) The Spark (13-26-19*-04*)', '31) Tribute (14-20-20-04)', '32) Flowstyle V2', '33) Medium Tub (14-17T-19-05)' ], initial: 0}, //{ name: 'profile', type: 'checkbox', checked: false, caption: 'Show Profile, Only'}, { name: 'width', type: 'float', initial: 9.5, step: 0.0625, max: 11, min: 6, caption: 'Width, inches'}, { name: 'wheelbase', type: 'float', initial: 30.0, step: 0.125, caption: 'Wheelbase, inches'}, { name: 'nose_length', type: 'float', initial: 5.75, step: 0.125, min: 1, max: 7.25, caption: 'Nose Length, inches'}, { name: 'tail_length', type: 'float', initial: 5.75, step: 0.125, min: 1, max: 7.25, caption: 'Tail Length, inches'}, //{ name: 'concave_drop', type: 'float', initial: 0.375, step: 0.0625, max: 0.75, min: 0.0, caption: 'Concave Drop, in.'}, // concave_radius=0, make flat board //{ name: 'kicknose_angle', type: 'float', initial: 20.0, min: 0, max: 25, caption: 'Kicknose, deg.'}, //{ name: 'kicktail_angle', type: 'float', initial: 20.0, min: 0, max: 25, caption: 'Kicktail, deg.'}, //{ name: 'nose_radius', type: 'float', initial: 9, step: 1, max: 20, min: 5, caption: 'Nose Radius, in.'}, //{ name: 'tail_radius', type: 'float', initial: 9, step: 1, max: 20, min: 5, caption: 'Tail Radius, in.'}, // { name: 'kick_gap', type: 'float', initial: 1, step: 0.125, max: 3, min: 0, caption: 'Kick Gap'}, { name: 'taperN', type: 'float', initial: 15, step: 0.125, caption: 'Nose Taper Point, in.'}, { name: 'taperT', type: 'float', initial: 15, step: 0.125, caption: 'Tail Taper Point, in.'}, { name: 'nose_adjust', type: 'slider', class: 'paramSlider tipShapes', min: 50, max: 100, initial: 70, step: 1, caption: '<span class="tipShapes">Nose Shape</span>'}, { name: 'tail_adjust', type: 'slider', class: 'paramSlider tipShapes', min: 50, max: 100, initial: 75, step: 1, caption: '<span class="tipShapes">Tail Shape</span>'}, { name: 'shift', type: 'float', class: 'shiftSpecs', initial: 0.875, step: 0.125, caption: '<span class="shiftSpecs">Tail Kick Gap, in.<br>(Single kick molds only!)</span>'}, { name: 'cutout_specs', caption: '<hr> <span class="category"> <a href="imgs/board_reference.pdf" target="_blank" class="paramLink">Wheel Cutouts</a> </span>', type: 'group'}, { name: 'make_cutouts', type: 'checkbox', checked: true, caption: 'Make Cutouts'}, { name: 'noseLipX', type: 'slider', class: 'paramSlider cutoutSpecs', min: 5, max: 18, step: 0.25, initial: 14, caption: '<span class="cutoutSpecs">Nose Cutout Depth</span>'}, { name: 'noseLipY', type: 'slider', class: 'paramSlider cutoutSpecs', min: -2, max: 4, step: 0.25, initial: 1, caption: '<span class="cutoutSpecs">Nose Cutout Width</span>'}, { name: 'noseY', type: 'slider', class: 'paramSlider cutoutSpecs', min: 2, max: 9, initial: 6, step: 0.25, caption: '<span class="cutoutSpecs">Nose Width</span>'}, { name: 'tailLipX', type: 'slider', class: 'paramSlider cutoutSpecs', min: 5, max: 18, step: 0.25, initial: 14, caption: '<span class="cutoutSpecs">Tail Cutout Depth</span>'}, { name: 'tailLipY', type: 'slider', class: 'paramSlider cutoutSpecs', min: -2, max: 4, step: 0.25, initial: 1, caption: '<span class="cutoutSpecs">Tail Cutout Width</span>'}, { name: 'tailY', type: 'slider', class: 'paramSlider cutoutSpecs', min: 2, max: 9, initial: 6, step: 0.25, caption: '<span class="cutoutSpecs">Tail Width</span>'}, { name: 'showLabels', type: 'checkbox', checked: false, class: 'cutoutSpecs', caption: '<span class="cutoutSpecs">Show Labels?</span>'} ]); } /* 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 mold = parameters.mold; var showLabels = parameters.showLabels; // var showProfile = parameters.profile; // var width_mod = 0.5; var width = parameters.width;//+width_mod; var wheelbase = parameters.wheelbase; //var concave_drop// = parameters.concave_drop; var concave_radius// = (Math.pow((width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop); var tail_length = parameters.tail_length; var nose_length = parameters.nose_length; var kicknose_angle// = parameters.kicknose_angle; var kicktail_angle// = parameters.kicktail_angle; var nose_shape = parameters.nose_adjust/100; var tail_shape = parameters.tail_adjust/100; var tail_kick_gap = parameters.shift; //to set tail kick gap var taperN = parameters.taperN; var taperT = parameters.taperT; var kicknose_radius; var kicktail_radius; var thickness = 0.4375; var bolt_pattern_width = 1.625; var bolt_pattern_length = 2.125; var nose_transition_length; var tail_transition_length; var make_cutouts = parameters.make_cutouts; var noseLipX = parameters.noseLipX; var noseLipY = parameters.noseLipY; var noseY = parameters.noseY; var tailLipX = parameters.tailLipX; var tailLipY = parameters.tailLipY; var tailY = parameters.tailY; var currentKG; //for single kick molds, before profile shift var shift = 0; //for single kick molds switch (mold) { case '0': kick_to_kick = 21; //placeholder, not used break; case '1': //13-16-11A22-05 concave_radius = 16.25; kicknose_angle = 11; kicktail_angle = 22; nose_transition_length = 4.75; tail_transition_length = 4.75; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 19.25; break; case '2': //asymmetrical - mid 14-23-16A19-06A08 concave_radius = 22.875; kicknose_angle = 16; kicktail_angle = 19; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 8; kick_to_kick = 20.25; break; case '3': //14-20-21-05 concave_radius = 20; kicknose_angle = 21; kicktail_angle = 21; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20.375; break; case '4': //14-34-15-06 concave_radius = 34; kicknose_angle = 15; kicktail_angle = 15; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 19.5; break; case '5': //14-62-14-09 concave_radius = 62; kicknose_angle = 14; kicktail_angle = 14; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 20.25; break; case '6': //14-33-18-10 concave_radius = 33; kicknose_angle = 18; kicktail_angle = 18; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 10; kicktail_radius = 10; kick_to_kick = 20.25; break; case '7': //14-20-18-09 concave_radius = 20; kicknose_angle = 18; kicktail_angle = 18; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 20.25; break; case '8': //14-20-20-05 --updated from 14-20-20-09 concave_radius = 20; kicknose_angle = 20; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20.25; break; case '9': //medium 14-20-19-06 concave_radius = 20; kicknose_angle = 19; kicktail_angle = 19; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 20.25; break; case '10': //14-18-21-05 concave_radius = 18; kicknose_angle = 21; kicktail_angle = 21; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 21.125; break; case '11': //big medium (hammerhead) 15-19-20-09 concave_radius = 19; kicknose_angle = 20; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 21.25; break; case '12': //XL medium 16-25-20-09 concave_radius = 25; kicknose_angle = 20; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 22.25; break; case '13': //mellow single kick X-45-0A12-09 concave_radius = 45.25; kicknose_angle = 0; kicktail_angle = 12; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 20; currentKG = (kick_to_kick-wheelbase-(2*bolt_pattern_length))/2; shift = tail_kick_gap - currentKG; console.log('shift value is '+shift); break; case '14': //steep single kick X-85-0A20-08 concave_radius = 85; kicknose_angle = 0; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 8; kicktail_radius = 8; kick_to_kick = 20; currentKG = (kick_to_kick-wheelbase-(2*bolt_pattern_length))/2; shift = tail_kick_gap - currentKG; console.log('shift value is '+shift); break; case '15': //15-24F19-18-05-R25 ignore the following specs (see imported model) concave_radius = 21; kicknose_angle = 19; kicktail_angle = 19; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20.75; break; case '16': //asymmetrical mid, steep 14-21-16A20-08A06 concave_radius = 20.5; kicknose_angle = 16; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 8; kicktail_radius = 6; kick_to_kick = 20.625; break; case '17': //symmetrical 22 14-17-22-06 concave_radius = 16.8; kicknose_angle = 22; kicktail_angle = 22; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 20.25; break; case '18': //flat single kick X-0-0A20-05 concave_radius = 0; kicknose_angle = 0; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20; currentKG = (kick_to_kick-wheelbase-(2*bolt_pattern_length))/2; shift = tail_kick_gap - currentKG; break; case '19': //short steep asymmetrical 14-28-20A22-06A07 concave_radius = 27.5; kicknose_angle = 20; kicktail_angle = 22; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 7; kick_to_kick = 20; break; case '20': //"Mooky" 15-24-23A21-07A06 concave_radius = 24.1; kicknose_angle = 23; kicktail_angle = 21; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 7; kicktail_radius = 6; kick_to_kick = 21.25; break; case '21': // steep asymmetrical 15-18-22A21-05 concave_radius = 18; kicknose_angle = 22; kicktail_angle = 21; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20.75; break; case '22': //Big Mellow (18-31-05A10-06) concave_radius = 31.5; kicknose_angle = 5; kicktail_angle = 10; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 23.75; break; case '23': //Barracuda (18-27F15-20-09) concave_radius = 18; kicknose_angle = 5; kicktail_angle = 10; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 24.25; break; case '24': //Dancer (31-54-12-05) concave_radius = 54; kicknose_angle = 12; kicktail_angle = 12; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 37.25; break; case '25': //Small FS (12-22-10A20-06) concave_radius = 22; kicknose_angle = 10; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 6; kicktail_radius = 6; kick_to_kick = 18.25; break; case '26': //mellow asymm (14-36-21A20-07A05) concave_radius = 36.25; kicknose_angle = 21; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 7; kicktail_radius = 5; kick_to_kick = 20.375; break; case '27': //tiny dancer (12-17-19-05) concave_radius = 16.63; kicknose_angle = 19; kicktail_angle = 19; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 18.25; break; case '28': //Mroz ignore the following specs (see imported model) concave_radius = 29; kicknose_angle = 18; kicktail_angle = 18; nose_transition_length = 4.25; tail_transition_length = 4.25; kicknose_radius = 8; kicktail_radius = 8; kick_to_kick = 13+4.25+2; break; case '29': //14-20-20-09 --Original Mold #1 concave_radius = 20; kicknose_angle = 20; kicktail_angle = 20; nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = 9; kicktail_radius = 9; kick_to_kick = 20.25; break; case '30': // The Spark - use imported model concave_radius = 26; kicknose_angle = 19; kicktail_angle = 19; nose_transition_length = 3.75; tail_transition_length = 3.75; kicknose_radius = 4; kicktail_radius = 4; kick_to_kick = 19; break; case '31': // Tribute - use imported model concave_radius = 20; kicknose_angle = 20; kicktail_angle = 20; nose_transition_length = 3.75; tail_transition_length = 3.75; kicknose_radius = 4; kicktail_radius = 4; kick_to_kick = 20; break; case '32': // Flowstyle V2 - use imported model concave_radius = 19; kicknose_angle = 18; kicktail_angle = 18; nose_transition_length = 2.75; tail_transition_length = 2.75; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20.25; break; case '33': // MedTub - use imported model concave_radius = 17; kicknose_angle = 19; kicktail_angle = 19; nose_transition_length = 3.75; tail_transition_length = 3.75; kicknose_radius = 5; kicktail_radius = 5; kick_to_kick = 20; break; } /*nose_transition_length = 4; tail_transition_length = 4; kicknose_radius = parameters.nose_radius; kicktail_radius = parameters.tail_radius; var kick_gap = parseFloat(parameters.kick_gap); kick_to_kick = wheelbase + (2*bolt_pattern_length)+ (2*kick_gap); console.log(kick_to_kick); */ var kick_gap = 1; var kicknose_length = (wheelbase/2) + bolt_pattern_length + nose_length - (kick_to_kick/2); var kicktail_length = (wheelbase/2) + bolt_pattern_length + tail_length - (kick_to_kick/2); var slice_thickness = 0.25; 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; var depth = .4375; if (mold == 0) { if (make_cutouts == false) { skateboard = make_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, depth); } else { skateboard = make_lb_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, depth, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY); } skateboard = skateboard.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase).translate([shift,0,0])); } else { if (mold == 15) { skateboard = rotate([0,0,90],makeRockerFlare()).translate([0,0,0.5]); } else if (mold == 23) { //Barracuda skateboard = makeBarracuda().translate([0,0,0.5]); } else if (mold == 28) { //Mroz skateboard = makeMroz().translate([0,0,0.5]); } else if (mold == 30) { //Spark skateboard = makeSpark().translate([0,0,4]); } else if (mold == 31) { //Tribute skateboard = makeTribute().translate([0,0,4]); } else if (mold == 32) { //FlowstyleV2 skateboard = rotate([0,0,90],makeFlowstyleV2().translate([0,0,4])); } else if (mold == 33) { //MedTub skateboard = makeMedTub().translate([0,0,4]); } else { var skateboard = make_concave(concave_radius, thickness, concave_length, width,flat_concave_length).translate([0,0,thickness]); if (kicknose_angle !== 0) { skateboard = skateboard.union(make_kicknose_curve(kicknose_radius, thickness, width, kicknose_angle, nose_transition_length, concave_length)); } else { skateboard = skateboard.union(make_concave(concave_radius, thickness, concave_length, width,flat_concave_length).translate([concave_length,0,thickness])); } if (kicktail_angle !== 0) { skateboard = skateboard.union(make_kicktail_curve(kicktail_radius, thickness, width, kicktail_angle, tail_transition_length, concave_length)); } else { skateboard = skateboard.union(make_concave(concave_radius, thickness, concave_length, width,flat_concave_length).translate([-concave_length,0,thickness])); } if (kicknose_angle !== 0) { skateboard = skateboard.union(make_kicknose_section(wheelbase, bolt_pattern_length, nose_length, kicknose_length, kicknose_radius_length, width, kicknose_radius_height, thickness, kicknose_angle, nose_transition_length, concave_length)); } if (kicktail_angle !== 0) { skateboard = skateboard.union(make_kicktail_section(wheelbase, bolt_pattern_length, tail_length, kicktail_length, kicktail_radius_length, width, kicktail_radius_height, thickness, kicktail_angle, tail_transition_length, concave_length)); } skateboard = color([0,0.99,0],skateboard); if (concave_radius!==0) { if (kicknose_angle !== 0) { skateboard = skateboard.union( ((rotate([0,0,90], make_transition_section(nose_transition_length, thickness, slice_thickness, width, min_radius, number_of_segments, mold)))).translate([concave_length/2+nose_transition_length,0,0])); } if (kicktail_angle !== 0) { skateboard = skateboard.union( ((rotate([0,0,-90], make_transition_section(tail_transition_length, thickness, slice_thickness, width, min_radius, number_of_segments, mold)))).translate([-(concave_length/2+tail_transition_length),0,0])); } } } skateboard = skateboard.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase).translate([shift,0,0])); var profile; if (make_cutouts == false) { profile = make_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, 10).translate([shift,0,0]); } else { profile = make_lb_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, 10, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY).translate([shift,0,0]); } skateboard = skateboard.intersect(profile); } if (make_cutouts == false) { skateboard = color([0,0.95,0],skateboard); } else { skateboard = color([0,0.95,0.95],skateboard); if (showLabels == true) { skateboard = skateboard.setColor([0.2,0.8,0.95,0.5]); var taperNLabel = createMarker("nose taper", (length/2-taperN), width/2, (length/2-taperN), (width/2+1),[0,0.7,0]); var taperTLabel = createMarker("tail taper", -(length/2-taperT), -width/2, -(length/2-taperT), -(width/2+1),[1,0,0]); var noseYLabel = createMarker("nose width", (wheelbase/2+bolt_pattern_length+nose_length), 0, (wheelbase/2+bolt_pattern_length+nose_length)+0.5, 0, [0, 0.7, 0]); var tailYLabel = createMarker("tail width", -(wheelbase/2+bolt_pattern_length+tail_length), 0, -((wheelbase/2+bolt_pattern_length+tail_length)+3), 0, [1,0,0]); var noseLipXLabel = createMarker("nose cutout depth", noseLipX, width/2, noseLipX, (width/2+1),[0,0.7,0]); var noseLipYLabel = createMarker("nose cutout width", noseLipX, noseLipY, noseLipX, (noseLipY),[0,0.7,0]); var tailLipXLabel = createMarker("tail cutout depth", -tailLipX, -width/2, -tailLipX, -width/2, [1,0,0]); var tailLipYLabel = createMarker("tail cutout width", -tailLipX, -tailLipY, -tailLipX, -(tailLipY), [1,0,0]); var tailYLine = cube({size: [0.25,tailY,3], center: true}).setColor([1,0,0]).translate([-(wheelbase/2+bolt_pattern_length+tail_length),0,0]); var noseYLine = cube({size: [0.25,noseY,3], center: true}).setColor([0,0.7,0]).translate([(wheelbase/2+bolt_pattern_length+nose_length),0,0]); skateboard = skateboard.union(tailYLine); skateboard = skateboard.union(noseYLine); skateboard = skateboard.union(taperNLabel); skateboard = skateboard.union(taperTLabel); skateboard = skateboard.union(noseYLabel); skateboard = skateboard.union(tailYLabel); skateboard = skateboard.union(noseLipXLabel); skateboard = skateboard.union(noseLipYLabel); skateboard = skateboard.union(tailLipXLabel); skateboard = skateboard.union(tailLipYLabel); } } return color([1,0.99,0.99],skateboard); } function createMarker(text,x,y,labelX,labelY,color) { var pointRad = 0.25; var pointDepth = 1.1; var markerText = vector_text(0, 0, text); var markerLabel = (csgFromSegments(markerText).translate([labelX,labelY,0])).setColor(color); var markerPoint = cylinder({r: pointRad, h: pointDepth, center: false}).translate([x,y,0]).setColor(color); markerLabel = markerLabel.union(markerPoint); return markerLabel; } function csgFromSegments (segments) { let output = []; segments.forEach(segment => output.push( rectangular_extrude(segment, { w: 4, h: 2 }) )); return (union(output).scale(0.03125)).translate([0,0,1]); } function make_origin(origin) { var result = new CSG(); var height = 20; result = union( cylinder({d: 0.25, h: height, center: true}).translate([0,0,height/2]), union( rotate([-90,0,0],cylinder({d: 0.25, h: height, center: true}).translate([0,0,height/2])), rotate([0,90,0],cylinder({d: 0.25, h: height, center: true}).translate([0,0,height/2])) ) ); return result; } function make_bolt_pattern(bolt_pattern_length, bolt_pattern_width) { var result = new CSG(); result = (cylinder({d: 0.1875, h: 6, center: false}).translate([bolt_pattern_length/2,bolt_pattern_width/2,0])).union(cylinder({d: 0.1875, h: 6, center: false}).translate([bolt_pattern_length/2,-bolt_pattern_width/2,0])); result = result.union(cylinder({d: 0.1875, h: 6, center: false}).translate([-bolt_pattern_length/2,-bolt_pattern_width/2,0])); result = result.union(cylinder({d: 0.1875, h: 6, center: false}).translate([-bolt_pattern_length/2,bolt_pattern_width/2,0])); return result; } function make_wheelbase(bolt_pattern_length, bolt_pattern_width, wheelbase) { var result = new CSG(); result = (make_bolt_pattern(bolt_pattern_length,bolt_pattern_width).translate([(wheelbase/2)+(bolt_pattern_length/2),0,-1])).union(make_bolt_pattern(bolt_pattern_length,bolt_pattern_width).translate([-((wheelbase/2)+(bolt_pattern_length/2)),0,-1])); 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= difference( difference( difference( (rotate([90,0,90], difference( cylinder({r: (concave_radius + thickness), h: concave_length, center: true, fn: 300}), cylinder({r: concave_radius, h:concave_length+2, center: true, fn: 300}).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_kicknose_curve(kicknose_radius, thickness, width, kicknose_angle, nose_transition_length, concave_length) { var result = new CSG(); result = difference( difference( rotate([90,0,90], difference( cylinder({r: kicknose_radius+thickness, h: width, center: false, fn: 100}), cylinder({r: kicknose_radius, h: width+2, center: false, fn: 100}).translate([0,0,-1]) )), rotate([0,0,90], cube({size: [kicknose_radius*2, width*4, kicknose_radius*4], center: false}).translate([-kicknose_radius*2, -width*2, -kicknose_radius-2]) )), mirror([1,0,0], rotate([0, kicknose_angle, -90], cube({size: [kicknose_radius*2, width*4, kicknose_radius*4], center: false}).translate([-kicknose_radius*2, -width*2, -kicknose_radius*2]))) ).translate([0,0,kicknose_radius+thickness]); result = rotate([0,0,-90],(result.translate([-width/2,0,0]))); result = result.translate([concave_length/2+nose_transition_length,0,0]); return result; } function make_kicktail_curve(kicktail_radius, thickness, width, kicktail_angle, tail_transition_length, concave_length) { var result = new CSG(); result = mirror([0,1,0], difference( difference( rotate([90,0,90], difference( cylinder({r: kicktail_radius+thickness, h: width, center: false, fn: 100}), cylinder({r: kicktail_radius, h: width+2, center: false, fn: 100}).translate([0,0,-1]) )), rotate([0,0,90], cube({size: [kicktail_radius*2, width*4, kicktail_radius*4], center: false}).translate([-kicktail_radius*2, -width*2, -kicktail_radius-2]) )), mirror([1,0,0], rotate([0, kicktail_angle, -90], cube({size: [kicktail_radius*2, width*4, kicktail_radius*4], center: false}).translate([-kicktail_radius*2, -width*2, -kicktail_radius*2]))) ).translate([0,0,kicktail_radius+thickness]) ); result = rotate([0,0,-90],(result.translate([-width/2,0,0]))); result = result.translate([-concave_length/2-tail_transition_length,0,0]); return result; } function make_kicknose_section(wheelbase, bolt_pattern_length, nose_length, kicknose_length, kicknose_radius_length, width, kicknose_radius_height, thickness, kicknose_angle, nose_transition_length, concave_length) { var result = new CSG(); result = mirror([0,0,1], cube({size: [kicknose_length+3, width, thickness]})); result = rotate([0,-kicknose_angle,0],result); result = result.translate([concave_length/2+nose_transition_length+kicknose_radius_length,-width/2,kicknose_radius_height+thickness]); return result; } function make_kicktail_section(wheelbase, bolt_pattern_length, tail_length, kicktail_length, kicktail_radius_length, width, kicktail_radius_height, thickness, kicktail_angle, tail_transition_length, concave_length) { var result = new CSG(); result = mirror([0,0,1], cube({size: [kicktail_length+3, width, thickness]})); result = rotate([0,-kicktail_angle,0],result); result = mirror([1,0,0], result); result = result.translate([-(concave_length/2+tail_transition_length+kicktail_radius_length),-width/2,kicktail_radius_height+thickness]); return result; } function make_transition_section(transition_length, thickness, slice_thickness, width, min_radius, number_of_segments, mold) { 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); //concave depth var flat_y = 0; //no concave //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 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=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))); } */ // 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); console.log(x_val + ',' + y_val); var reg_radius = (Math.pow((width/2),2) + Math.pow(y_val,2))/(2*y_val); var reg_half_angle = asin((width/2)/reg_radius); var reg_segment_angle = reg_half_angle/number_of_segments; var sub_radius = reg_radius+thickness; var sub_half_angle = asin((width/2)/sub_radius); var sub_segment_angle = sub_half_angle/number_of_segments; result = result.union( linear_extrude({height: x_val-x_val_last, center: false}, polygon({ //currently set up for 20 segments per full arc: points: [ [(sub_radius*sin(sub_segment_angle*0)),(sub_radius*cos(sub_segment_angle*0))], [(sub_radius*sin(sub_segment_angle*1)),(sub_radius*cos(sub_segment_angle*1))], [(sub_radius*sin(sub_segment_angle*2)),(sub_radius*cos(sub_segment_angle*2))], [(sub_radius*sin(sub_segment_angle*3)),(sub_radius*cos(sub_segment_angle*3))], [(sub_radius*sin(sub_segment_angle*4)),(sub_radius*cos(sub_segment_angle*4))], [(sub_radius*sin(sub_segment_angle*5)),(sub_radius*cos(sub_segment_angle*5))], [(sub_radius*sin(sub_segment_angle*6)),(sub_radius*cos(sub_segment_angle*6))], [(sub_radius*sin(sub_segment_angle*7)),(sub_radius*cos(sub_segment_angle*7))], [(sub_radius*sin(sub_segment_angle*8)),(sub_radius*cos(sub_segment_angle*8))], [(sub_radius*sin(sub_segment_angle*9)),(sub_radius*cos(sub_segment_angle*9))], [(sub_radius*sin(sub_segment_angle*10)),(sub_radius*cos(sub_segment_angle*10))], [(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))] ] })).translate([0,-sub_radius,x_val_last]) ); x_val_last = x_val; slice_adj = slice_adj + slice_thickness; } result = result.union(mirror([1,0,0],result)); result = rotate([-90,0,0],result); if (mold == 13 || mold == 14) { result = color([0,0.95,0],result); } else { result = color([0,0.99,0],result); } 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); skateboard = color([0,0.99,0],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; }

Need some help getting started?
Check out the SK8CAD "cookbook" for some board recipes.

Kicknose angle: ° || Kicktail Angle: °
Kicknose radius: " || Kicktail Radius: "
Concave drop: "
Note: Concave drop is measured before rounding the edges of your board,
so it will likely be slightly less than what's shown here.

Intended wheelbase: " (with 1" kick gap)
Kick gap: "
Overall length: "

Skateboard Deck

Sheet of grip tape - black Jessup

Size

See our work on Instagram: @opensourceboards

Default construction: sustainably-sourced 1/16" maple veneers with PVA (water-based/non-toxic) glue. Boards are built in San Diego, CA. Boards come blank, but a graphic can be added (see below).

Boards are built to-order and ship in approximately 1-2 weeks. Economy shipping is default (5-7 business days domestic / 6-10 business days international). International customers: Please contact us for a shipping quote to place your order.

If you'd like additional customization - laser engraving, larger order quantities, alternative materials, graphics, expediting, etc. please contact us.

Price breaks are at the following sizes:
Up to 8.75" x 33"
8.76"-11" x 33.1"-45"
Larger sizes are possible, please contact us with your specs.

Quality guarantee - boards are guaranteed against manufacturing defects. Please contact us within 10 days of receiving your board if you believe it has a manufacturing issue for a full refund or credit. NOTE: Open Source Skateboards is not liable for any injuries from riding a board or breaking a board - please skate safe.

Humans work here! To talk to a real person, please contact us.