//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 : SK8CAD - Chocolate Chip (Vanilla Mod)
// author : Beau Trifiro
// license : Copyright 2020 - present, Open Source Skateboards
// description: Skateboard and two-sided mold customizer
// last edit : 23 June 2022
// filename : chocolate-chip-0-1-0.jscad
// version : 0.1.0
// rev notes : Derived from https://sk8cad.com
function getParameterDefinitions()
{
return ([
{ name: 'display_title', caption: '<span class="category">Display</span>', type: 'group', class: 'category'},
{ name: 'display_item', caption: 'Show ', type: 'choice', values: [0, 1, 2, 5], initial: 5, captions: ['Board', 'Male Mold', 'Female Mold', 'Both']},
{ name: 'display_inches', type: 'checkbox', checked: false, caption: 'Dual Unit Display'},
{ name: 'mold_design', caption: '<hr> <span class="category">Mold Specs</span>', type: 'group'},
{ name: 'mold_length', id: 'mold_length_id', caption: 'Length, in <span id="moldLengthInches" class="inchDisplay" > </span>', type: 'choice', values: [33,33.5,34,34.5,35,35.5,36],initial: 34, captions: ['33','33.5','34','34.5','35','35.5','36']},
{ name: 'mold_width', id: 'mold_width_id', caption: 'Width, in <span id="moldWidthInches" class="inchDisplay" > </span>', type: 'choice', values: [9,9.5,10,10.5,11,11.5,12],initial: 9.5, captions: ['9','9.5','10','10.5','11','11.5','12']},
//{ name: 'mold_height', id: 'mold_height_id', caption: 'Mold Height, in <span id="moldHeightInches" class="inchDisplay" > </span>', type: 'float', initial: 4, min: 1, step: 0.125},
//{ name: 'female_mold_height', caption: 'Female Mold Height, in', type: 'float', initial: 4, min: 1, step: 0.125},
{ name: 'mold_offset', type: 'float', initial: 0.875, step: 0.0625, caption: 'Mold Offset, in <span id="moldOffsetInches" class="inchDisplay" > </span>'},
//{ name: 'min_cavity_height', type: 'float', initial: 3, step: 0.125, caption: 'Min. Female Mold Height, in'},
//{ name: 'mold_holes', type: 'checkbox', checked: false, caption: 'Include Truck Holes'},
//{ name: 'truck_hole_diameter', caption: 'Truck Hole Diameter, in <span id="truckHoleDiameterInches" class="inchDisplay" > </span>', type: 'float', initial: 0.1875, min: 0.05, max: 1, step: 0.01},
//{ name: 'make_notches', type: 'checkbox', checked: true, caption: 'Alignment Notches'},
//{ name: 'notch_size', caption: 'Notch Diameter, in <span id="notchSizeInches" class="inchDisplay" > </span>', type: 'float', initial: 0.5, min: 0.05, max: 1, step: 0.01},
/*{ name: 'resolution', type: 'float', initial: 0.25, step: 0.0625, min: 0, max: 0.5, caption: 'Model Resolution<br><span style="font-size: 9px;">(For exporting)</span>'},
*/
//{ name: 'model_res', type: 'float', initial: 8, step: 4, min: 4, max: 16, caption: 'Model Resolution<br><span style="font-size: 9px;">(For exporting)</span>'},
/*{ name: 'print_settings', caption: '<hr> <span class="category">Sections</span>', type: 'group'},
{ name: 'print_width', type: 'float', initial: 8, step: 1, min: 5, max: 15, caption: 'Print Section Width, in<br> <span id="printWidthInches" class="inchDisplay" > </span>'},
{ name: 'print_length', type: 'float', initial: 8, step: 1, min: 5, max: 15, caption: 'Print Section Length, in<br> <span id="printLengthInches" class="inchDisplay" > </span>'},
{ name: 'make_bores', type: 'checkbox', checked: false, caption: 'Mold Bores'},
{ name: 'bore_diameter', type: 'float', initial: 0.25, step: 0.01, min: 0.02, max: 1, caption: 'Bore Diameter, in <span id="boreDiameterInches" class="inchDisplay" > </span>'},
{ name: 'bore_depth', type: 'float', initial: 0.3, step: 0.1, min: 0.02, max: 2, caption: 'Bore Depth, in <span id="boreDepthInches" class="inchDisplay" > </span>'},
{ name: 'bore_spacing', type: 'float', initial: 0.5, step: 0.1, min: 0.02, max: 2, caption: 'Bore Spacing, in <span id="boreSpacingInches" class="inchDisplay" > </span>'},
{ name: 'printSection', caption: 'Section to Download', type: 'choice', values: ['NONE','C','1N','1T','2N','2T','3N','3T'], initial: 0, captions: ['None', 'Center', 'Adjacent Nose', 'Adjacent Tail', 'Nose', 'Tail', 'Extended Nose', 'Extended Tail']},
*/
{ name: 'board_design', caption: '<hr> <span class="category">Design Your Board</span> <br> <p style="font-size: 11px; font-weight: normal;"> Board Length: <span id="lengthDisplay"> </span> <span id="boardLengthInches" class="inchDisplay"> </span> <br> <span style="font-size: 9px; font-weight: normal;"> (To change this, update wheelbase,<br> nose length, and tail length.) </span> </p>', type: 'group'},
{ name: 'profile', type: 'checkbox', checked: false, caption: 'Show Board Outline, Only <br>(Faster rendering)'},
{ name: 'uncut', type: 'checkbox', checked: false, caption: 'Show Uncut Deck'},
{ name: 'width', id: 'width_id', type: 'float', initial: 8.25, step: 0.125, caption: 'Width, in <span id="widthInches" class="inchDisplay" > </span>'},
{ name: 'wheelbase', id: 'wheelbase_id', type: 'float', initial: 14.0, step: 0.125, caption: 'Wheelbase, in <span id="wheelbaseInches" class="inchDisplay" > </span>'},
{ name: 'nose_length', id: 'nose_length_id', type: 'float', initial: 6.75, step: 0.125, caption: 'Nose Length, in <span id="noseLengthInches" class="inchDisplay" > </span>'},
{ name: 'tail_length', id: 'tail_length_id', type: 'float', initial: 6.5, step: 0.125, caption: 'Tail Length, in <span id="tailLengthInches" class="inchDisplay" > </span>'},
{ name: 'concave_drop', id: 'concave_drop_id', type: 'float', initial: 0.4, step: 0.1, max: 0.6, min: 0.0, caption: 'Concave Drop, in <span id="concaveDropInches" class="inchDisplay" > </span>'}, // concave_radius=0, make flat board
{ name: 'tub_concave', id: 'tub_concave_id', type: 'checkbox', checked: true, caption: 'Tub Concave'},
{ name: 'flat_width', id: 'flat_width_id', type: 'float', initial: 2.0, step: 0.125, caption: 'Flat Concave Width, in<br> <span id="flatWidthInches" class="inchDisplay" > </span>'},
//{ name: 'tub_angle', type: 'float', initial: 11, step: 0.25, caption: 'Tub Angle, deg.'},
{ name: 'tub_radius', id: 'tub_radius_id', type: 'float', initial: 6, step: 0.5, caption: 'Tub Radius, in <span id="tubRadInches" class="inchDisplay" > </span>'},
{ name: 'kicknose_angle', id: 'kicknose_angle_id', type: 'float', initial: 20.0, step: 1, min: 0, max: 25.0, caption: 'Kicknose, deg'},
{ name: 'kicktail_angle', id: 'kicktail_angle_id', type: 'float', initial: 19.0, step: 1, min: 0, max: 25.0, caption: 'Kicktail, deg'},
{ name: 'nose_radius', id: 'nose_radius_id', type: 'float', initial: 4, step: 1, max: 20, min: 4, caption: 'Nose Radius, in <span id="noseRadiusInches" class="inchDisplay" > </span>'},
{ name: 'tail_radius', id: 'tail_radius_id', type: 'float', initial: 5, step: 1, max: 20, min: 4, caption: 'Tail Radius, in <span id="tailRadiusInches" class="inchDisplay" > </span>'},
{ name: 'transition_length', id: 'transition_length_id', type: 'float', initial: 4, step: 0.25, max: 8, min: 3, caption: 'Transition Length, in<br> <span id="transitionLengthInches" class="inchDisplay" > </span>'},
{ name: 'kick_gap', id: 'kick_gap_id', type: 'float', initial: 1, step: 0.125, max: 3, min: 0, caption: 'Kick Gap, in <span id="kickGapInches" class="inchDisplay" > </span>'},
{ name: 'kick_concave_label', caption: '<span class="category">Kick Concave</span>', type: 'group'},
{ name: 'kick_concave', id: 'kick_concave_id', type: 'checkbox', checked: false, caption: 'Concave in Kicks'},
{ name: 'nose_base_drop', id: 'nose_base_drop_id', type: 'float', initial: 0.125, step: 0.03125, max: 0.2, min: 0, caption: 'Nose Base Drop, in<br> <span id="noseDropInches" class="inchDisplay" > </span>'},
{ name: 'nose_edge_kick_angle', id: 'nose_edge_kick_angle_id', type: 'float', initial: 1, step: 0.5, max: 3, min: 0, caption: 'Add. Angle - Nose, deg'},
{ name: 'nose_edge_kick_rad', id: 'nose_edge_kick_rad_id', type: 'float', initial: 1, step: 0.5, max: 3, min: 0, caption: 'Add. Radius - Nose, in<br> <span id="noseEdgeRadInches" class="inchDisplay" > </span>'},
{ name: 'tail_base_drop', id: 'tail_base_drop_id', type: 'float', initial: 0.125, step: 0.03125, max: 0.2, min: 0, caption: 'Tail Base Drop, in<br> <span id="tailDropInches" class="inchDisplay" > </span>'},
{ name: 'tail_edge_kick_angle', id: 'tail_edge_kick_angle_id', type: 'float', initial: 1, step: 0.5, max: 3, min: 0, caption: 'Add. Angle - Tail, deg'},
{ name: 'tail_edge_kick_rad', id: 'tail_edge_kick_rad_id', type: 'float', initial: 1, step: 0.5, max: 3, min: 0, caption: 'Add. Radius - Tail, in<br> <span id="tailEdgeRadInches" class="inchDisplay" > </span>'},
{ name: 'kcRes', id: 'kcRes_id', type: 'slider', class: 'paramSlider', min: -4, max: 4, initial: 0, step: 1, caption: 'Kick Concave Resolution'},
{ name: 'show_contours', type: 'checkbox', checked: false, caption: 'Show Contours'},
{ name: 'contour_res', caption: 'Contour Resolution ', type: 'choice', values: [0.0625, 0.125, 0.25, 0.5], initial: 0.25, captions: ['Ultra fine', 'Fine', 'Medium', 'Coarse']},
{ name: 'cutout_specs', caption: '<span class="category">Shape Controls</span>', type: 'group'},
{ name: 'taperN', id: 'taperN_id', type: 'float', initial: 7, step: 0.125, caption: 'Nose Taper Point, in<br> <span id="noseTaperInches" class="inchDisplay" > </span>'},
{ name: 'taperT', id: 'taperT_id', type: 'float', initial: 7.25, step: 0.125, caption: 'Tail Taper Point, in<br> <span id="tailTaperInches" class="inchDisplay" > </span>'},
{ name: 'nose_adjust', id: 'nose_adjust_id', type: 'slider', class: 'paramSlider tipShapes', min: 50, max: 100, initial: 72, step: 1, caption: '<span class="tipShapes">Nose Shape</span>'},
{ name: 'tail_adjust', id: 'tail_adjust_id', type: 'slider', class: 'paramSlider tipShapes', min: 50, max: 100, initial: 70, step: 1, caption: '<span class="tipShapes">Tail Shape</span>'},
{ name: 'make_cutouts', id: 'make_cutouts_id', type: 'checkbox', checked: false, caption: 'Advanced Shapes'},
{ name: 'noseLipX', id: 'noseLipX_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: 5, max: 18, step: 0.1, initial: 10, caption: '<span class="cutoutSpecs">Nose Cutout Depth</span>'},
{ name: 'noseLipY', id: 'noseLipY_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: -2, max: 4, step: 0.1, initial: 4, caption: '<span class="cutoutSpecs">Nose Cutout Width</span>'},
{ name: 'noseY', id: 'noseY_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: 2, max: 9, initial: 4, step: 0.1, caption: '<span class="cutoutSpecs">Nose Width</span>'},
{ name: 'tailLipX', id: 'tailLipX_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: 5, max: 18, step: 0.1, initial: 12, caption: '<span class="cutoutSpecs">Tail Cutout Depth</span>'},
{ name: 'tailLipY', id: 'tailLipY_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: -2, max: 4, step: 0.1, initial: 2, caption: '<span class="cutoutSpecs">Tail Cutout Width</span>'},
{ name: 'tailY', id: 'tailY_id', type: 'slider', class: 'paramSlider cutoutSpecs', min: 2, max: 9, initial: 6, step: 0.1, caption: '<span class="cutoutSpecs">Tail Width</span>'}
]);
}
function main (parameters)
{
var display = parameters.display_item;
var mold_size;
var mold_length = parameters.mold_length;
var mold_width = parameters.mold_width;
var mold_height = 3.75; //parameters.mold_height;
var actual_cav_height = mold_height; //stock material height
var mold_holes = false;// parameters.mold_holes;
var truck_hole_diameter = 0.1875; //parameters.truck_hole_diameter;
var make_notches = true;//parameters.make_notches;
var notch_diameter = 0.5;// parameters.notch_size;
var model_res = 8;//parameters.model_res;
var tub_res = 2/model_res;
var showProfile = parameters.profile;
var show_uncut = parameters.uncut;
if (show_uncut == true) {
make_notches = false;
}
var mold_choice = '0';
var profile_choice = mold_choice;
var printSection = false; //parameters.printSection;
var make_bores = false; //parameters.make_bores;
/*var bore_dia = parameters.bore_diameter;
var bore_depth = parameters.bore_depth;
var bore_spacing = parameters.bore_spacing;
*/
var make_cutouts;
var width;
var wheelbase;
var tail_length;
var nose_length;
var nose_shape;
var tail_shape;
var taperN;
var taperT;
var noseLipX;
var noseLipY;
var noseY;
var tailLipX;
var tailLipY;
var tailY;
var concave_drop;
var concave_radius;
var kicknose_angle;
var kicktail_angle;
var kicknose_radius;
var kicktail_radius;
var kick_gap;
var mold_offset = parameters.mold_offset;
var min_cavity_height = 3;//parameters.min_cavity_height;
var thickness = 0.4375;
var bolt_pattern_width = 1.625;
var bolt_pattern_length = 2.125;
var nose_transition_length;
var tail_transition_length;
nose_transition_length = parameters.transition_length;
tail_transition_length = parameters.transition_length;
var mold_length;
var mold_width;
var mold_height;
var max_cav_height;
var low_point;
var new_cav_base
var contour_res = parameters.contour_res;
var tub_concave = parameters.tub_concave;
var flat_width = parameters.flat_width;
//var tub_angle = parameters.tub_angle;
var tub_radius = parameters.tub_radius;
width = parameters.width;
wheelbase = parameters.wheelbase;
tail_length = parameters.tail_length;
nose_length = parameters.nose_length;
nose_shape = parameters.nose_adjust/100;
tail_shape = parameters.tail_adjust/100;
taperN = parameters.taperN;
taperT = parameters.taperT;
noseLipX = parameters.noseLipX;
noseLipY = parameters.noseLipY;
noseY = parameters.noseY;
tailLipX = parameters.tailLipX;
tailLipY = parameters.tailLipY;
tailY = parameters.tailY;
make_cutouts = parameters.make_cutouts;
var make_contours = parameters.show_contours;
var kcRes = parseFloat(parameters.kcRes);
var a = 1;
var loopCheck = false; //to track if we are showing both molds
var modelArray = [];
var boardDisplay = false;
if (display=='0') {
boardDisplay = true;
mold_offset = 0.4375;
}
if (showProfile == true) {
if (show_uncut == false){
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)
}
}
else {
skateboard = make_profile_uncut(mold_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, depth, mold_length)
}
var hole_depth = 6;
skateboard = skateboard.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase,hole_depth,truck_hole_diameter));
skateboard = color([0,0.99,0.99],skateboard);
return skateboard;
}
while (a==1) {
if (loopCheck == true) { //true if we did one iteration (for display ='1') already
display = '2'; //make female mold
loopCheck == false; //turn off so we don't repeat
}
if (display=='5' || display=='0') { //make both molds
a = 0; //reset counter
display = '1'; //make male mold
loopCheck = true; //store this so we make female mold in second iteration
}
a=a+1; //if display isn't 5, end while loop after this iteration
if (mold_choice == '0') {
concave_drop = parseFloat(parameters.concave_drop);
concave_radius = (Math.pow((width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop);
if (concave_drop == 0) {
tub_concave = false;
concave_radius = 0;
}
kicknose_angle = parameters.kicknose_angle;
kicktail_angle = parameters.kicktail_angle;
kicknose_radius = parameters.nose_radius;
kicktail_radius = parameters.tail_radius;
var kick_concave = parameters.kick_concave;
if (kick_concave == true) {
nose_base_drop = parameters.nose_base_drop;
tail_base_drop = parameters.tail_base_drop;
}
else {
nose_base_drop = 0;
tail_base_drop = 0;
}
nose_edge_kick_angle = parameters.nose_edge_kick_angle + kicknose_angle;
nose_edge_kick_rad = parameters.nose_edge_kick_rad + kicknose_radius;
tail_edge_kick_angle = parameters.tail_edge_kick_angle + kicktail_angle;
tail_edge_kick_rad = parameters.tail_edge_kick_rad + kicktail_radius;
kick_gap = parseFloat(parameters.kick_gap);
// mold_size = parameters.mold_size;
}
else {
switch (mold_choice) {
case '1': //street deck
concave_drop = 0.375;
concave_radius = (Math.pow((width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop);
if (concave_drop == 0) {
concave_radius = 0;
}
kicknose_angle = 20;
kicktail_angle = 20;
kicknose_radius = 6;
kicktail_radius = 6;
kick_gap = 1;
//mold_size = '0';
break;
case '2': //dancer
concave_drop = 0.125;
concave_radius = (Math.pow((width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop);
if (concave_drop == 0) {
concave_radius = 0;
}
kicknose_angle = 12;
kicktail_angle = 12;
kicknose_radius = 6;
kicktail_radius = 6;
kick_gap = 1;
mold_size = '1';
break;
case '3': //cruiser
concave_drop = 0.25;
concave_radius = (Math.pow((width/2),2) + Math.pow(concave_drop,2))/(2*concave_drop);
if (concave_drop == 0) {
concave_radius = 0;
}
kicknose_angle = 12;
kicktail_angle = 21;
kicknose_radius = 6;
kicktail_radius = 6;
kick_gap = 1;
// mold_size = '0';
break;
}
}
kick_to_kick = wheelbase + (2*bolt_pattern_length)+ (2*kick_gap);
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 nose_offset = (nose_length - tail_length)/2;
var mold_kicknose_length = ((mold_length - kick_to_kick)/2)+nose_offset;
var mold_kicktail_length = ((mold_length - kick_to_kick)/2)-nose_offset;
var slice_thickness = parseFloat(parameters.resolution);
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 = 8; //for transition section resolution
var skateboard;
var depth = 1; /*depth of profile*/
/*
if (display == 0) {
/**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));
}
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)))).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)))).translate([-(concave_length/2+tail_transition_length),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);
}
else {
profile = make_lb_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, 10, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY)
}
skateboard = skateboard.intersect(profile);
}
*/
if (display == '2' || display == '4') { // 1/27/21 add cavity
//adjust parameters for offset:
var nose_rad_original = kicknose_radius;
var tail_rad_original = kicktail_radius;
var nose_base_drop_original = nose_base_drop;
var tail_base_drop_original = tail_base_drop;
kicknose_radius += mold_offset;
kicktail_radius += mold_offset;
if (concave_radius !== 0 ) {
concave_radius += mold_offset;
min_radius += mold_offset;
}
if (nose_base_drop !== 0) {
var nBR = (Math.pow(nose_base_drop,2)+Math.pow(mold_width/2,2))/(2*nose_base_drop); //kick base radius
nBR += mold_offset;
nose_base_drop = (-(-2*nBR) - sqrt(Math.pow(2*nBR,2)-(4*1*Math.pow(mold_width/2,2))))/(2);
}
if (tail_base_drop !== 0) {
var tBR = (Math.pow(tail_base_drop,2)+Math.pow(mold_width/2,2))/(2*tail_base_drop); //kick base radius
tBR += mold_offset;
tail_base_drop = (-(-2*tBR) - sqrt(Math.pow(2*tBR,2)-(4*1*Math.pow(mold_width/2,2))))/(2);
}
if (kicknose_angle !== 0) {
if (kick_concave == false) {
kicknose = make_mold_kicknose_curve(kicknose_radius, mold_width, kicknose_angle, nose_transition_length, concave_length, kicknose_length);
}
else { //bt edit 3/29
kicknose = make_concave_kick_offset(mold_width, nose_rad_original, kicknose_angle, nose_base_drop_original, nose_edge_kick_rad, nose_edge_kick_angle, mold_kicknose_length, mold_height-mold_offset, kcRes, mold_offset);
kicknose = mirror([0,0,1],kicknose);
kicknose = rotate([0,0,-90],(kicknose.translate([0,kick_to_kick/2,0])));
}
}
else {
if (tub_concave == true) {
kicknose = make_tub_concave(concave_drop, mold_height, mold_kicknose_length+nose_transition_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, true).translate([(mold_kicknose_length+nose_transition_length)/2+concave_length/2,0,0]);
}
else {
kicknose = make_mold_concave(concave_radius, mold_height, mold_kicknose_length+nose_transition_length, mold_width,flat_concave_length).translate([(mold_kicknose_length+nose_transition_length)/2+concave_length/2,0,0]);
}
}
if (kicktail_angle !== 0) {
if (kick_concave == false) {
kicktail = make_mold_kicktail_curve(kicktail_radius, mold_width, kicktail_angle, tail_transition_length, concave_length, kicktail_length);
}
else { //bt edit 3/29
kicktail = make_concave_kick_offset(mold_width, tail_rad_original, kicktail_angle, tail_base_drop_original, tail_edge_kick_rad, tail_edge_kick_angle, mold_kicktail_length, mold_height-mold_offset, kcRes, mold_offset);
kicktail = mirror([0,0,1],kicktail);
kicktail = rotate([0,0,90],(kicktail.translate([0,kick_to_kick/2,0])));
}
}
else {
if (tub_concave == true) {
kicktail = make_tub_concave(concave_drop, mold_height, mold_kicktail_length+tail_transition_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, true).translate([-(mold_kicktail_length+tail_transition_length)/2-concave_length/2,0,0]);
}
else {
kicktail = make_mold_concave(concave_radius, mold_height, mold_kicktail_length+tail_transition_length, mold_width,flat_concave_length).translate([-(mold_kicktail_length+tail_transition_length)/2-concave_length/2,0,0]);
}
}
var mold;
if (tub_concave == true) {
mold = color([0.7,0.7,0.7],make_tub_concave(concave_drop, mold_height, concave_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, true));
}
else {
mold = color([0.7,0.7,0.7],make_mold_concave(concave_radius, mold_height, concave_length, mold_width, flat_concave_length));
}
mold = mold.union(color([.5,.5,.5],kicknose));
mold = mold.union(color([.5,.5,.5],kicktail));
if (concave_radius !== 0) {
//BT edit 3/29: added "base drop" parameters
var nose_transition
if (kicknose_angle!==0){
if (tub_concave == false) {
nose_transition = make_mold_transition_section_offset(nose_transition_length, mold_height, slice_thickness, mold_width, min_radius-mold_offset, number_of_segments,model_res,nose_base_drop_original,mold_offset);
}
else {
nose_transition = make_tub_transition_section_offset(nose_transition_length, thickness, slice_thickness, mold_width, width, tub_radius, number_of_segments, model_res, nose_base_drop_original, flat_width, concave_drop, mold_height, tub_res, mold_offset);
}
}
//return nose_transition;
var tail_transition
if (kicktail_angle!==0) {
if (tub_concave == false) {
tail_transition = mirror([1,0,0], make_mold_transition_section_offset(tail_transition_length, mold_height, slice_thickness, mold_width, min_radius-mold_offset, number_of_segments,model_res,tail_base_drop_original,mold_offset));
}
else {
tail_transition = mirror([1,0,0], make_tub_transition_section_offset(tail_transition_length, thickness, slice_thickness, mold_width, width, tub_radius, number_of_segments, model_res, tail_base_drop_original, flat_width, concave_drop, mold_height, tub_res, mold_offset));
}
}
if (kicknose_angle !== 0) {
nose_transition = nose_transition.translate([concave_length/2+nose_transition_length,0,0]);
}
if (kicktail_angle !== 0) {
tail_transition = tail_transition.translate([-concave_length/2-tail_transition_length,0,0]);
}
}
// if (kick_concave == false) {
if (nose_transition && tail_transition) {
mold = [mold, nose_transition, tail_transition];
}
else if (nose_transition && (!tail_transition)) {
mold = [mold, nose_transition];
}
else if (tail_transition && (!nose_transition)) {
mold = [mold, tail_transition];
}
else {
mold = [mold];
}
var block = cube({size: [mold_length, mold_width, mold_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,-mold_height/2]);
//return block.intersect(mold[3]);
for (let i=0;i<mold.length;i++) {
mold = block.intersect(mold[i]);
}
// }
if (nose_transition) {mold = mold.union(nose_transition)};
if (tail_transition) {mold = mold.union(tail_transition)};
var edge_eraser_left;
var edge_eraser_right;
var left_bounds = mold.getBounds()[0].x;
var right_bounds = mold.getBounds()[1].x;
edge_eraser_left = cube({size: [mold_length, mold_width, mold_height+3], center: true}).translate([0,-mold_width,-mold_height/2]);
mold = mold.subtract(edge_eraser_left);
edge_eraser_right = cube({size: [mold_length, mold_width, mold_height+3], center: true}).translate([0,mold_width,-mold_height/2]);
mold = mold.subtract(edge_eraser_right);
if (display == '2') {
mold = (cube({size: [mold_length, mold_width, actual_cav_height+1], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,-actual_cav_height/2+0.5])).subtract(mold);
mold = mold.union(cube({size: [mold_length, mold_width, actual_cav_height-0.5], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,actual_cav_height/2+0.25]));
max_cav_height = mold.getBounds()[1].z - mold.getBounds()[0].z;
low_point = mold.getBounds()[0].z; //peak of kicks on female mold
new_cav_base = low_point + actual_cav_height;
mold = mold.subtract(cube({size: [mold_length, mold_width, max_cav_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,(new_cav_base+(max_cav_height/2))]));
}
mold = mold.translate([0,0,mold_offset]);
skateboard = mold;
}
else {
/*bt edits for troubleshooting
var concave_drop = parameters.concave_drop;
var tub = make_tub_concave(concave_drop, mold_height, concave_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res);
return tub;
*/
if (kicknose_angle !== 0) {
if (kick_concave == false) {
kicknose = make_mold_kicknose_curve(kicknose_radius, mold_width, kicknose_angle, nose_transition_length, concave_length, kicknose_length);
}
else {
kicknose = make_concave_kick(mold_width, kicknose_radius, kicknose_angle, nose_base_drop, nose_edge_kick_rad, nose_edge_kick_angle, mold_kicknose_length, mold_height, kcRes, nose_base_drop);
kicknose = mirror([0,0,1],kicknose);
kicknose = rotate([0,0,-90],(kicknose.translate([0,kick_to_kick/2,0])));
}
}
else {
if (tub_concave == true) {
kicknose = make_tub_concave(concave_drop, mold_height, mold_kicknose_length+nose_transition_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, false).translate([(mold_kicknose_length+nose_transition_length)/2+concave_length/2,0,0]);
}
else {
kicknose = make_mold_concave(concave_radius, mold_height, mold_kicknose_length+nose_transition_length, mold_width,flat_concave_length).translate([(mold_kicknose_length+nose_transition_length)/2+concave_length/2,0,0]);
}
}
if (kicktail_angle !== 0) {
if (kick_concave == false) {
kicktail = make_mold_kicktail_curve(kicktail_radius, mold_width, kicktail_angle, tail_transition_length, concave_length, kicktail_length);
}
else {
kicktail = make_concave_kick(mold_width, kicktail_radius, kicktail_angle, tail_base_drop, tail_edge_kick_rad, tail_edge_kick_angle, mold_kicktail_length, mold_height, kcRes, tail_base_drop);
kicktail = mirror([0,0,1],kicktail);
kicktail = rotate([0,0,90],(kicktail.translate([0,kick_to_kick/2,0])));
}
}
else {
if (tub_concave == true) {
kicktail = make_tub_concave(concave_drop, mold_height, mold_kicktail_length+tail_transition_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, false).translate([-(mold_kicktail_length+tail_transition_length)/2-concave_length/2,0,0]);
}
else {
kicktail = make_mold_concave(concave_radius, mold_height, mold_kicktail_length+tail_transition_length, mold_width,flat_concave_length).translate([-(mold_kicktail_length+tail_transition_length)/2-concave_length/2,0,0]);
}
}
var mold;
if (tub_concave == true) {
mold = color([0.7,0.7,0.7],make_tub_concave(concave_drop, mold_height, concave_length, mold_width, flat_concave_length, flat_width, tub_radius, width, tub_res, mold_offset, false));
}
else {
mold = color([0.7,0.7,0.7],make_mold_concave(concave_radius, mold_height, concave_length, mold_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
if (kicknose_angle!==0){
if (tub_concave == false && kicknose) {
nose_transition = make_mold_transition_section_new(nose_transition_length, mold_height, slice_thickness, mold_width, min_radius, number_of_segments,model_res, nose_base_drop);
}
else {
nose_transition = make_tub_transition_section(nose_transition_length, thickness, slice_thickness, mold_width, width, tub_radius, number_of_segments, model_res, nose_base_drop, flat_width, concave_drop, mold_height, tub_res);
}
}
var tail_transition
if (kicktail_angle!==0) {
if (tub_concave == false) {
tail_transition = mirror([1,0,0], make_mold_transition_section_new(tail_transition_length, mold_height, slice_thickness, mold_width, min_radius, number_of_segments,model_res, tail_base_drop));
}
else {
tail_transition = mirror([1,0,0],make_tub_transition_section(tail_transition_length, thickness, slice_thickness, mold_width, width, tub_radius, number_of_segments, model_res, tail_base_drop, flat_width, concave_drop, mold_height, tub_res));
}
}
if (kicknose_angle !== 0) {
nose_transition = nose_transition.translate([concave_length/2+nose_transition_length,0,0]);
}
if (kicktail_angle !== 0) {
tail_transition = tail_transition.translate([-concave_length/2-tail_transition_length,0,0]);
}
}
//if (kick_concave==false) {
if (nose_transition && tail_transition) {
mold = [mold, nose_transition, tail_transition]; //removed kicknose and kicktail from all of these 6/7/22
}
else if (nose_transition && (!tail_transition)) {
mold = [mold, nose_transition];
}
else if (tail_transition && (!nose_transition)) {
mold = [mold, tail_transition];
}
else {
mold = [mold];
}
var block = cube({size: [mold_length, mold_width, mold_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,-mold_height/2]);
//return block.intersect(mold[3]);
for (let i=0;i<mold.length;i++) {
mold = block.intersect(mold[i]);
}
//}
if (nose_transition) {mold = mold.union(nose_transition)};
if (tail_transition) {mold = mold.union(tail_transition)};
if (display == '3') {
mold = (cube({size: [mold_length, mold_width, actual_cav_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,-(actual_cav_height)/2])).subtract(mold);
mold = mold.union((cube({size: [mold_length, mold_width, actual_cav_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,(actual_cav_height/2)])));
max_cav_height = mold.getBounds()[1].z - mold.getBounds()[0].z;
low_point = mold.getBounds()[0].z; //peak of kicks on female mold
new_cav_base = low_point + actual_cav_height;
mold = mold.subtract(cube({size: [mold_length, mold_width, max_cav_height], center: true}).translate([(nose_transition_length-tail_transition_length+nose_length-tail_length)/2,0,(new_cav_base+(max_cav_height/2))]));
}
skateboard = mold;
}
var mDia = notch_diameter; //notch diameter
if (display == '1' || display == '3') {
if (make_notches == true) {
var notches = make_markers(mold_width, wheelbase, nose_length, tail_length, bolt_pattern_length, mDia, kick_gap, nose_transition_length, tail_transition_length, nose_base_drop, tail_base_drop);
skateboard = skateboard.subtract(notches);
}
skateboard = color([0,0.99,0],skateboard);
}
if (display == '2' || display == '4') {
if (make_notches == true) {
skateboard = skateboard.subtract(make_markers(mold_width, wheelbase, nose_length, tail_length, bolt_pattern_length, mDia, kick_gap, nose_transition_length, tail_transition_length, nose_base_drop, tail_base_drop).translate([0,0,mold_offset]));
}
skateboard = color([0,0.5,0.99],skateboard);
}
var hole_depth;
if (display == '0' || showProfile == true) {
hole_depth = 6;
skateboard = skateboard.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase,hole_depth,truck_hole_diameter));
skateboard = color([0,0.99,0.99],skateboard);
}
else if ((display !== '0') && (mold_holes == true)) {
hole_depth = 3*(mold_height+mold_offset+min_cavity_height);
skateboard = skateboard.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase,hole_depth,truck_hole_diameter).translate([0,0,-3*(mold_height+mold_offset+min_cavity_height)/2]));
}
//skateboard = color([0,0.99,0],skateboard);
var printLength = parameters.print_length;
var printWidth = parameters.print_width;
var sectionWidth;
if (printWidth >= mold_width) {
sectionWidth = mold_width;
sectionWidthMoveX = 0;
}
else {
sectionWidth = printWidth;
sectionWidthMoveX = sectionWidth/2;
}
if (display == '2' || display == '4') {
var sectionHeight = 2*(mold_height + (mold_offset) + min_cavity_height);
switch (printSection) {
case 'C':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '1N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '1T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([-printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '2N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([2*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '2T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([-2*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '3N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([3*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case '3T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,sectionHeight], center: true})).translate([-3*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,0]));
break;
case 'NONE':
break;
}
}
else {
//max mold size: 16" x 48" using 8" x 8" print area.
switch (printSection) {
case 'C':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '1N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '1T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([-printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '2N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([2*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '2T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([-2*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '3N':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([3*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case '3T':
skateboard = skateboard.intersect(color([0.99,0,0],cube({size:[printLength,sectionWidth,mold_height], center: true})).translate([-3*printLength+(nose_length-tail_length)/2,sectionWidthMoveX,-mold_height/2]));
break;
case 'NONE':
break;
}
}
//console.log('bounds are ' + (skateboard.getBounds()[1].z - skateboard.getBounds()[0].z))
if (make_bores == true) {
var bore_oversize = 0.1; //how much longer to make the bore for cleaner cuts
if (display == '1' || display == '2') {
var bores = make_section_bores(mold_width, mold_length, printLength, printWidth, bore_dia, bore_depth, mold_height, printSection, bore_spacing, nose_length, tail_length, display, bore_oversize);
var numberOfBores = bores.length;
if (display == '2') {
for (var i=0; i<numberOfBores;i++) {
bores[i] = bores[i].translate([0,0,mold_height+skateboard.getBounds()[1].z-bore_depth+bore_oversize]);
}
}
if (printSection == 'NONE') {
var verticalPlane = CSG.Plane.fromPoints([0,0,0], [5, 0, 1], [-5, 0, 1]);
for (var k=0;k<bores.length;k++) {
skateboard = skateboard.subtract(bores[k].mirrored(verticalPlane));
}
}
skateboard = skateboard.subtract(bores);
}
}
modelArray.push(color([0.9,0.95,0.95],skateboard));
}
if (boardDisplay == true) {
var profile;
var extrusion_height;
var extrusion_adjust = 0.1;
var lower_bound = modelArray[0].getBounds()[0].z;
var upper_bound = modelArray[1].getBounds()[1].z;
var mold_height_delta = upper_bound - lower_bound;
extrusion_height = mold_height_delta;
extrusion_height -= extrusion_adjust; //to prevent adjacent faces
if (show_uncut == false) {
if (make_cutouts == false) {
profile = make_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, nose_shape, tail_shape, extrusion_height);
}
else {
profile = make_lb_profile(width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, extrusion_height, noseLipX, noseLipY, noseY, tailLipX, tailLipY, tailY)
}
}
else {
profile = make_profile_uncut(mold_width, wheelbase, bolt_pattern_length, nose_length, tail_length, length, taperN, taperT, extrusion_height, mold_length)
}
profile = profile.translate([0,0,-mold_height+(extrusion_adjust/2)]);
profile = profile.subtract(modelArray[1]);
profile = profile.subtract(modelArray[0]);
hole_depth = 6;
profile = profile.subtract(make_wheelbase(bolt_pattern_length, bolt_pattern_width,wheelbase,hole_depth,truck_hole_diameter).translate([0,0,-hole_depth/2]));
profile = color([0,0.99,0.99],profile);
modelArray = [profile];
}
if (make_contours == true) {
var top_bound, bottom_bound;
for (var i = 0; i<modelArray.length; i++) {
if ((modelArray[i-1]==null) || (modelArray[i].getBounds()[1].z > modelArray[i-1].getBounds()[1].z )) {
top_bound = modelArray[i].getBounds()[1].z;
}
if ((modelArray[i-1]==null) || (modelArray[i].getBounds()[0].z < modelArray[i-1].getBounds()[0].z)) {
bottom_bound = modelArray[i].getBounds()[0].z;
}
}
var topoStack = topoLayers(mold_length+1, mold_width+1, contour_res, bottom_bound, top_bound, mold_height);
//return skateboard;
var stackArray = []
for (var j=0;j<topoStack.length;j++) {
for (var k = 0; k<modelArray.length;k++) {
if (j%2 == 0) {
stackArray.push(color([0,0.9,0.99],modelArray[k].intersect(topoStack[j])));
}
else {
stackArray.push(color([0.9,0.95,0.99],modelArray[k].intersect(topoStack[j])));
}
}
}
modelArray = stackArray;
}
return modelArray;
//return color([0.9,0.95,0.95],skateboard);
}
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_markers(width, wheelbase, nose_length, tail_length, boltL, mDia, kick_gap, noseT, tailT, nose_base_drop, tail_base_drop) {
var result = new CSG();
result = sphere({r: mDia/2, center: true});
result = result.translate([(wheelbase/2+boltL+kick_gap+((noseT-tailT)/2)),(width/2),-nose_base_drop]);
result = result.union(sphere({r: mDia/2, center: true}).translate([(wheelbase/2+boltL+kick_gap+((noseT-tailT)/2)),-(width/2),-nose_base_drop]));
result = result.union(sphere({r: mDia/2, center: true}).translate([-(wheelbase/2+boltL+kick_gap-((noseT-tailT)/2)),-(width/2),-tail_base_drop]));
result = result.union(sphere({r: mDia/2, center: true}).translate([-(wheelbase/2+boltL+kick_gap-((noseT-tailT)/2)),(width/2),-tail_base_drop]));
return result;
}
function topoLayers(length,width,thick,bottom_bound,top_bound,moldHeight) {
var result = [];
var height = top_bound-bottom_bound;
var iSteps = height/thick;
for (var i=0; i<=iSteps+1;i++){
if (i%2 == 0) {
result.push(color([0,0.9,0.99],cube({size: [length,width,thick], center: true})).translate([0,0,i*thick+(bottom_bound)]));
}
else {
result.push(color([.95,0.95,0.99],cube({size: [length,width,thick], center: true})).translate([0,0,i*thick+(bottom_bound)]));
}
}
return result;
}
function make_bolt_pattern(bolt_pattern_length, bolt_pattern_width, depth, truck_hole_diameter)
{
var result = new CSG();
result = (cylinder({d: truck_hole_diameter, h: depth, center: false}).translate([bolt_pattern_length/2,bolt_pattern_width/2,0])).union(cylinder({d: truck_hole_diameter, h: depth, center: false}).translate([bolt_pattern_length/2,-bolt_pattern_width/2,0]));
result = result.union(cylinder({d: truck_hole_diameter, h: depth, center: false}).translate([-bolt_pattern_length/2,-bolt_pattern_width/2,0]));
result = result.union(cylinder({d: truck_hole_diameter, h: depth, center: false}).translate([-bolt_pattern_length/2,bolt_pattern_width/2,0]));
return result;
}
function make_wheelbase(bolt_pattern_length, bolt_pattern_width, wheelbase, depth, truck_hole_diameter)
{
var result = new CSG();
result = (make_bolt_pattern(bolt_pattern_length,bolt_pattern_width,depth,truck_hole_diameter).translate([(wheelbase/2)+(bolt_pattern_length/2),0,-1])).union(make_bolt_pattern(bolt_pattern_length,bolt_pattern_width,depth,truck_hole_diameter).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: 500}),
cylinder({r: concave_radius, h:concave_length+2, center: true, fn: 500}).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_mold_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;
}
}
function make_tub_concave(concave_drop, thickness, concave_length, mold_width, flat_concave_length, flat_width, tub_rad, deck_width, tub_res, mold_offset, isOffset)
{
var res = 100; //resolution of bezier curves
var x_res = tub_res;
/*The following equations were derived on a piece of paper, using tan(tub_angle) = (concave_drop - tub_rad + tub_rad*cos(tub_angle))/(deck_width/2 - flat_width/2 - tub_rad*sin(tub_angle)) and some trig identities: sin^2(x) + cos^2(x) = 1. This website was helpful: https://www.symbolab.com/solver/trigonometric-simplification-calculator
*/
var a = Math.pow(concave_drop-tub_rad,2)+Math.pow((deck_width/2 - flat_width/2),2);
var b = 2*tub_rad*(concave_drop-tub_rad);
var c = Math.pow(tub_rad,2)-Math.pow(deck_width/2 - flat_width/2, 2);
var tub_angle1 = acos((-b + sqrt(Math.pow(b,2) - 4*a*c))/(2*a));
//var tub_angle2 = acos((-b - sqrt(Math.pow(b,2) - 4*a*c))/(2*a));
var tub_angle = tub_angle1;
//update tub rad if female mold:
if (isOffset) {
tub_rad += mold_offset;
}
var x_adjust = Math.ceil((flat_width/2)/x_res);
var profile = new CSG.Path2D([
[0,0],
[x_res*x_adjust,0]
]);
var x;
for (x=x_res; x<=mold_width/2-flat_width/2; x+=x_res) { //as we move from the flat section to mold edge
if (x<=(tub_rad*sin(tub_angle))) {
profile = profile.appendPoint([x+(x_res*x_adjust),-(tub_rad-sqrt((pow(tub_rad,2)-pow((x),2))))]);
}
else {
profile = profile.appendPoint([x+(x_res*x_adjust),-((tub_rad - (tub_rad*cos(tub_angle)))+(((x)-tub_rad*sin(tub_angle))*tan(tub_angle)))]);
}
//console.log(profile);
}
profile = profile.appendPoints([
[x-x_res+(x_res*x_adjust),-thickness],
[0,-thickness]
]);
profile = profile.close();
var result = profile.innerToCAG();
result = linear_extrude({height: concave_length}, result);
result = result.union(mirror([1,0,0],result));
result = rotate([90,0,90],result);
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_mold_kicknose_curve(kicknose_radius, width, kicknose_angle, nose_transition_length, concave_length, kicknose_length)
{
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*2], 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.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_mold_kicktail_curve(kicktail_radius, width, kicktail_angle, tail_transition_length, concave_length, kicktail_length)
{
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*2], 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]})).translate([0,-width,0]));
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_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, 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, 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;
}
/*---- added concave in kicks -----*/
function make_concave_kick(moldWidth, kickRadius, kickAngle, kickBaseDrop, kickRadiusEdge, kickAngleEdge, kickLength, moldHeight, kcRes) {
var deckWidth = moldWidth;
/* var kickRadius = 4;
var kickAngle = 20;
var kickBaseDrop = 0.125;
var kickTipDrop = 0.25;
var kickRadiusEdge = 5;
var kickAngleEdge = 21;
var kickLength = 7+1;
var moldHeight = 4;*/
var y_max = kickLength;
var x_max = deckWidth/2;
var stepsPerY = 24+kcRes; //how many iterations are done until we move onto next y value
var stepsPerX = 8; //how many iterations done until move onto next x value
var y_res = y_max/stepsPerY;
var x_res= x_max/stepsPerX;
var pointArray = [];
var subArray =[];
var x;
var y;
var z;
var zRad; //radius of curve from zc to ze
var coord; //point coordinates in x,y,z
var i; //keep track of iterations
var transitionZc;
var transitionZe;
var transitionYc;
var transitionYe;
var zc;
var ze;
for (y=0; y<=y_max; y=y+y_res) { //as we move from kick base to tip
if (y<=(kickRadius*sin(kickAngle))) { //get zc and ze first
zc = kickRadius-sqrt((pow(kickRadius,2)-pow(y,2))); // get zc in radius section
transitionZc = zc; //save last zc before change
transitionYc = y;
}
else {
zc = (kickRadius - (kickRadius*cos(kickAngle)))+((y-kickRadius*sin(kickAngle))*tan(kickAngle)); //get zc in stratight section
}
if (y<=(kickRadiusEdge*sin(kickAngleEdge))) {
ze = kickBaseDrop+kickRadiusEdge-sqrt((pow(kickRadiusEdge,2)-pow(y,2))); //ze in radius section
transitionZe = ze; //save last ze before change
transitionYe = y;
}
else {
ze = (kickBaseDrop+kickRadiusEdge - (kickRadiusEdge*cos(kickAngleEdge)))+((y-kickRadiusEdge*sin(kickAngleEdge))*tan(kickAngleEdge)); //ze in straight section
}
//now that we have zc and ze, we can find the z values in between, at specific x values
for (x=0; x<=x_max; x=x+x_res) {
zRad = (pow(x_max,2)+pow((ze-zc),2))/(2*(ze-zc)); //establish the radius of the curve along the x axis
z = zc + zRad - sqrt(pow(zRad,2)-pow(x,2));
coord = [x,y,z];
pointArray.push(coord);
if (x!==x_max){
if (x+x_res>x_max) {
x=x_max-x_res;
}
}
}
if (y!==y_max){
if (y+y_res>y_max) {
y=y_max-y_res;
}
}
}
var finalZc = zc;
var finalZe = ze;
var triangleArray = [];
var a=0;
var b=1;
var i;
var maxTriangleArray = pointArray.length-stepsPerX-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerX+1) {
for (a=i;a<(i+stepsPerX);a++) {
triangleArray.push([(a),(a+1),(stepsPerX+a+1)]);
if ((a+1)<=(i+stepsPerX)) {
triangleArray.push([(stepsPerX+a+2),(stepsPerX+a+1),a+1]);
}
}
}
var result= polyhedron({ //
points: pointArray, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor(255,255,255);
// triangleArray = findDuplicates(triangleArray);
var mainPoly = polyhedron({
points: pointArray,
triangles: triangleArray
});
//side:
var yeRadPts = [];
var yei;
for (yei=0; yei<=(kickRadiusEdge*sin(kickAngleEdge)); yei=(yei+y_res)) {
var zei = kickBaseDrop+kickRadiusEdge-sqrt((pow(kickRadiusEdge,2)-pow(yei,2)));
yeRadPts.push([x_max,yei,zei]);
}
transitionZe = (kickBaseDrop+kickRadiusEdge - (kickRadiusEdge*cos(kickAngleEdge)))+((yei-kickRadiusEdge*sin(kickAngleEdge))*tan(kickAngleEdge));
yeRadPts.push([x_max,yei,transitionZe]);
var radialSection = yeRadPts.length;
yeRadPts.push([x_max,y_max,ze],[x_max,y_max,moldHeight],[x_max,0,moldHeight],[x_max,0,kickBaseDrop]);
var yeRadTriangles = [];
for (var yej=1; yej<(yeRadPts.length-2); yej++){
yeRadTriangles.push([yej,(yeRadPts.length-1),yej+1]);
}
var yeRadCAG = polyhedron({
points: yeRadPts,
triangles: yeRadTriangles
});
//add yeRadTriangles to triangleArray:
for (var k=0; k<(yeRadTriangles.length); k++){
yeRadTriangles[k][0]+=pointArray.length;
yeRadTriangles[k][1]+=pointArray.length;
yeRadTriangles[k][2]+=pointArray.length;
}
pointArray = pointArray.concat(yeRadPts);
triangleArray = triangleArray.concat(yeRadTriangles);
/*--------------------------------- yc -------------------*/
/* var ycRadPts = [];
var yci;
for (yci=0; yci<=(kickRadius*sin(kickAngle)); yci=(yci+y_res)) {
var zci = kickRadius-sqrt((pow(kickRadius,2)-pow(yci,2)));
ycRadPts.push([0,yci,zci]);
}
transitionZc = (kickRadius - (kickRadius*cos(kickAngle)))+((yci-kickRadius*sin(kickAngle))*tan(kickAngle));
ycRadPts.push([0,yci,transitionZc]);
var radialSectionC = ycRadPts.length;
ycRadPts.push([0,y_max,zc],[0,y_max,moldHeight],[0,0,moldHeight],[0,0,0]);
var ycRadTriangles = [];
for (var ycj=1; ycj<(ycRadPts.length-2); ycj++){
ycRadTriangles.push([ycj+1,(ycRadPts.length-1),ycj]);
}
var ycRadCAG = polyhedron({
points: ycRadPts,
triangles: ycRadTriangles
});
//add ycRadTriangles to triangleArray:
for (var k=0; k<(ycRadTriangles.length); k++){
ycRadTriangles[k][0]+=pointArray.length;
ycRadTriangles[k][1]+=pointArray.length;
ycRadTriangles[k][2]+=pointArray.length;
}
pointArray = pointArray.concat(ycRadPts);
triangleArray = triangleArray.concat(ycRadTriangles);
/*----------------- tip ---------------*/
var tipRadPts = [];
var xti;
for (xti=0; xti<=x_max; xti=(xti+x_res)) {
var zRadt = (pow(x_max,2)+pow((finalZe-finalZc),2))/(2*(finalZe-finalZc)); //establish the radius of the curve along the x axis
var zti = finalZc + zRadt - sqrt(pow(zRadt,2)-pow(xti,2));
tipRadPts.push([xti,y_max,zti]);
}
tipRadPts.push([x_max,y_max,moldHeight]);
var radialSectionTip = tipRadPts.length;
tipRadPts.push([0,y_max,moldHeight]);
var tipRadTriangles = [];
for (var xtj=0; xtj<(tipRadPts.length-2); xtj++){
tipRadTriangles.push([xtj+1,(tipRadPts.length-1),xtj]);
}
var tipRadCAG = polyhedron({
points: tipRadPts,
triangles: tipRadTriangles
});
//add ycRadTriangles to triangleArray:
for (var k=0; k<(tipRadTriangles.length); k++){
tipRadTriangles[k][0]+=pointArray.length;
tipRadTriangles[k][1]+=pointArray.length;
tipRadTriangles[k][2]+=pointArray.length;
}
pointArray = pointArray.concat(tipRadPts);
triangleArray = triangleArray.concat(tipRadTriangles);
/*----------------- base ---------------*/
var baseRadPts = [];
var xbi;
var zeInit = kickBaseDrop;
var zcInit = 0;
for (xbi=0; xbi<=x_max; xbi=(xbi+x_res)) {
var zRadb = (pow(x_max,2)+pow((zeInit-zcInit),2))/(2*(zeInit-zcInit)); //establish the radius of the curve along the x axis
var zbi = zcInit + zRadb - sqrt(pow(zRadb,2)-pow(xbi,2));
baseRadPts.push([xbi,0,zbi]);
}
baseRadPts.push([x_max,0,moldHeight]);
var radialSectionBase = baseRadPts.length;
baseRadPts.push([0,0,moldHeight]);
var baseRadTriangles = [];
for (var xbj=0; xbj<(baseRadPts.length-2); xbj++){
baseRadTriangles.push([xbj,(baseRadPts.length-1),xbj+1]);
}
var baseRadCAG = polyhedron({
points: baseRadPts,
triangles: baseRadTriangles
});
//add ycRadTriangles to triangleArray:
for (var k=0; k<(baseRadTriangles.length); k++){
baseRadTriangles[k][0]+=pointArray.length;
baseRadTriangles[k][1]+=pointArray.length;
baseRadTriangles[k][2]+=pointArray.length;
}
pointArray = pointArray.concat(baseRadPts);
triangleArray = triangleArray.concat(baseRadTriangles);
/*------- bottom --------*/
var bottomOffset = pointArray.length;
pointArray = pointArray.concat(
[ [0,0,moldHeight],
[0,y_max,moldHeight],
[x_max,y_max,moldHeight],
[x_max,0,moldHeight]]);
triangleArray = triangleArray.concat(
[[bottomOffset,bottomOffset+1,bottomOffset+2],
[bottomOffset,bottomOffset+2,bottomOffset+3]]);
/*------------ bring together --------------*/
triangleArray.push(triangleArray[triangleArray.length-1]);
for (var i=0;i<pointArray.length;i++){
for (var k=0;k<=2;k++) {
pointArray[i][k] = Math.round((pointArray[i][k])*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(pointArray));
for (let i=0;i<pointArray.length;i++) {
finalArray.push([-pointArray[i][0],pointArray[i][1],pointArray[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+pointArray.length,triangleArray[i][0]+pointArray.length,triangleArray[i][2]+pointArray.length]);
}
var mainPoly = polyhedron({
points: finalArray,
polygons: finalTriangleArray
});
return mainPoly;
}
function make_concave_kick_offset(moldWidth, kickRadius, kickAngle, kickBaseDrop, kickRadiusEdge, kickAngleEdge, kickLength, moldHeight, kcRes, offset) {
var deckWidth = moldWidth;
/* var kickRadius = 4;
var kickAngle = 20;
var kickBaseDrop = 0.125;
var kickTipDrop = 0.25;
var kickRadiusEdge = 5;
var kickAngleEdge = 21;
var kickLength = 7+1;
var moldHeight = 4;*/
var y_max = kickLength;
var x_max = deckWidth/2;
var stepsPerY = 24+kcRes; //how many iterations are done until we move onto next y value
var stepsPerX = 8+kcRes; //how many iterations done until move onto next x value
var y_res = y_max/stepsPerY;
var x_res= x_max/stepsPerX;
var pointArray = [];
var subArray =[];
var x;
var y;
var z;
var zRad; //radius of curve from zc to ze
var coord; //point coordinates in x,y,z
var i; //keep track of iterations
var transitionZc;
var transitionZe;
var transitionYc;
var transitionYe;
var zc;
var ze;
var offsetArray = []; //array of points that will be offset
var xcounter=0; //keeps track whenever we change to a next x value
for (y=0; y<=y_max; y=y+y_res) { //as we move from kick base to tip
xcounter=0;
if (y<=(kickRadius*sin(kickAngle))) { //get zc and ze first
zc = kickRadius-sqrt((pow(kickRadius,2)-pow(y,2))); // get zc in radius section
transitionZc = zc; //save last zc before change
transitionYc = y;
}
else {
zc = (kickRadius - (kickRadius*cos(kickAngle)))+((y-kickRadius*sin(kickAngle))*tan(kickAngle)); //get zc in stratight section
}
if (y<=(kickRadiusEdge*sin(kickAngleEdge))) {
ze = kickBaseDrop+kickRadiusEdge-sqrt((pow(kickRadiusEdge,2)-pow(y,2))); //ze in radius section
transitionZe = ze; //save last ze before change
transitionYe = y;
}
else {
ze = (kickBaseDrop+kickRadiusEdge - (kickRadiusEdge*cos(kickAngleEdge)))+((y-kickRadiusEdge*sin(kickAngleEdge))*tan(kickAngleEdge)); //ze in straight section
}
//now that we have zc and ze, we can find the z values in between, at specific x values
for (x=0; x<=x_max; x=x+x_res) {
xcounter+=1;
zRad = (pow(x_max,2)+pow((ze-zc),2))/(2*(ze-zc)); //establish the radius of the curve along the x axis
z = zc + zRad - sqrt(pow(zRad,2)-pow(x,2));
coord = [x,y,z];
pointArray.push(coord);
if (x!==x_max){
if (x+x_res>x_max) {
x=x_max-x_res;
}
}
}
if (y!==y_max){
if (y+y_res>y_max) {
y=y_max-y_res;
}
}
}
var finalZc = zc;
var finalZe = ze;
var triangleArray = [];
var a=0;
var b=1;
var i;
var maxTriangleArray = pointArray.length-stepsPerX-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerX+1) {
for (a=i;a<(i+stepsPerX);a++) {
triangleArray.push([(a),(a+1),(stepsPerX+a+1)]);
if ((a+1)<=(i+stepsPerX)) {
triangleArray.push([(stepsPerX+a+2),(stepsPerX+a+1),a+1]);
}
}
}
for (let i = 0; i < (pointArray.length); i+=xcounter) {
const chunk = pointArray.slice(i, i+xcounter);
offsetArray.push(chunk);
}
//our "offsetArray" is now an array of arrays split whenever we iterate the x value.
var offsetPoints = JSON.parse(JSON.stringify(pointArray)); //offsetPoints will be the array of points we offset, while offsetArray is used for keeping track
var last_x = -1;
var last_y = -1;
var last_z = 0;
var last_zy = 0;
var x_offset, y_offset, z_offset;
var phi; //angle of offset point against x axis
var beta; //angle of offset point against y axis
//the difference from the last point to the current point for generating normals
var delta_x;
var delta_z;
var delta_z;
var current_x, current_y, current_z;
var j=0;
var offsetYePts = []; //offset edge points
var offsetYcPts = []; //offset center points
var offsetYtPts = [];
var offsetTipPts = [];
for (let i=0; i < pointArray.length; i++) { //as we move to each point
//offset the x value
j = i-1;
current_x = pointArray[i][0]; // get the current x value
current_y = pointArray[i][1]; //get the current y value
current_z = pointArray[i][2]; // get the current z value we calculated earlier
// to find last_z:
if(current_x == 0) {
last_z = current_z; //we are at the edge and we want phi to be 0;
last_x = -1;
}
else {
last_z = pointArray[j][2]; //the previous point's z value
last_x = pointArray[j][0]; //the previous point's x value
}
delta_x = current_x-last_x;
delta_z = current_z-last_z;
phi = abs(90-atan(delta_z/delta_x));
if (phi == 90) {
phi = 0; //to prevent infinity/NaN
}
//to find the previous y value and z value when x was the same
if (current_y == 0) {
last_y = -1;
last_zy = current_z;
}
else if (current_y == y_max){
last_y = y_max-y_res;
last_zy = pointArray[i-xcounter][2];
}
else {
last_y = current_y - y_res;
last_zy = pointArray[i-xcounter][2];
}
delta_zy = current_z - last_zy;
delta_y = current_y - last_y; //along y-axis, not along x
beta = abs(90-atan(delta_zy/delta_y));
if (beta == 90) {
beta = 0; //to prevent infinity/NaN
}
/* --------------*/
var x_component = 1/Math.pow(tan(phi),2);
var y_component = 1/Math.pow(tan(beta),2);
if (!isFinite(x_component)) {
x_component=0;
}
if (!isFinite(y_component)) {
y_component=0;
}
z_offset = sqrt(Math.pow(offset,2)/(x_component+y_component+1));
x_offset = z_offset/tan(phi);
y_offset = z_offset/tan(beta);
if (!isFinite(x_offset)) {
x_offset=0;
}
if (!isFinite(y_offset)) {
y_offset = 0;
}
if (z_offset == 0) {
z_offset=offset;
}
offsetPoints[i][0] += x_offset;
offsetPoints[i][1] += y_offset;
offsetPoints[i][2] -= z_offset;
if (current_x == x_max) { //ye pts
offsetYePts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_x == 0) { //yc pts
offsetYcPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == 0) { //transition pts
offsetYtPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == y_max) {
offsetTipPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
}
var offsetPointsGroupedRef = JSON.parse(JSON.stringify(offsetPoints));
var offsetPointsGrouped = [];
for (let i = 0; i < (offsetPointsGroupedRef.length); i+=xcounter) {
const chunk = offsetPointsGroupedRef.slice(i, i+xcounter);
offsetPointsGrouped.push(chunk);
}
/*--------- ye -------------*/
offsetYePts.push([x_max,y_max,moldHeight],[x_max,0,moldHeight]);
var offsetYeTriangles = [];
for (i=0; i<(offsetYePts.length-2);i++) {
offsetYeTriangles.push([i,offsetYePts.length-1,i+1]);
}
for (var k=0; k<offsetYeTriangles.length; k++){
offsetYeTriangles[k][0]+=offsetPoints.length;
offsetYeTriangles[k][1]+=offsetPoints.length;
offsetYeTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYePts);
triangleArray = triangleArray.concat(offsetYeTriangles);
/*--------- yc --------------*/
/*offsetYcPts.push([0,y_max,moldHeight],[0,0,moldHeight]);
var offsetYcTriangles = [];
for (i=0; i<(offsetYcPts.length-2);i++) {
offsetYcTriangles.push([offsetYcPts.length-1,i,i+1]);
}
for (var k=0; k<offsetYcTriangles.length; k++){
offsetYcTriangles[k][0]+=offsetPoints.length;
offsetYcTriangles[k][1]+=offsetPoints.length;
offsetYcTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYcPts);
triangleArray = triangleArray.concat(offsetYcTriangles);
/*--------- transition ----------*/
offsetYtPts.push([x_max,0,moldHeight],[0,0,moldHeight]);
var offsetYtTriangles = [];
for (i=0; i<(offsetYtPts.length-2);i++) {
offsetYtTriangles.push([i,offsetYtPts.length-1,i+1]);
}
for (var k=0; k<offsetYtTriangles.length; k++){
offsetYtTriangles[k][0]+=offsetPoints.length;
offsetYtTriangles[k][1]+=offsetPoints.length;
offsetYtTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYtPts);
triangleArray = triangleArray.concat(offsetYtTriangles);
/*--------- tip ---------------*/
offsetTipPts.push([x_max,y_max,moldHeight],[0,y_max,moldHeight]);
var offsetTipTriangles = [];
for (i=0; i<(offsetTipPts.length-2);i++) {
offsetTipTriangles.push([offsetTipPts.length-1,i,i+1]);
}
for (var k=0; k<offsetTipTriangles.length; k++){
offsetTipTriangles[k][0]+=offsetPoints.length;
offsetTipTriangles[k][1]+=offsetPoints.length;
offsetTipTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetTipPts);
triangleArray = triangleArray.concat(offsetTipTriangles);
/*---------- bottom ------------*/
var bottomPts = [[0,0,moldHeight],[x_max,0,moldHeight],[x_max,y_max,moldHeight],[0,y_max,moldHeight]];
bottomTriangles = [[0,2,1],[0,3,2]];
for (var k=0; k<bottomTriangles.length; k++){
bottomTriangles[k][0]+=offsetPoints.length;
bottomTriangles[k][1]+=offsetPoints.length;
bottomTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(bottomPts);
triangleArray = triangleArray.concat(bottomTriangles);
/*------------ bring together --------------*/
for (var i=0;i<offsetPoints.length;i++){
for (var k=0;k<=2;k++) {
offsetPoints[i][k] = Math.round((offsetPoints[i][k])*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(offsetPoints));
for (let i=0;i<offsetPoints.length;i++) {
finalArray.push([-offsetPoints[i][0],offsetPoints[i][1],offsetPoints[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+offsetPoints.length,triangleArray[i][0]+offsetPoints.length,triangleArray[i][2]+offsetPoints.length]);
}
var resultOffset = polyhedron({
points: finalArray,
polygons: finalTriangleArray
});
return resultOffset.translate([0,0,offset]);
}
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); //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_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)));
}
*/
// 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);
var reg_half_angle = Math.round(asin((width/2)/reg_radius)*10000)/10000;
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);
return result;
}
function make_mold_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: [
/*[Math.round((reg_radius*sin(reg_segment_angle*12))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*12))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*11))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*11))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*10))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*10))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*9))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*9))*100000000000)/100000000000],*/
[Math.round((reg_radius*sin(reg_segment_angle*8))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*8))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*7))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*7))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*6))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*6))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*5))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*5))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*4))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*4))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*3))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*3))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*2))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*2))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*1))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*1))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*0))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*0))*100000000000)/100000000000],
[Math.round((reg_radius*sin(reg_segment_angle*0))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*0))*100000000000)/100000000000-5],
[Math.round((reg_radius*sin(reg_segment_angle*8))*100000000000)/100000000000,Math.round((reg_radius*cos(reg_segment_angle*8))*100000000000)/100000000000-5]
/*
[(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_mold_transition_section_new(transition_length, thickness, slice_thickness, width, min_radius, number_of_segments,model_res, kick_base_drop)
{
var section_depth=thickness;
var y_max = transition_length;
var x_max = width/2;
var concave_depth = (2*min_radius-sqrt(pow(2*min_radius,2)-(4*1*pow(width,2)/4)))/(2*1);
var stepsPerY = model_res; //how many iterations are done until we move onto next y value
var stepsPerX = model_res; //how many iterations done until move onto next x value
var xStepSize = x_max/stepsPerX;
// 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
//the direction of i is the direction of y
var i_size = i_range/stepsPerY;
var origin_x = 0;
var origin_y = 0;
var a = 0; //initial t value of Bezier
var x0 = 0;
var x1 = transition_length/4;
var x2 = transition_length*(2/3);
var x3 = transition_length;
var y0 = kick_base_drop;
var y1 = kick_base_drop;
var y2 = concave_depth;
var y3 = concave_depth;
var z;
var slice_adj = 0;
var x_val_last = 0;
var transition_points = [];
if (kick_base_drop == 0){
a = a+i_size; //prevent dividing by 0
for (var i=0; i <= x_max; i=i+xStepSize) {
transition_points.push([i,0,0]);
}
}
var concave_array = []; /*this is the last array of points along the x-axis (width) before the concave section*/
var kick_array= []; /*this is the first array of points along the x-axis (y=0), needed for kick base drop*/
var bezier_array = [[width/2,0,0]]; /*array of points along edge of bezier curve*/
for (var i = a; i < (i_range+i_size); i=i+i_size) //starting at 0, going until 1, increment at i_size
{
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); //actually the position along y
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); //actually the z height
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/stepsPerX/2;
var counter = 0;
for (var j=0; j <= x_max; j=j+xStepSize) {
z = Math.round(tan(reg_segment_angle*counter)*(j)*1000)/1000;
transition_points.push([j,x_val,z]);
if (t==0) {
kick_array.push([j,x_val,z]);
}
if (t==1) {
concave_array.push([j,x_val,z]);
}
if (j == x_max) {
bezier_array.push([j,x_val,z]);
}
counter++;
}
}
var triangleArray = [];
var c=0;
var b=1;
var i;
var maxTriangleArray = transition_points.length-stepsPerX-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerX+1) {
for (c=i;c<(i+stepsPerX);c++) {
triangleArray.push([(c),(c+1),(stepsPerX+c+1)]);
if ((c+1)<=(i+stepsPerX)) {
triangleArray.push([(stepsPerX+c+2),(stepsPerX+c+1),c+1]);
}
}
}
/*var result1= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
});
*/
/* ------------ kick side --------*/
if (kick_base_drop !== 0) {
var kick_side_points = kick_array; /*get just the points along
the curve, which will vary with resolution.*/
var kick_array_length = kick_side_points.length;
kick_array.push([0,0,section_depth]);
kick_array.push([width/2,0,section_depth]);
var kickSideTriangles = [];
for (var j=0; j<kick_array_length-1; j++) {
kickSideTriangles.push([j+1,j,kick_array_length]);
}
kickSideTriangles.push([kick_array_length-1,kick_array.length-2,kick_array.length-1]);
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=transition_points.length;
kickSideTriangles[k][1]+=transition_points.length;
kickSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(kick_array);
triangleArray = triangleArray.concat(kickSideTriangles);
}
else {
var kickSidePoints = [
[0,0,0],
[width/2,0,0],
[0,0,section_depth],
[width/2,0,section_depth]
];
var kickSideTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=transition_points.length;
kickSideTriangles[k][1]+=transition_points.length;
kickSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(kickSidePoints);
triangleArray = triangleArray.concat(kickSideTriangles);
}
/* var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor(255,255,255);
return result;
*/
/* ------------ center of transition section --------*/
/*var transitionCenterPoints = [
[0,0,0],
[0,transition_length,0],
[0,0,section_depth],
[0,transition_length,section_depth]
];
var transitionCenterTriangles = [
[0,1,2],
[1,3,2]
];
for (var k=0; k<(transitionCenterTriangles.length); k++){
transitionCenterTriangles[k][0]+=transition_points.length;
transitionCenterTriangles[k][1]+=transition_points.length;
transitionCenterTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(transitionCenterPoints);
triangleArray = triangleArray.concat(transitionCenterTriangles);
/* var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor(255,255,255);
return result;*/
/* ------------ concave end of transition section --------*/
//points are concave_array points, plus the border points, which are added below:
var concave_array_curve_points = concave_array; /*get just the points along
the curve, which will vary with resolution.*/
var curve_array_length = concave_array_curve_points.length;
concave_array.push([0,transition_length,section_depth]);
concave_array.push([width/2,transition_length,section_depth]);
var concaveSideTriangles = [];
for (var j=0; j<curve_array_length-1; j++) {
concaveSideTriangles.push([j,j+1,curve_array_length]);
}
concaveSideTriangles.push([curve_array_length-1,concave_array.length-1,concave_array.length-2]);
/* var result=polyhedron({
points: concave_array,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(concaveSideTriangles.length); k++){
concaveSideTriangles[k][0]+=transition_points.length;
concaveSideTriangles[k][1]+=transition_points.length;
concaveSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(concave_array);
triangleArray = triangleArray.concat(concaveSideTriangles);
var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor(255,255,255);
/* ------------ edge of transition section (along bezier) --------*/
//points are bezier_array points, plus the border points, which are added below:
var bezier_array_length = bezier_array.length; /*first, store the value of */
bezier_array.push([width/2,0,section_depth]);
bezier_array.push([width/2,transition_length,section_depth]);
var bezierTriangles = [];
for (var j=0; j<bezier_array_length-1; j++) {
bezierTriangles.push([bezier_array_length,j+1,j]);
}
bezierTriangles.push([bezier_array.length-2,bezier_array.length-1,bezier_array_length-1]);
/* var result=polyhedron({
points: concave_array,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(bezierTriangles.length); k++){
bezierTriangles[k][0]+=transition_points.length;
bezierTriangles[k][1]+=transition_points.length;
bezierTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(bezier_array);
triangleArray = triangleArray.concat(bezierTriangles);
/* var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor(255,255,255);
return result;*/
/* ------------ bottom --------*/
var bottomPoints = [
[0,0,section_depth],
[width/2,0,section_depth],
[0,transition_length,section_depth],
[width/2,transition_length,section_depth]
];
var bottomTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(bottomTriangles.length); k++){
bottomTriangles[k][0]+=transition_points.length;
bottomTriangles[k][1]+=transition_points.length;
bottomTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(bottomPoints);
triangleArray = triangleArray.concat(bottomTriangles);
for (let i=0; i<transition_points.length;i++) {
for (let j=0; j<3; j++) {
transition_points[i][j] = Math.round(transition_points[i][j]*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(transition_points));
for (let i=0;i<transition_points.length;i++) {
finalArray.push([-transition_points[i][0],transition_points[i][1],transition_points[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+transition_points.length,triangleArray[i][0]+transition_points.length,triangleArray[i][2]+transition_points.length]);
}
var result= polyhedron({ //
points: finalArray, //
triangles: finalTriangleArray // two triangles for square base
}).setColor(0.9,0.9,0.9);
//result = result.union(mirror([1,0,0],result));
result = rotate([180,0,-90],result);
result = result.translate([0,0,0]);
return result; //radial transition section
}
function make_mold_transition_section_offset(transition_length, thickness, slice_thickness, width, min_radius, number_of_segments,model_res, kick_base_drop, offset)
{
var section_depth=thickness-offset;
var y_max = transition_length;
var x_max = width/2;
var concave_depth = (2*min_radius-sqrt(pow(2*min_radius,2)-(4*1*pow(width,2)/4)))/(2*1);
var stepsPerY = model_res; //how many iterations are done until we move onto next y value
var stepsPerX = model_res; //how many iterations done until move onto next x value
var xStepSize = x_max/stepsPerX;
// 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
//the direction of i is the direction of y
var i_size = i_range/stepsPerY;
var origin_x = 0;
var origin_y = 0;
var a = 0; //initial t value of Bezier
var x0 = 0;
var x1 = transition_length/4;
var x2 = transition_length*(2/3);
var x3 = transition_length;
var y0 = kick_base_drop;
var y1 = kick_base_drop;
var y2 = concave_depth;
var y3 = concave_depth;
var z;
var slice_adj = 0;
var x_val_last = 0;
var transition_points = [];
if (kick_base_drop == 0){
a = a+i_size; //prevent dividing by 0
for (var i=0; i <= x_max; i=i+xStepSize) {
transition_points.push([i,0,0]);
}
}
var concave_array = []; /*this is the last array of points along the x-axis (width) before the concave section*/
var kick_array= []; /*this is the first array of points along the x-axis (y=0), needed for kick base drop*/
var bezier_array = [[width/2,0,0]]; /*array of points along edge of bezier curve*/
var offsetArray = []; //array of points that will be offset
for (var i = a; i < (i_range+i_size); i=i+i_size) //starting at 0, going until 1, increment at i_size
{
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); //actually the position along y
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); //actually the z height
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/stepsPerX/2;
var counter = 0;
for (var j=0; j <= x_max; j=j+xStepSize) {
z = Math.round(tan(reg_segment_angle*counter)*(j)*1000)/1000;
transition_points.push([j,x_val,z]);
if (t==0) {
kick_array.push([j,x_val,z]);
}
if (t==1) {
concave_array.push([j,x_val,z]);
}
if (j == x_max) {
bezier_array.push([j,x_val,z]);
}
counter++;
}
}
var triangleArray = [];
var c=0;
var b=1;
var i;
var maxTriangleArray = transition_points.length-stepsPerX-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerX+1) {
for (c=i;c<(i+stepsPerX);c++) {
triangleArray.push([(c),(c+1),(stepsPerX+c+1)]);
if ((c+1)<=(i+stepsPerX)) {
triangleArray.push([(stepsPerX+c+2),(stepsPerX+c+1),c+1]);
}
}
}
for (let i = 0; i < (transition_points.length); i+=(counter)) {
const chunk = transition_points.slice(i, i+(counter));
offsetArray.push(chunk);
}
console.log(transition_points);
var mainPoly = polyhedron({ //
points: transition_points, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.9,0.9]);
var shiftedPoly = (polyhedron({ //
points: transition_points, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.2,0.2])).translate([0,0,-offset]);
/*var result1= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
});
*/
//our "offsetArray" is now an array of arrays split whenever we iterate the x value.
var y_max=transition_length;
var offsetPoints = JSON.parse(JSON.stringify(transition_points)); //offsetPoints will be the array of points we offset, while offsetArray is used for keeping track
var last_x = -1;
var last_y = -1;
var last_z = 0;
var last_zy = 0;
var x_offset, y_offset, z_offset;
var phi; //angle of offset point against x axis
var beta; //angle of offset point against y axis
//the difference from the last point to the current point for generating normals
var delta_x;
var delta_z;
var delta_z;
var current_x, current_y, current_z;
var j=0;
var offsetYePts = []; //offset edge points
var offsetYcPts = []; //offset center points
var offsetYtPts = [];
var offsetTipPts = [];
var last_y=-1;
for (let i=0; i < transition_points.length; i++) { //as we move to each point
//offset the x value
j = i-1;
current_x = transition_points[i][0]; // get the current x value
current_y = transition_points[i][1]; //get the current y value
current_z = transition_points[i][2]; // get the current z value we calculated earlier
// to find last_z:
if(current_x == 0) {
last_z = current_z; //we are at the edge and we want phi to be 0;
last_x = -1;
}
else {
last_z = transition_points[j][2]; //the previous point's z value
last_x = transition_points[j][0]; //the previous point's x value
}
delta_x = current_x-last_x;
delta_z = current_z-last_z;
phi = abs(90-atan(delta_z/delta_x));
if (phi == 90) {
phi = 0; //to prevent infinity/NaN
}
//to find the previous y value and z value when x was the same
if (current_y == 0) {
last_y = -1;
last_zy = current_z;
}
else if (current_y == y_max){
last_y = transition_points[i-counter][1];
last_zy = current_z;
/*console.log('current zy and last zy is ' + current_z + ' ' + last_zy);
console.log('current zx and last zx is ' + current_z + ' ' + last_z);*/
}
else {
last_y = transition_points[i-counter][1];
last_zy = transition_points[i-counter][2];
}
delta_zy = current_z - last_zy;
delta_y = current_y - last_y; //along y-axis, not along x
beta = abs(atan(delta_zy/delta_y));
if (beta == 90) {
beta = 0; //to prevent infinity/NaN
}
/*if (current_y == y_max){
console.log('phi and beta');
console.log(phi);
console.log(beta);
}*/
/* --------------*/
var x_component = 1/Math.pow(tan(phi),2);
var y_component = Math.pow(tan(beta),2);
if (!isFinite(x_component)) {
x_component=0;
}
if (!isFinite(y_component)) {
y_component=0;
}
z_offset = sqrt(Math.pow(offset,2)/(x_component+y_component+1));
x_offset = z_offset/tan(phi);
y_offset = z_offset*tan(beta);
if (!isFinite(x_offset)) {
x_offset=0;
}
if (!isFinite(y_offset)) {
y_offset = 0;
}
if (z_offset == 0) {
z_offset=offset;
}
offsetPoints[i][0] += x_offset;
offsetPoints[i][1] += y_offset;
offsetPoints[i][2] -= z_offset;
console.log('x and y');
console.log(current_x + ' ' + current_y);
console.log('phi and beta');
console.log(phi + ' ' + beta);
console.log('offset points:');
console.log(offsetPoints[i]);
if (current_x == x_max) { //ye pts
offsetYePts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_x == 0) { //yc pts
offsetYcPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == 0) { //transition pts
offsetYtPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == y_max) {
offsetTipPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
last_y=current_y;
}
var offsetPointsGroupedRef = JSON.parse(JSON.stringify(offsetPoints));
var offsetPointsGrouped = [];
for (let i = 0; i < (offsetPointsGroupedRef.length); i+=counter) {
const chunk = offsetPointsGroupedRef.slice(i, i+counter);
offsetPointsGrouped.push(chunk);
}
console.log(offsetPoints); //findme
var testPoly = polyhedron({ //
points: offsetPoints, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.9,0.9]);
// return [color([0.1,0.8,0.95],testPoly),mainPoly, shiftedPoly];
/* ------------ kick end --------*/
if (kick_base_drop !== 0) {
var kick_side_points = offsetYtPts; /*get just the points along
the curve, which will vary with resolution.*/
var kick_array_length = kick_side_points.length;
offsetYtPts.push([0,0,section_depth]);
offsetYtPts.push([width/2,0,section_depth]);
var kickSideTriangles = [];
for (var j=0; j<kick_array_length-1; j++) {
kickSideTriangles.push([j+1,j,kick_array_length]);
}
kickSideTriangles.push([kick_array_length-1,offsetYtPts.length-2,offsetYtPts.length-1]);
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=offsetPoints.length;
kickSideTriangles[k][1]+=offsetPoints.length;
kickSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYtPts);
triangleArray = triangleArray.concat(kickSideTriangles);
}
else {
var kickSidePoints = [
[0,0,-offset],
[width/2,0,-offset],
[0,0,section_depth],
[width/2,0,section_depth]
];
var kickSideTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=offsetPoints.length;
kickSideTriangles[k][1]+=offsetPoints.length;
kickSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(kickSidePoints);
triangleArray = triangleArray.concat(kickSideTriangles);
}
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor(0.5,0.9,0.95);
return result; */
/* ------------ center of transition section --------*/
/* var transitionCenterPoints = [
[0,0,-offset],
[0,transition_length,-offset],
[0,0,section_depth],
[0,transition_length,section_depth]
];
var transitionCenterTriangles = [
[0,1,2],
[1,3,2]
];
for (var k=0; k<(transitionCenterTriangles.length); k++){
transitionCenterTriangles[k][0]+=offsetPoints.length;
transitionCenterTriangles[k][1]+=offsetPoints.length;
transitionCenterTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(transitionCenterPoints);
triangleArray = triangleArray.concat(transitionCenterTriangles);
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor(0.5,0.5,0.99);
return result;
*/
/* ------------ concave end of transition section --------*/
//points are concave_array points, plus the border points, which are added below:
var concave_array_curve_points = offsetTipPts; /*get just the points along
the curve, which will vary with resolution.*/
var curve_array_length = concave_array_curve_points.length;
offsetTipPts.push([0,transition_length,section_depth]);
offsetTipPts.push([width/2,transition_length,section_depth]);
var concaveSideTriangles = [];
for (var j=0; j<curve_array_length-1; j++) {
concaveSideTriangles.push([j,j+1,curve_array_length]);
}
concaveSideTriangles.push([curve_array_length-1,offsetTipPts.length-1,offsetTipPts.length-2]);
/* var result=polyhedron({
points: offsetTipPts,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(concaveSideTriangles.length); k++){
concaveSideTriangles[k][0]+=offsetPoints.length;
concaveSideTriangles[k][1]+=offsetPoints.length;
concaveSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetTipPts);
triangleArray = triangleArray.concat(concaveSideTriangles);
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor(0.5,0.95,0.99);
return result;
*/
/* ------------ edge of transition section (along bezier) --------*/
//points are bezier_array points, plus the border points, which are added below:
var bezier_array_length = offsetYePts.length; /*first, store the value of */
offsetYePts.push([width/2,0,section_depth]);
offsetYePts.push([width/2,transition_length,section_depth]);
var bezierTriangles = [];
for (var j=0; j<bezier_array_length-1; j++) {
bezierTriangles.push([bezier_array_length,j+1,j]);
}
bezierTriangles.push([offsetYePts.length-2,offsetYePts.length-1,bezier_array_length-1]);
/* var result=polyhedron({
points: offsetTipPts,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(bezierTriangles.length); k++){
bezierTriangles[k][0]+=offsetPoints.length;
bezierTriangles[k][1]+=offsetPoints.length;
bezierTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYePts);
triangleArray = triangleArray.concat(bezierTriangles);
/* var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor(0.8,0.99,0.99);
return result;*/
/* ------------ bottom --------*/
var bottomPoints = [
[0,0,section_depth],
[width/2,0,section_depth],
[0,transition_length,section_depth],
[width/2,transition_length,section_depth]
];
var bottomTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(bottomTriangles.length); k++){
bottomTriangles[k][0]+=offsetPoints.length;
bottomTriangles[k][1]+=offsetPoints.length;
bottomTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(bottomPoints);
triangleArray = triangleArray.concat(bottomTriangles);
for (let i=0; i<offsetPoints.length;i++) {
for (let j=0; j<3; j++) {
offsetPoints[i][j] = Math.round(offsetPoints[i][j]*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(offsetPoints));
for (let i=0;i<offsetPoints.length;i++) {
finalArray.push([-offsetPoints[i][0],offsetPoints[i][1],offsetPoints[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+offsetPoints.length,triangleArray[i][0]+offsetPoints.length,triangleArray[i][2]+offsetPoints.length]);
}
var result= polyhedron({ //
points: finalArray, //
triangles: finalTriangleArray // two triangles for square base
}).setColor(0.9,0.9,0.9);
//result = result.union(mirror([1,0,0],result));
result = rotate([180,0,-90],result);
result = result.translate([0,0,-offset]);
return result; //radial transition section offset
}
function make_tub_transition_section_offset(transition_length, thickness, slice_thickness, width, deck_width, tub_rad, number_of_segments, model_res, kick_base_drop, flat_width, concave_drop, mold_height, tub_res, offset)
{
var section_depth=mold_height-offset;
var y_max = transition_length;
var x_max = width/2;
var res = 100; //resolution of bezier curves
var x_res = tub_res;
/*The following equations were derived on a piece of paper, using tan(tub_angle) = (concave_drop - tub_rad + tub_rad*cos(tub_angle))/(deck_width/2 - flat_width/2 - tub_rad*sin(tub_angle)) and some trig identities: sin^2(x) + cos^2(x) = 1. This website was helpful: https://www.symbolab.com/solver/trigonometric-simplification-calculator
*/
var a = Math.pow(concave_drop-tub_rad,2)+Math.pow((deck_width/2 - flat_width/2),2);
var b = 2*tub_rad*(concave_drop-tub_rad);
var c = Math.pow(tub_rad,2)-Math.pow(deck_width/2 - flat_width/2, 2);
var tub_angle = acos((-b + sqrt(Math.pow(b,2) - 4*a*c))/(2*a));
var x = x_max;
var concave_depth;
if (x<flat_width/2) {
concave_depth = 0;
}
else {
if (x<=(tub_rad*sin(tub_angle))) {
concave_depth = (tub_rad-sqrt((pow(tub_rad,2)-pow((x),2))));
}
else {
concave_depth = ((tub_rad - (tub_rad*cos(tub_angle)))+(((x)-tub_rad*sin(tub_angle))*tan(tub_angle)));
}
}
var stepsPerY = model_res; //how many iterations are done until we move onto next y value
var stepsPerX = (width/2)/x_res; //how many iterations done until we move onto next x value
var xStepSize = x_res;
//console.log('y res = ' + stepsPerY);
// 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
//the direction of i is the direction of y
var i_size = i_range/stepsPerY;
var origin_x = 0;
var origin_y = 0;
var a = 0; //initial t value of Bezier
var x0 = 0;
var x1 = transition_length/4;
var x2 = transition_length*(2/3);
var x3 = transition_length;
/*var y0 = kick_base_drop;
var y1 = kick_base_drop;
var y2 = concave_depth;
var y3 = concave_depth;*/
var z;
var slice_adj = 0;
var x_val_last = 0;
var transition_points = [];
var kBR = (Math.pow(kick_base_drop,2)+Math.pow(width/2,2))/(2*kick_base_drop); //kick base radius
if (!isFinite(kBR)) {
kBR = 0;
}
var concave_array = []; /*this is the last array of points along the x-axis (width) before the concave section*/
var kick_array= []; /*this is the first array of points along the x-axis (y=0), needed for kick base drop*/
var bezier_array = [[width/2,0,0]]; /*array of points along edge of bezier curve*/
var x_tub = 0;
var offsetArray = []; //array of points that will be offset
var counter;
for (x=0; x<=width/2; x+=x_res) { //
counter=0;
var y0 = kBR - kBR*cos(asin(x/kBR));
if (!isFinite(y0)) {
y0 = 0;
}
var y1 = y0;
var concave_drop_x; //concave drop along x width
if (x<flat_width/2) {
concave_drop_x = 0;
}
else {
if (x_tub<=(tub_rad*sin(tub_angle))) {
concave_drop_x = (tub_rad-sqrt((pow(tub_rad,2)-pow((x_tub),2))));
}
else {
concave_drop_x = ((tub_rad - (tub_rad*cos(tub_angle)))+(((x_tub)-tub_rad*sin(tub_angle))*tan(tub_angle)));
}
x_tub += x_res;
}
var y2 = concave_drop_x;
var y3 = y2;
for (var i = a; i < (i_range+i_size); i=i+i_size)
{
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); //actually the position along y
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); //actually the z height
x_val = Math.round(x_val*1000)/1000;
y_val = Math.round(y_val*1000)/1000;
x = Math.round(x*100000)/100000;
z = y_val;
transition_points.push([x,x_val,z]);
if (t==0) {
kick_array.push([x,x_val,z]);
}
if (t==1) {
concave_array.push([x,x_val,z]);
}
if (x == x_max) {
bezier_array.push([x,x_val,z]);
}
}
counter++;
}
var triangleArray = [];
var c=0;
var b=1;
var i;
var maxTriangleArray = transition_points.length-stepsPerY-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerY+1) {
for (c=i;c<(i+stepsPerY);c++) {
triangleArray.push([(c+1),(c),(stepsPerY+c+1)]);
if ((c+1)<=(i+stepsPerY)) {
triangleArray.push([(stepsPerY+c+1),(stepsPerY+c+2),c+1]);
}
}
}
for (let i = 0; i < (transition_points.length); i+=(counter)) {
const chunk = transition_points.slice(i, i+(counter));
offsetArray.push(chunk);
}
var result1= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
});
var ptArray = [];
console.log('og');
console.log(transition_points);
var mainPoly = polyhedron({ //
points: transition_points, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.9,0.9]);
var shiftedPoly = (polyhedron({ //
points: transition_points, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.8,0.2,0.8])).translate([0,0,-offset]);
//our "offsetArray" is now an array of arrays split whenever we iterate the x value.
var y_max=transition_length;
var offsetPoints = JSON.parse(JSON.stringify(transition_points)); //offsetPoints will be the array of points we offset, while offsetArray is used for keeping track
var last_x = -1;
var last_y = -1;
var last_z = 0;
var last_zy = 0;
var x_offset, y_offset, z_offset;
var phi; //angle of offset point against x axis
var beta; //angle of offset point against y axis
//the difference from the last point to the current point for generating normals
var delta_x;
var delta_z;
var delta_z;
var current_x, current_y, current_z;
var j=0;
var offsetYePts = []; //offset edge points
var offsetYcPts = []; //offset center points
var offsetYtPts = [];
var offsetTipPts = [];
var last_y=-1;
console.log('counter is ' + counter);
for (let i=0; i < transition_points.length; i++) { //as we move to each point
//offset the x value
j = i-1;
current_x = transition_points[i][0]; // get the current x value
current_y = transition_points[i][1]; //get the current y value
current_z = transition_points[i][2]; // get the current z value we calculated earlier
// to find last_z:
if(current_x == 0) {
last_z = current_z; //we are at the edge and we want phi to be 0;
last_x = -1;
}
else {
last_x = transition_points[i-(1+stepsPerY)][0]
last_z = transition_points[i-(1+stepsPerY)][2]
}
delta_x = current_x-last_x;
delta_z = current_z-last_z;
phi = abs(90-atan(abs(delta_z/delta_x)));
if (phi == 90) {
phi = 0; //to prevent infinity/NaN
}
//to find the previous y value and z value when x was the same
if (current_y == 0) {
last_y = -1;
last_zy = current_z;
}
else if (current_y == y_max){
last_y = transition_points[j][1];
last_zy = current_z; // 6/8/22
}
else {
//last_y = current_y - y_res;
last_y = transition_points[j][1];
last_zy = transition_points[j][2];
}
delta_zy = current_z - last_zy;
delta_y = current_y - last_y; //along y-axis, not along x
/*console.log('x and y comparison');
console.log(current_x + ' ' + last_x);
console.log(current_y + ' ' + last_y);
console.log('(' + current_x + ',' + current_y + ')');
console.log(delta_z + ' ' + delta_zy);
*/
beta = abs(atan((abs(delta_zy/delta_y))));
if (beta == 90) {
beta = 0; //to prevent infinity/NaN
}
/* --------------*/
var x_component = 1/Math.pow(tan(phi),2);
var y_component = Math.pow(tan(beta),2);
if (!isFinite(x_component)) {
x_component=0;
}
if (!isFinite(y_component)) {
y_component=0;
}
if (delta_zy/delta_z !== abs(delta_zy/delta_z)) {
}
z_offset = sqrt(Math.pow(offset,2)/(x_component+y_component+1));
x_offset = z_offset/tan(phi);
y_offset = z_offset*tan(beta);
if (!isFinite(x_offset)) {
x_offset=0;
}
if (!isFinite(y_offset)) {
y_offset = 0;
}
if (z_offset == 0) {
z_offset=offset;
}
/*console.log('phi ' + phi);
console.log('x_offset: ' + x_offset);
*/
offsetPoints[i][0] += x_offset;
offsetPoints[i][1] += y_offset;
offsetPoints[i][2] -= z_offset;
if (current_x == x_max) { //ye pts
offsetYePts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_x == 0) { //yc pts
offsetYcPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == 0) { //transition pts
offsetYtPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
if (current_y == y_max) {
offsetTipPts.push([current_x+x_offset,current_y+y_offset,current_z-z_offset]);
}
last_y=current_y;
}
var offsetPointsGroupedRef = JSON.parse(JSON.stringify(offsetPoints));
var offsetPointsGrouped = [];
for (let i = 0; i < (offsetPointsGroupedRef.length); i+=counter) {
const chunk = offsetPointsGroupedRef.slice(i, i+counter);
offsetPointsGrouped.push(chunk);
}
var testPoly = polyhedron({ //
points: offsetPoints, // the apex point
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.9,0.9]);
/* console.log('offsetPoints');
console.log(offsetPoints);
console.log(transition_points);*/
//return [testPoly,mainPoly,shiftedPoly];
/* ------------ kick side --------*/
if (kick_base_drop !== 0) {
var kick_side_points = offsetYtPts; /*get just the points along
the curve, which will vary with resolution.*/
var kick_array_length = kick_side_points.length;
offsetYtPts.push([0,0,section_depth]);
offsetYtPts.push([width/2,0,section_depth]);
var kickSideTriangles = [];
for (var j=0; j<kick_array_length-1; j++) {
kickSideTriangles.push([j+1,j,kick_array_length]);
}
kickSideTriangles.push([kick_array_length-1,offsetYtPts.length-2,offsetYtPts.length-1]);
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=offsetPoints.length;
kickSideTriangles[k][1]+=offsetPoints.length;
kickSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYtPts);
triangleArray = triangleArray.concat(kickSideTriangles);
}
else {
var kickSidePoints = [
[0,0,-offset],
[width/2,0,-offset],
[0,0,section_depth],
[width/2,0,section_depth]
];
var kickSideTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=offsetPoints.length;
kickSideTriangles[k][1]+=offsetPoints.length;
kickSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(kickSidePoints);
triangleArray = triangleArray.concat(kickSideTriangles);
}
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor([.9,.99,.9]);
return result; */
/* ------------ center of transition section --------*/
/*var transitionCenterPoints = [
[0,0,-offset],
[0,transition_length,-offset],
[0,0,section_depth],
[0,transition_length,section_depth]
];
var transitionCenterTriangles = [
[0,1,2],
[1,3,2]
];
for (var k=0; k<(transitionCenterTriangles.length); k++){
transitionCenterTriangles[k][0]+=offsetPoints.length;
transitionCenterTriangles[k][1]+=offsetPoints.length;
transitionCenterTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(transitionCenterPoints);
triangleArray = triangleArray.concat(transitionCenterTriangles);
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor([.99,.95,.95]);
return result;*/
/* ------------ concave end of transition section --------*/
//points are concave_array points, plus the border points, which are added below:
var concave_array_curve_points = offsetTipPts; /*get just the points along
the curve, which will vary with resolution.*/
var curve_array_length = concave_array_curve_points.length;
offsetTipPts.push([0,transition_length,section_depth]);
offsetTipPts.push([width/2,transition_length,section_depth]);
var concaveSideTriangles = [];
for (var j=0; j<curve_array_length-1; j++) {
concaveSideTriangles.push([j,j+1,curve_array_length]);
}
concaveSideTriangles.push([curve_array_length-1,offsetTipPts.length-1,offsetTipPts.length-2]);
/* var result=polyhedron({
points: offsetTipPts,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(concaveSideTriangles.length); k++){
concaveSideTriangles[k][0]+=offsetPoints.length;
concaveSideTriangles[k][1]+=offsetPoints.length;
concaveSideTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetTipPts);
triangleArray = triangleArray.concat(concaveSideTriangles);
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor([0.9,0.95,0.99]);
return result;*/
/* ------------ edge of transition section (along bezier) --------*/
//points are bezier_array points, plus the border points, which are added below:
var bezier_array_length = offsetYePts.length; /*first, store the value of */
offsetYePts.push([width/2,0,section_depth]);
offsetYePts.push([width/2,transition_length,section_depth]);
var bezierTriangles = [];
for (var j=0; j<bezier_array_length-1; j++) {
bezierTriangles.push([bezier_array_length,j+1,j]);
}
bezierTriangles.push([offsetYePts.length-2,offsetYePts.length-1,bezier_array_length-1]);
/* var result=polyhedron({
points: concave_array,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(bezierTriangles.length); k++){
bezierTriangles[k][0]+=offsetPoints.length;
bezierTriangles[k][1]+=offsetPoints.length;
bezierTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(offsetYePts);
triangleArray = triangleArray.concat(bezierTriangles);
/*var result= polyhedron({ //
points: offsetPoints, //
triangles: triangleArray // two triangles for square base
}).setColor([0.8,0.99,0.95]);
return result;*/
/* ------------ bottom --------*/
var bottomPoints = [
[0,0,section_depth],
[width/2,0,section_depth],
[0,transition_length,section_depth],
[width/2,transition_length,section_depth]
];
var bottomTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(bottomTriangles.length); k++){
bottomTriangles[k][0]+=offsetPoints.length;
bottomTriangles[k][1]+=offsetPoints.length;
bottomTriangles[k][2]+=offsetPoints.length;
}
offsetPoints = offsetPoints.concat(bottomPoints);
triangleArray = triangleArray.concat(bottomTriangles);
for (let i=0; i<offsetPoints.length;i++) {
for (let j=0; j<3; j++) {
offsetPoints[i][j] = Math.round(offsetPoints[i][j]*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(offsetPoints));
for (let i=0;i<offsetPoints.length;i++) {
finalArray.push([-offsetPoints[i][0],offsetPoints[i][1],offsetPoints[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+offsetPoints.length,triangleArray[i][0]+offsetPoints.length,triangleArray[i][2]+offsetPoints.length]);
}
var result= polyhedron({ //
points: finalArray, //
triangles: finalTriangleArray // two triangles for square base
}).setColor(0.9,0.9,0.9);
//result = result.union(mirror([1,0,0],result));
result = rotate([180,0,-90],result);
result = result.translate([0,0,-offset]);
return result; //tub transition section offset
}
function make_tub_transition_section(transition_length, thickness, slice_thickness, width, deck_width, tub_rad, number_of_segments, model_res, kick_base_drop, flat_width, concave_drop, mold_height, tub_res)
{
var section_depth=mold_height;
var y_max = transition_length;
var x_max = width/2;
var res = 100; //resolution of bezier curves
var x_res = tub_res;
/*The following equations were derived on a piece of paper, using tan(tub_angle) = (concave_drop - tub_rad + tub_rad*cos(tub_angle))/(deck_width/2 - flat_width/2 - tub_rad*sin(tub_angle)) and some trig identities: sin^2(x) + cos^2(x) = 1. This website was helpful: https://www.symbolab.com/solver/trigonometric-simplification-calculator
*/
var a = Math.pow(concave_drop-tub_rad,2)+Math.pow((deck_width/2 - flat_width/2),2);
var b = 2*tub_rad*(concave_drop-tub_rad);
var c = Math.pow(tub_rad,2)-Math.pow(deck_width/2 - flat_width/2, 2);
var tub_angle = acos((-b + sqrt(Math.pow(b,2) - 4*a*c))/(2*a));
var x = x_max;
var concave_depth;
if (x<flat_width/2) {
concave_depth = 0;
}
else {
if (x<=(tub_rad*sin(tub_angle))) {
concave_depth = (tub_rad-sqrt((pow(tub_rad,2)-pow((x),2))));
}
else {
concave_depth = ((tub_rad - (tub_rad*cos(tub_angle)))+(((x)-tub_rad*sin(tub_angle))*tan(tub_angle)));
}
}
var stepsPerY = model_res; //how many iterations are done until we move onto next y value
var stepsPerX = (width/2)/x_res; //how many iterations done until we move onto next x value
var xStepSize = x_res;
// 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
//the direction of i is the direction of y
var i_size = i_range/stepsPerY;
var origin_x = 0;
var origin_y = 0;
var a = 0; //initial t value of Bezier
var x0 = 0;
var x1 = transition_length/4;
var x2 = transition_length*(2/3);
var x3 = transition_length;
/*var y0 = kick_base_drop;
var y1 = kick_base_drop;
var y2 = concave_depth;
var y3 = concave_depth;*/
var z;
var slice_adj = 0;
var x_val_last = 0;
var transition_points = [];
var kBR = (Math.pow(kick_base_drop,2)+Math.pow(width/2,2))/(2*kick_base_drop); //kick base radius
if (!isFinite(kBR)) {
kBR = 0;
}
var concave_array = []; /*this is the last array of points along the x-axis (width) before the concave section*/
var kick_array= []; /*this is the first array of points along the x-axis (y=0), needed for kick base drop*/
var bezier_array = [[width/2,0,0]]; /*array of points along edge of bezier curve*/
var x_tub = 0;
for (x=0; x<=width/2; x+=x_res) { //
var y0 = kBR - kBR*cos(asin(x/kBR));
if (!isFinite(y0)) {
y0 = 0;
}
var y1 = y0;
var concave_drop_x; //concave drop along x width
if (x<flat_width/2) {
concave_drop_x = 0;
}
else {
if (x_tub<=(tub_rad*sin(tub_angle))) {
concave_drop_x = (tub_rad-sqrt((pow(tub_rad,2)-pow((x_tub),2))));
}
else {
concave_drop_x = ((tub_rad - (tub_rad*cos(tub_angle)))+(((x_tub)-tub_rad*sin(tub_angle))*tan(tub_angle)));
}
x_tub += x_res;
}
var y2 = concave_drop_x;
var y3 = y2;
for (var i = a; i < (i_range+i_size); i=i+i_size)
{
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); //actually the position along y
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); //actually the z height
x_val = Math.round(x_val*1000)/1000;
y_val = Math.round(y_val*1000)/1000;
x = Math.round(x*100000)/100000;
z = y_val;
transition_points.push([x,x_val,z]);
if (t==0) {
kick_array.push([x,x_val,z]);
}
if (t==1) {
concave_array.push([x,x_val,z]);
}
if (x == x_max) {
bezier_array.push([x,x_val,z]);
}
}
}
var triangleArray = [];
var c=0;
var b=1;
var i;
var maxTriangleArray = transition_points.length-stepsPerY-2;
for (i=0;i<=maxTriangleArray;i=i+stepsPerY+1) {
for (c=i;c<(i+stepsPerY);c++) {
triangleArray.push([(c+1),(c),(stepsPerY+c+1)]);
if ((c+1)<=(i+stepsPerY)) {
triangleArray.push([(stepsPerY+c+1),(stepsPerY+c+2),c+1]);
}
}
}
var result1= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
});
var ptArray = [];
/*for (var i=0; i<transition_points.length; i++) {
ptArray.push(cube({size: [0.05, 0.05, 0.05], center: true}).translate([(transition_points[i][0]),(transition_points[i][1]),(transition_points[i][2])]));
}
return ptArray;*/
//return result1;
/* ------------ kick side --------*/
if (kick_base_drop !== 0) {
var kick_side_points = kick_array; /*get just the points along
the curve, which will vary with resolution.*/
var kick_array_length = kick_side_points.length;
kick_array.push([0,0,section_depth]);
kick_array.push([width/2,0,section_depth]);
var kickSideTriangles = [];
for (var j=0; j<kick_array_length-1; j++) {
kickSideTriangles.push([j+1,j,kick_array_length]);
}
kickSideTriangles.push([kick_array_length-1,kick_array.length-2,kick_array.length-1]);
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=transition_points.length;
kickSideTriangles[k][1]+=transition_points.length;
kickSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(kick_array);
triangleArray = triangleArray.concat(kickSideTriangles);
}
else {
var kickSidePoints = [
[0,0,0],
[width/2,0,0],
[0,0,section_depth],
[width/2,0,section_depth]
];
var kickSideTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(kickSideTriangles.length); k++){
kickSideTriangles[k][0]+=transition_points.length;
kickSideTriangles[k][1]+=transition_points.length;
kickSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(kickSidePoints);
triangleArray = triangleArray.concat(kickSideTriangles);
}
var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor([.9,.9,.9]);
//return result;
/* ------------ center of transition section --------*/
/*var transitionCenterPoints = [
[0,0,0],
[0,transition_length,0],
[0,0,section_depth],
[0,transition_length,section_depth]
];
var transitionCenterTriangles = [
[0,1,2],
[1,3,2]
];
for (var k=0; k<(transitionCenterTriangles.length); k++){
transitionCenterTriangles[k][0]+=transition_points.length;
transitionCenterTriangles[k][1]+=transition_points.length;
transitionCenterTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(transitionCenterPoints);
triangleArray = triangleArray.concat(transitionCenterTriangles);
var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor([.95,.95,.95]);
//return result;
/* ------------ concave end of transition section --------*/
//points are concave_array points, plus the border points, which are added below:
var concave_array_curve_points = concave_array; /*get just the points along
the curve, which will vary with resolution.*/
var curve_array_length = concave_array_curve_points.length;
concave_array.push([0,transition_length,section_depth]);
concave_array.push([width/2,transition_length,section_depth]);
var concaveSideTriangles = [];
for (var j=0; j<curve_array_length-1; j++) {
concaveSideTriangles.push([j,j+1,curve_array_length]);
}
concaveSideTriangles.push([curve_array_length-1,concave_array.length-1,concave_array.length-2]);
/* var result=polyhedron({
points: concave_array,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(concaveSideTriangles.length); k++){
concaveSideTriangles[k][0]+=transition_points.length;
concaveSideTriangles[k][1]+=transition_points.length;
concaveSideTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(concave_array);
triangleArray = triangleArray.concat(concaveSideTriangles);
var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor([0.95,0.95,0.95]);
//return result;
/* ------------ edge of transition section (along bezier) --------*/
//points are bezier_array points, plus the border points, which are added below:
var bezier_array_length = bezier_array.length; /*first, store the value of */
bezier_array.push([width/2,0,section_depth]);
bezier_array.push([width/2,transition_length,section_depth]);
var bezierTriangles = [];
for (var j=0; j<bezier_array_length-1; j++) {
bezierTriangles.push([bezier_array_length,j+1,j]);
}
bezierTriangles.push([bezier_array.length-2,bezier_array.length-1,bezier_array_length-1]);
/* var result=polyhedron({
points: concave_array,
triangles: concaveSideTriangles
});
return result;*/
for (var k=0; k<(bezierTriangles.length); k++){
bezierTriangles[k][0]+=transition_points.length;
bezierTriangles[k][1]+=transition_points.length;
bezierTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(bezier_array);
triangleArray = triangleArray.concat(bezierTriangles);
var result= polyhedron({ //
points: transition_points, //
triangles: triangleArray // two triangles for square base
}).setColor([0.95,0.95,0.95]);
// return result;
/* ------------ bottom --------*/
var bottomPoints = [
[0,0,section_depth],
[width/2,0,section_depth],
[0,transition_length,section_depth],
[width/2,transition_length,section_depth]
];
var bottomTriangles = [
[2,1,0],
[2,3,1]
];
for (var k=0; k<(bottomTriangles.length); k++){
bottomTriangles[k][0]+=transition_points.length;
bottomTriangles[k][1]+=transition_points.length;
bottomTriangles[k][2]+=transition_points.length;
}
transition_points = transition_points.concat(bottomPoints);
triangleArray = triangleArray.concat(bottomTriangles);
for (let i=0; i<transition_points.length;i++) {
for (let j=0; j<3; j++) {
transition_points[i][j] = Math.round(transition_points[i][j]*1000)/1000;
}
}
var finalArray = JSON.parse(JSON.stringify(transition_points));
for (let i=0;i<transition_points.length;i++) {
finalArray.push([-transition_points[i][0],transition_points[i][1],transition_points[i][2]]);
}
var finalTriangleArray = JSON.parse(JSON.stringify(triangleArray));
var triangleArrayLength = triangleArray.length;
for (let i=0;i<triangleArrayLength;i++){
finalTriangleArray.push([triangleArray[i][1]+transition_points.length,triangleArray[i][0]+transition_points.length,triangleArray[i][2]+transition_points.length]);
}
var result= polyhedron({ //
points: finalArray, //
triangles: finalTriangleArray // two triangles for square base
}).setColor(0.9,0.9,0.9);
// result = result.union(mirror([1,0,0],result));
result = rotate([180,0,-90],result);
result = result.translate([0,0,0]);
return result; //tub transition section (not offset)
}
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_profile_uncut(mold_width, wheelbase, boltL, nose_length, tail_length, length, taperN, taperT, depth, mold_length)
{
var width = mold_width;
var nose_offset = (nose_length - tail_length)/2;
var profile = new CSG.Path2D([[0,(width/2)],[(mold_length/2+nose_offset),(width/2)]]);
profile = profile.appendPoint([(mold_length/2+nose_offset),-(width/2)]);
profile = profile.appendPoint([(-(mold_length/2-nose_offset)),-(width/2)]);
profile = profile.appendPoint([(-(mold_length/2-nose_offset)),(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 = 250; //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_section_bores(mold_width, mold_length, print_length, print_width, bore_dia, bore_depth, mold_height, printSection, spacing, nose_length, tail_length, display, extra_depth) {
var result = new CSG();
var cyl_depth = bore_depth+extra_depth;
var maxNumberSections = 7; //at most we have 7 sections with extended nose/tail
var minNumberSections = 5; //at minimum we have 5 sections
var width_location;
if (print_width >= mold_width) {
width_location = -(mold_width/2-spacing);
}
else {
width_location = spacing;
}
result = cylinder({r: bore_dia/2, h: cyl_depth, center: true}).translate([0,0,-mold_height+(cyl_depth/2)-extra_depth]);
var cyl1 = result;
var cyl2 = result;
var cyl3 = result;
var cyl4 = result;
cyl1 = cyl1.translate([(nose_length-tail_length)/2+(print_length/2)-spacing, width_location, 0]);
cyl2 = cyl2.translate([(nose_length-tail_length)/2+(print_length/2)-spacing, mold_width/2-spacing, 0]);
cyl3 = cyl3.translate([(nose_length-tail_length)/2-((print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl4 = cyl4.translate([(nose_length-tail_length)/2-((print_length/2)-spacing), width_location, 0]);
var cyl5 = result;
var cyl6 = result;
var cyl7 = result;
var cyl8 = result;
cyl5 = cyl5.translate([print_length+(nose_length-tail_length)/2+(print_length/2)-spacing, width_location, 0]);
cyl6 = cyl6.translate([print_length+(nose_length-tail_length)/2+(print_length/2)-spacing, mold_width/2-spacing, 0]);
cyl7 = cyl7.translate([print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl8 = cyl8.translate([print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), width_location, 0]);
var cyl17 = result;
var cyl18 = result;
var cyl19 = result;
var cyl20 = result;
cyl17 = cyl17.translate([(nose_length-tail_length)/2-(print_length+(print_length/2)-spacing), width_location, 0]);
cyl18 = cyl18.translate([(nose_length-tail_length)/2-(print_length+(print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl19 = cyl19.translate([(nose_length-tail_length)/2-(print_length-((print_length/2)-spacing)), mold_width/2-spacing, 0]);
cyl20 = cyl20.translate([(nose_length-tail_length)/2-(print_length-((print_length/2)-spacing)), width_location, 0]);
var cyl9 = result;
var cyl10 = result;
var cyl11 = result;
var cyl12 = result;
var cyl21 = result;
var cyl22 = result;
var cyl23 = result;
var cyl24 = result;
if ((mold_length<=(5*print_length))) {
cyl9 = cyl9.translate([(nose_length-tail_length)/2+(mold_length/2)-spacing, width_location, 0]);
cyl10 = cyl10.translate([(nose_length-tail_length)/2+(mold_length/2)-spacing, mold_width/2-spacing, 0]);
cyl21 = cyl21.translate([(nose_length-tail_length)/2-((mold_length/2)-spacing),width_location, 0]);
cyl22 = cyl22.translate([(nose_length-tail_length)/2-((mold_length/2)-spacing), mold_width/2-spacing, 0]);
}
else {
cyl9 = cyl9.translate([2*print_length+(nose_length-tail_length)/2+((print_length/2)-spacing), width_location, 0]);
cyl10 = cyl10.translate([2*print_length+(nose_length-tail_length)/2+((print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl21 = cyl21.translate([(nose_length-tail_length)/2-(2*print_length+((print_length/2)-spacing)), width_location, 0]);
cyl22 = cyl22.translate([(nose_length-tail_length)/2-(2*print_length+((print_length/2)-spacing)), mold_width/2-spacing, 0]);
}
cyl11 = cyl11.translate([2*print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl12 = cyl12.translate([2*print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), width_location, 0]);
cyl23 = cyl23.translate([(nose_length-tail_length)/2-(2*print_length-((print_length/2)-spacing)), mold_width/2-spacing, 0]);
cyl24 = cyl24.translate([(nose_length-tail_length)/2-(2*print_length-((print_length/2)-spacing)), width_location, 0]);
var plane = CSG.Plane.fromPoints([(nose_length-tail_length)/2,0,0], [(nose_length-tail_length)/2, 5, 1], [(nose_length-tail_length)/2, 1, 2]);
var bore_array = [cyl1,cyl2,cyl3,cyl4,cyl5,cyl6,cyl7,cyl8,cyl9,cyl10,cyl11,cyl12,cyl17,cyl18,cyl19,cyl20,cyl21,cyl22,cyl23,cyl24];
if ((mold_length>(5*print_length))||(mold_length<(7*print_length)) ){
var cyl13 = result;
var cyl14 = result;
var cyl15 = result;
var cyl16 = result;
cyl13 = cyl13.translate([(nose_length-tail_length)/2+(mold_length/2)-spacing, width_location, 0]);
cyl14 = cyl14.translate([(nose_length-tail_length)/2+(mold_length/2)-spacing, mold_width/2-spacing, 0]);
cyl15 = cyl15.translate([3*print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), mold_width/2-spacing, 0]);
cyl16 = cyl16.translate([3*print_length+(nose_length-tail_length)/2-((print_length/2)-spacing), width_location, 0]);
var cyl25 = result;
var cyl26 = result;
var cyl27 = result;
var cyl28 = result;
cyl25 = cyl25.translate([(nose_length-tail_length)/2-((mold_length/2)-spacing), width_location, 0]);
cyl26 = cyl26.translate([(nose_length-tail_length)/2-((mold_length/2)-spacing), mold_width/2-spacing, 0]);
cyl27 = cyl27.translate([(nose_length-tail_length)/2-(3*print_length-((print_length/2)-spacing)), mold_width/2-spacing, 0]);
cyl28 = cyl28.translate([(nose_length-tail_length)/2-(3*print_length-((print_length/2)-spacing)), width_location, 0]);
var extended_bores = [cyl13,cyl14,cyl15,cyl16,cyl25,cyl26,cyl27,cyl28];
var ext_bore_array_length = extended_bores.length;
for (var j=0; j<ext_bore_array_length;j++) {
bore_array.push(extended_bores[j]);
}
}
var bore_array_length = bore_array.length;
/*console.log('bore array length = ' + bore_array.length);
for (var i=0; i<bore_array_length; i++) {
bore_array.push((bore_array[i]).mirrored(plane)); //need to fix this - mirrored holes get shifted in z direction
}*/
/*for (var k=0;k<bore_array_length;k++) {
bore_array[k]=bore_array[k].translate([0,0,bore_depth/2]);
}
*/
return bore_array;
}
Please consider supporting SK8CAD via Patreon or a one-time donation:
DISCLAIMER:
This software is provided as-is, and Open Source Skateboards is not liable for any loss (direct or indirect) due to the use of this software. In other words, use this tool at your own risk!
...
CNC Machined Foam Mold
Mold Info: Molds are CNC machined using Roarockit high-density foam blanks. The top surface will have clear tape applied as a mold release, and 1/2" diameter notches will be made as shown to aid with board alignment.
Shipping: Molds ship in about 5-7 business days. Default shipping is economy ground - contact us if you'd like to know about alternative shipping methods, to pick up your mold, or for larger order quantities.
International customers: Please contact us for a shipping quote to place your order.
If you'd like additional customization - wheel flares, rocker, camber, alternative concaves, etc., please contact us for our design services. There's typically a $100 design fee for such features.