diff --git a/.gitignore b/.gitignore index 34fd461..30f61f6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Results output dist +tmp *.csg *.csv @@ -21,6 +22,13 @@ nbproject/ .settings .project +# Local config +config.ini +config.scad + +# Local post processing scripts +post-render.sh +post-slice.sh + # Generated files *.stl - diff --git a/HISTORY.md b/HISTORY.md index 0913abd..a0df978 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,19 @@ # rc-tracks history +## [Version 1.0.0](https://github.com/jsconan/rc-tracks/releases/tag/1.0.0) + +Add a variant of the race track system for 1/64 to 1/76 scale RC cars. + +![scale 64](https://github.com/jsconan/rc-tracks/raw/2635fe50cdf437d53924655f017a9943ff9a0d68/doc/rctrack-64.jpg) + +This variant can be fully printed, barriers and ground included. It still comes with a modular approach, each element being able to be printed separately. Full tiles can also be printed all at once (barriers + ground). + +Regarding the changes impacting the whole project: + +- The structure and the config have been unified, common config is available at the top level. +- The script files also got unified, with support added for post-processing scripts. +- Readme files are provided with details for each variant. + ## [Version 0.5.0](https://github.com/jsconan/rc-tracks/releases/tag/0.5.0) Finalize the extract of the race track system for 1/24 to 1/32 scale RC cars from the repository [jsconan/things](https://github.com/jsconan/things). diff --git a/README.md b/README.md index 0ef517e..58df057 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,127 @@ -# rc-tracks -Printable race track systems for RC cars. +# RC-tracks + +A printable race track systems for remote controlled cars. + + + +- [At a glance](#Ataglance) +- [Install and requirements](#Installandrequirements) + - [OpenSCAD](#OpenSCAD) + - [Source code](#Sourcecode) + - [Download the zip file](#Downloadthezipfile) + - [Get the code from the repository](#Getthecodefromtherepository) + - [Configuration](#Configuration) +- [Render the parts](#Rendertheparts) +- [Post-scripts](#Post-scripts) + + + + +## At a glance + +The project contains designs for a modular race track system aimed at remote controlled cars. The parts are designed using a scripting language, processed by [OpenSCAD](https://openscad.org/about.html). There is no ready to use 3D model files in the source code. If you are interested in such files, please look at the [released versions](https://github.com/jsconan/rc-tracks/releases) which contains 3D model files built with default parameters. However, if you want to customize these parts, tailoring them with your measures, you should rather download the source code and then tweak the configuration files before generating your own 3D model files. + +The project contains two different systems, each targeting a particular RC car scale: + +- [1/24 to 1/32 scale](scale-24/README.md) + + ![RC track](./doc/rctrack-24.jpg) + +- [1/64 to 1/76 scale](scale-64/README.md) + + ![RC track](./doc/rctrack-64.jpg) + +Please refer to the readme file for each variant in order to get the proper documentation. + +> **Note:** the scales are given as an estimate, not all scales have been tested. The `1/24 to 1/32` variant has been tested with `1/28` scale models, while the `1/64 to 1/76` variant has been tested with `1/76` models. + +## Install and requirements + +To properly use the project you first need to do some installations steps. + +### OpenSCAD + +First of all you need [OpenSCAD](https://openscad.org/) to be installed. To do so, please go to the [OpenSCAD download page](https://openscad.org/downloads.html), an get the version suitable for your operating system. + +### Source code + +The source code is hosted on a [Git](https://git-scm.com/) repository. To get it you can either download a [zip file](https://github.com/jsconan/rc-tracks/archive/refs/heads/main.zip), or clone the repository locally. + +#### Download the zip file + +The source code can be downloaded from the [GitHub repository](https://github.com/jsconan/rc-tracks). + +You can download it as zip file from this [link](https://github.com/jsconan/rc-tracks/archive/refs/heads/main.zip). + +As the project is using a shared library, that is not supplied with the package, you will need to also download it. + +Download the zip file from this [link](https://github.com/jsconan/camelSCAD/archive/refs/heads/main.zip). + +Then extract its content inside the folder `lib/camelSCAD`. Please make sure the folder directly contains the library and not an intermediate folder like `lib/camelSCAD/camelSCAD-main`. If this is the case, please move the content one folder up and delete the extra folder. + +Note: the easiest way is to call the `init.sh` script, that will take care of this for you. + +#### Get the code from the repository + +A git tool is needed if you intend to get the source code from the git repository. You can download one either from the [main git website](https://git-scm.com/downloads), or from [GitHub](https://docs.github.com/en/github-cli). + +Once you have your git tool installed, open a console window, select a project folder (create it if needed), then run the following commands: + +``` +git clone https://github.com/jsconan/rc-tracks.git +cd rc-tracks +git submodule init +git submodule update +``` + +The source code should have been downloaded, as well as the libraries. + +Note: you can also use a graphical interface tool. In this case, please make it can also install the submodules. + +Note 2: the easiest way is to call the `init.sh` script, that will take care of this for you. + +### Configuration + +The configuration for each system may be changed locally. To not collide with changes in the main implementation, the configuration files are not versioned. Instead, you will find `-dist` files that contain a copy of the typical configuration. + +From a fresh copy of the project, you will need first to create these configuration files. The easiest way is to call the `init.sh` script, that will take care of this for you. The configuration files will also be checked and created if needed each time the `render.sh` script is called. + +This initial creation of the configuration files could also be done manually. Here is how: + +1. Go to the `config` folder +2. Copy any of the files having a `-dist` suffix in their name to a file without this suffix. + + _Example:_ copy `config-dist.scad` to `config.scad` + +Please refer to the readme file for each variant in order to get the proper documentation. + +## Render the parts + +In each system, the parts are all located into the `parts` folder. They can all be opened separately in [OpenSCAD](https://openscad.org/) and rendered. + +However, it is possible to render all parts in batch. Each system proposes a script `render.sh` to take care of this. + +This is a command-line tool, which accept several parameters. By default, it will render the preset selected in the config. + +It is possible to select another preset, as well as set a different number of cells for the containers. + +The parameter `-h` make it show the help. + +If the slicer [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer) is installed, running the command `render.sh -s` will produce the [G-code](https://en.wikipedia.org/wiki/G-code) from the rendered STL files and using the setting from the file `config/config.ini`. + +Please refer to the readme file for each variant in order to get the proper documentation. + +## Post-scripts + +For each system, when using the built-in script to render/slice the models in batch, you can also add custom post-processing scripts. There is one for `render.sh` and one for `slice.sh`. They are respectively named `post-render.sh` and `post-slice.sh`. + +As these script can be defined locally, they are not part of the versioned content. Instead, you can find sample files at `post-render-dist.sh` and `post-slice-dist.sh`. To use them, you need to: + +- copy the dist file to a local file, for example: `cp post-render-dist.sh post-render.sh`. +- you need to make sure the file is executable: `chmod +x post-render.sh`. +- finally, add you own commands to the copy. + +Please refer to the readme file for each variant in order to get the proper documentation. diff --git a/config/config.scad b/config/config.scad new file mode 100644 index 0000000..3cf33d6 --- /dev/null +++ b/config/config.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Global configuration. + * + * @author jsconan + */ + +// We will render the object using the specifications of this mode +renderMode = MODE_PROD; + +// Defines the characteristics of the printer +layerHeight = 0.2; // The height of the printed layers +nozzleWidth = 0.4; // The size of the printer's nozzle +printTolerance = 0.1; // The print tolerance when pieces need to be assembled +printInterval = 5; // The interval between 2 pieces when presented together +printerLength = 250; // The length of the printer's build plate +printerWidth = 210; // The width of the printer's build plate diff --git a/config/constants.scad b/config/constants.scad new file mode 100644 index 0000000..79589b4 --- /dev/null +++ b/config/constants.scad @@ -0,0 +1,32 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Global constants. + * + * @author jsconan + */ + +// The angle of a typical curve +CURVE_ANGLE = RIGHT; diff --git a/config/helpers.scad b/config/helpers.scad new file mode 100644 index 0000000..a374ea9 --- /dev/null +++ b/config/helpers.scad @@ -0,0 +1,165 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Global functions. + * + * @author jsconan + */ + +/** + * Aligns a value with respect to the target layer height. + * @param Number value + * @returns Number + */ +function layerAligned(value) = roundBy(value, layerHeight); + +/** + * Aligns a value with respect to the target nozzle size. + * @param Number value + * @returns Number + */ +function nozzleAligned(value) = roundBy(value, nozzleWidth); + +/** + * Gets the thickness of N layers. + * @param Number N + * @returns Number + */ +function layers(N) = N * layerHeight; + +/** + * Gets the width of N times the nozzle width. + * @param Number N + * @returns Number + */ +function shells(N) = N * nozzleWidth; + +/** + * Computes the print interval between the centers of 2 objects. + * @param Number size - The size of the shape. + * @returns Number + */ +function getPrintInterval(size) = size + printInterval; + +/** + * Gets the adjusted quantity of shapes to place on a grid with respect to the size of one shape. + * @param Number length - The length of the shape. + * @param Number width - The width of the shape. + * @param Number [quantity] - The number of shapes to place. + * @returns Number + */ +function getMaxQuantity(length, width, quantity=1) = + let( + maxLine = floor(printerLength / length), + maxCol = floor(printerWidth / width) + ) + min(maxLine * maxCol, quantity) +; + +/** + * Gets the maximal number of shapes that can be placed on a line with respect the size of one shape. + * @param Number length - The length of the shape. + * @param Number width - The width of the shape. + * @param Number [quantity] - The number of shapes to place. + * @param Number [line] - The expected number of shapes per line. + * @returns Number + */ +function getMaxLine(length, width, quantity=1, line=undef) = + let( + maxLine = floor(printerLength / length) + ) + min(uor(line, ceil(sqrt(quantity))), maxLine) +; + +/** + * Gets the overall length of the area taken to place the repeated shapes on a grid with respect to the expected quantity. + * @param Number length - The length of the shape. + * @param Number width - The width of the shape. + * @param Number [quantity] - The number of shapes to place. + * @param Number [line] - The expected number of shapes per line. + * @returns Number + */ +function getGridLength(length, width, quantity=1, line=undef) = + let( + length = getPrintInterval(length), + width = getPrintInterval(width), + quantity = getMaxQuantity(length, width, quantity) + ) + min(quantity, getMaxLine(length, width, quantity, line)) * length +; + +/** + * Gets the overall width of the area taken to place the repeated shapes on a grid with respect to the expected quantity. + * @param Number length - The length of the shape. + * @param Number width - The width of the shape. + * @param Number [quantity] - The number of shapes to place. + * @param Number [line] - The expected number of shapes per line. + * @returns Number + */ +function getGridWidth(length, width, quantity=1, line=undef) = + let( + length = getPrintInterval(length), + width = getPrintInterval(width), + quantity = getMaxQuantity(length, width, quantity), + line = getMaxLine(length, width, quantity, line) + ) + ceil(quantity / line) * width +; + +/** + * Computes the length of a straight section given the ratio. + * @param Number length - The length of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getStraightLength(length, ratio=1) = length * abs(ratio); + +/** + * Gets the length of a curved section given the radius and the ratio. + * @param Number radius - The radius of the curve. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveLength(radius, ratio=1) = getArcLength(radius=radius, angle=getCurveAngle(ratio)); + +/** + * Computes the angle of a curve with respect to the ratio. + * @param Number ratio - The ratio of the curve. + * @returns Number + */ +function getCurveAngle(ratio) = CURVE_ANGLE / abs(ratio); + +/** + * Computes the rotation angle used to place a curve. + * @param Number angle - The angle of the curve. + * @returns Number + */ +function getCurveRotationAngle(angle) = CURVE_ANGLE - angle / 2; + +/** + * Prints the project version, including the package version. + * @returns String + */ +function printVersion() = str(PROJECT_VERSION, " (package: ", PACKAGE_VERSION, ")"); diff --git a/config/operators.scad b/config/operators.scad new file mode 100644 index 0000000..2322c50 --- /dev/null +++ b/config/operators.scad @@ -0,0 +1,97 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Defines shared operators. + * + * @author jsconan + */ + +/** + * Extrudes the profile on the expected linear length. + * @param Number length - The length of the element. + */ +module extrudeStraightProfile(length) { + rotate([RIGHT, 0, RIGHT]) { + linear_extrude(height=length, center=true, convexity=10) { + children(); + } + } +} + +/** + * Extrudes the profile on the expected circle path. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + */ +module extrudeCurvedProfile(radius, angle) { + rotate_extrude(angle=angle, convexity=10) { + translateX(radius) { + children(); + } + } +} + +/** + * Adjusts the position on the print plat to either print as it or to flip upside down the model. + * @param Boolean flip - Flip upside down the element. + */ +module flipElement(flip=false) { + rotate(flip ? [180, 0, 180] : [0, 0, 0]) { + children(); + } +} + +/** + * Repeats and place a shape on a grid with respect to the expected quantity. + * @param Number length - The length of the shape. + * @param Number width - The width of the shape. + * @param Number [quantity] - The number of shapes to place. + * @param Number [line] - The expected number of shapes per line. + */ +module placeElements(length, width, quantity=1, line=undef) { + length = getPrintInterval(length); + width = getPrintInterval(width); + quantity = getMaxQuantity(length, width, quantity); + repeatGrid( + count = quantity, + intervalX = xAxis3D(length), + intervalY = yAxis3D(width), + line = getMaxLine(length, width, quantity, line), + center = true + ) { + children(); + } +} + +/** + * Centers the children elements to te printer's build plate. + * @param Boolean [moveOrigin] - Translate the children in order to be centered on the build plate. + */ +module centerBuildPlate(moveOrigin = false) { + buildPlate([printerLength, printerWidth], center=!moveOrigin); + translate(moveOrigin ? [printerLength, printerWidth, 0] / 2 : [0, 0, 0]) { + children(); + } +}; diff --git a/config/setup.scad b/config/setup.scad new file mode 100644 index 0000000..119d18d --- /dev/null +++ b/config/setup.scad @@ -0,0 +1,43 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Project's bootstrap. + * + * @author jsconan + */ + +// Imports the library. +include <../lib/camelSCAD/shapes.scad> + +// Defines the package's version +include + +// Imports the global configuration +include + +// Imports the global helpers and constants +include +include +include diff --git a/config/version.scad b/config/version.scad new file mode 100644 index 0000000..42ded57 --- /dev/null +++ b/config/version.scad @@ -0,0 +1,33 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Version of the package. + * + * @author jsconan + */ + +PACKAGE_VERSION = "1.0.0"; +PROJECT_VERSION = "0.0.0"; +PROJECT_SCALE = "various"; diff --git a/doc/rctrack-24.jpg b/doc/rctrack-24.jpg new file mode 100644 index 0000000..d913877 Binary files /dev/null and b/doc/rctrack-24.jpg differ diff --git a/doc/rctrack-64.jpg b/doc/rctrack-64.jpg new file mode 100644 index 0000000..7f09c2d Binary files /dev/null and b/doc/rctrack-64.jpg differ diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..d9779d7 --- /dev/null +++ b/init.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# Initialize the project +# +# @author jsconan +# + +# script config +scriptpath="$(dirname $0)" +configpath24="${scriptpath}/scale-24/config" +configpath64="${scriptpath}/scale-64/config" + +# make sure to get the library +if [ ! -d "${scriptpath}/lib/camelSCAD" ]; then + if [ -d "${scriptpath}/.git" ] && [ -x "$(command -v git)" ]; then + echo "Install camelSCAD using Git" + git submodule init + git submodule update + else + echo "Install camelSCAD from an archive" + mkdir "${scriptpath}/lib" + cd "${scriptpath}/lib" + curl -LJO https://github.com/jsconan/camelSCAD/archive/refs/heads/main.zip + unzip camelSCAD-main.zip + rm camelSCAD-main.zip + mv camelSCAD-main camelSCAD + fi +fi + +# include the libs +source "${scriptpath}/lib/camelSCAD/scripts/utils.sh" + +# make sure the config exists +distfile "${configpath24}/config.ini" +distfile "${configpath24}/config.scad" +distfile "${configpath64}/config.ini" +distfile "${configpath64}/config.scad" diff --git a/lib/camelSCAD b/lib/camelSCAD index 85ef885..1bb6946 160000 --- a/lib/camelSCAD +++ b/lib/camelSCAD @@ -1 +1 @@ -Subproject commit 85ef885b56a354786b6008ed41116f874bc0c7dc +Subproject commit 1bb694636dfb5107f6e3fcc814959ace5f537f27 diff --git a/scale-24/.gitignore b/scale-24/.gitignore deleted file mode 100644 index e4a80ae..0000000 --- a/scale-24/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/output -/dist -/config/config.ini diff --git a/scale-24/README.md b/scale-24/README.md new file mode 100644 index 0000000..19df617 --- /dev/null +++ b/scale-24/README.md @@ -0,0 +1,146 @@ +# 1/24 to 1/32 scale RC-track system + +A printable race track systems for remote controlled cars from scale 1/24 to 1/32. + + + +- [At a glance](#Ataglance) +- [Configuration](#Configuration) +- [Render the parts](#Rendertheparts) +- [Post-scripts](#Post-scripts) + + + + +## At a glance + +The project contains designs for a modular race track system aimed at remote controlled cars. The parts are designed using a scripting language, processed by [OpenSCAD](https://openscad.org/about.html). There is no ready to use 3D model files in the source code. If you are interested in such files, please look at the [released versions](https://github.com/jsconan/rc-tracks/releases) which contains 3D model files built with default parameters. However, if you want to customize these parts, tailoring them with your measures, you should rather download the source code and then tweak the configuration files before generating your own 3D model files. + +> **Note:** the scales are given as an estimate, not all scales have been tested. The `1/24 to 1/32` variant has been tested with `1/28` scale models. + +This variant contains a set of track barriers that can be used to delimit a race track. To keep a regular track width and to prevent the barriers to be pushed out, a set of arches is proposed to link together the two sides of the track lane. As the barriers, as well as the arches, are modular, you can design tracks of various sizes. The only limit is the size of your printer. + +Two versions of the barriers exist: + +- A composite version made from 3 parts: a bottom and a top beam clipping a blade. This variant is faster to print, but requires more work to build the barriers. +- A unibody version made from a single piece. This variant is slower to print, but it makes it easier to build the race track. + +A particular set of parts is also proposed to allow joining barriers from both versions. + +![RC track](./doc/rctrack-24.jpg) + +## Configuration + +The configuration may be changed locally. To not collide with changes in the main implementation, the configuration files are not versioned. Instead, you will find `-dist` files that contain a copy of the typical configuration. + +From a fresh copy of the project, you will need first to create these configuration files. The easiest way is to call the `init.sh` script, that will take care of this for you. The configuration files will also be checked and created if needed each time the `render.sh` script is called. + +This initial creation of the configuration files could also be done manually. Here is how: + +1. Go to the `config` folder +2. Copy any of the files having a `-dist` suffix in their name to a file without this suffix. + + _Example:_ copy `config-dist.scad` to `config.scad` + +## Render the parts + +The parts are all located into the `parts` folder. They can all be opened separately in [OpenSCAD](https://openscad.org/) and rendered. + +However, it is possible to render all parts in batch. The script `render.sh` takes care of this. + +This is a command-line tool, which accept several parameters. By default, it will render the preset selected in the config. + +It is possible to select another preset, as well as set a different number of cells for the containers. + +The parameter `-h` make it show the help. + +Running the command `render.sh -h` will show this message: + +``` +Renders OpenSCAD files + Usage: + ./render.sh [command] [-h|--help] [-o|--option value] files + + a, accessories Render the accessories + e, elements Render the track separated elements + u, unibody Render the track unibody elements + s, samples Render the samples + p, plates Render the plates + c, config Show the config values + -h, --help Show this help + -l, --length Set the length of a track section + -w, --width Set the virtual width of a track lane (used to compute the radius) + -t --track Set the actual width of a track lane (physical width, used for the arches) + -b --height Set the height of the track barrier + -r --radius Set the radius of the track inner curve + -m --sample Set the size of sample element + -f --format Set the output format + -p --parallel Set the number of parallel processes + -s --slice Slice the rendered files using the default configuration + -c --clean Clean up the output folder before rendering +``` + +The STL files are rendered to the `dist/stl` folder. + +If the slicer [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer) is installed, running the command `render.sh -s` will produce the [G-code](https://en.wikipedia.org/wiki/G-code) from the rendered STL files and using the setting from the file `config/config.ini`. Out of the box, it is produce instruction for PETG and a 0.2mm layer height. + +## Post-scripts + +When using the built-in script to render/slice the models in batch, you can also add custom post-processing scripts. There is one for `render.sh` and one for `slice.sh`. They are respectively named `post-render.sh` and `post-slice.sh`. + +As these script can be defined locally, they are not part of the versioned content. Instead, you can find sample files at `post-render-dist.sh` and `post-slice-dist.sh`. To use them, you need to: + +- copy the dist file to a local file, for example: `cp post-render-dist.sh post-render.sh`. +- you need to make sure the file is executable: `chmod +x post-render.sh`. +- finally, add you own commands to the copy. + +As an example: + +- The script used to zip the rendered files: + +```sh +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +stlpath="${project}/dist/stl/" +zippath="stl-scale-24.zip" +logpath="${project}/dist/zip.log" + +# Post process the rendered files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-render script: zip files" +dummy=$( + cd "${stlpath}" + rm *.zip > /dev/null + zip -r "${zippath}" * +) +printmessage "${C_MSG}===========================================" +``` + +- The script used to copy the sliced files to a SD-card: + +```sh +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +gcodepath="${project}/dist/gcode/" +sdcardpath="/PATH/TO/SD/CARD" # <-- CHANGE THIS! +logpath="${project}/dist/gcode-sync.log" + +# Post process the sliced files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-slice script: copy Gcode to the SDcard" +date > ${logpath} +createpath "${sdcardpath}" +rsync -ahvt --no-links --delete --partial --force --modify-window=1 --exclude=.DS_Store --log-file=${logpath} "${gcodepath}" "${sdcardpath}" +printmessage "${C_MSG}===========================================" +``` diff --git a/scale-24/config/config.scad b/scale-24/config/config-dist.scad similarity index 79% rename from scale-24/config/config.scad rename to scale-24/config/config-dist.scad index 82181f3..0c0ca3b 100644 --- a/scale-24/config/config.scad +++ b/scale-24/config/config-dist.scad @@ -23,23 +23,11 @@ /** * A race track system for 1/24 to 1/32 scale RC cars. * - * Configures the project. + * Local configuration for the project. * * @author jsconan */ - projectVersion = "0.5.0"; - -// We will render the object using the specifications of this mode -renderMode = MODE_PROD; - -// Defines the constraints of the printer. -printResolution = 0.2; // The target layer height -nozzleWidth = 0.4; // The size of the printer's nozzle -printTolerance = 0.1; // The print tolerance when pieces need to be assembled -printerLength = 250; // The length of the printer's build plate -printerWidth = 210; // The width of the printer's build plate - // The dimensions and constraints of a track element trackSectionLength = 100; // The nominal length of a track element: the length for straight element, or the radius for a curved element trackSectionWidth = 400; // The virtual width of a track lane: this will condition the outer radius for a curved element (i.e. the width used to compute the outer radius) @@ -60,4 +48,3 @@ flagWidth = 40; // The width of the accessory flag flagHeight = 20; // The height of the accessory flag flagThickness = 0.8; // The thickness of the accessory flag rightOriented = false; // The orientation of the curved elements -printInterval = 5; // Interval between 2 pieces when presented together diff --git a/scale-24/config/setup.scad b/scale-24/config/setup.scad index 88d8e58..49a7d49 100644 --- a/scale-24/config/setup.scad +++ b/scale-24/config/setup.scad @@ -28,8 +28,11 @@ * @author jsconan */ -// As we need to use some shapes, use the right entry point of the library. -include <../../lib/camelSCAD/shapes.scad> +// Bootstrap the project using the global config +include <../../config/setup.scad> + +// Defines the project's version +include // Then we need the config for the project, as well as the related functions include diff --git a/scale-24/config/values.scad b/scale-24/config/values.scad index c6c0cd1..c477108 100644 --- a/scale-24/config/values.scad +++ b/scale-24/config/values.scad @@ -28,34 +28,6 @@ * @author jsconan */ -/** - * Aligns a value with respect to the target layer height. - * @param Number value - * @returns Number - */ -function layerAligned(value) = roundBy(value, printResolution); - -/** - * Aligns a value with respect to the target nozzle size. - * @param Number value - * @returns Number - */ -function nozzleAligned(value) = roundBy(value, nozzleWidth); - -/** - * Gets the thickness of N layers. - * @param Number N - * @returns Number - */ -function layers(N) = N * printResolution; - -/** - * Gets the width of N times the nozzle width. - * @param Number N - * @returns Number - */ -function shells(N) = N * nozzleWidth; - /** * Computes the height of the barrier body part that will be inserted in the holder. * @param Number base - The base unit value used to design the barrier holder. @@ -124,7 +96,7 @@ function getBarrierHolderTopWidth(base, thickness) = nozzleAligned((getBarrierLi * @param Number [distance] - An additional distance added to the outline of the barrier holder. * @returns Number */ -function getBarrierHolderHeight(base, distance = 0) = getBarrierStripHeight(base) + minThickness + printResolution + distance * 2; +function getBarrierHolderHeight(base, distance = 0) = getBarrierStripHeight(base) + minThickness + layerHeight + distance * 2; /** * Computes the height of the link for a barrier holder. @@ -162,14 +134,7 @@ function getBarrierBodyInnerHeight(height, base) = height - (getBarrierStripHeig * @param Number height - The height of the barrier. * @returns Number */ -function getBarrierBodyHeight(height) = height - (minThickness + printResolution) * 2; - -/** - * Gets the length of a curved ctrack elementhunk (the length of the arc of the curve). - * @param Number length - The length of the track element. - * @returns Number - */ -function getCurveLength(length) = getArcLength(radius = length, angle = 90); +function getBarrierBodyHeight(height) = height - (minThickness + layerHeight) * 2; /** * Gets the difference between the length of a curved track element chunk and a straight track element. @@ -217,20 +182,6 @@ function getOuterCurveRatio(length, width, radius) = (width + radius) / length; */ function getCurveRadius(length, ratio) = length * ratio; -/** - * Computes the angle of a curve with respect to the ratio. - * @param Number ratio - The ratio of the curve. - * @returns Number - */ -function getCurveAngle(ratio) = curveAngle / ratio; - -/** - * Computes the rotation angle used to place a curve. - * @param Number angle - The angle of the curve. - * @returns Number - */ -function getCurveRotationAngle(angle) = 45 + (curveAngle - angle) / 2; - /** * Computes the radius of the accessory mast. * @param Number width - The width of the mast. @@ -238,23 +189,6 @@ function getCurveRotationAngle(angle) = 45 + (curveAngle - angle) / 2; */ function getMastRadius(width) = circumradius(n = mastFacets, a = width / 2); -/** - * Computes the print interval between the centers of 2 objects. - * @param Number size - The size of the shape. - * @returns Number - */ -function getPrintInterval(size) = size + printInterval; - -/** - * Centers the children elements to te printer's build plate. - */ -module centerBuildPlate(moveOrigin = false) { - buildPlate([printerLength, printerWidth], center=!moveOrigin); - translate(moveOrigin ? [printerLength, printerWidth, 0] / 2 : [0, 0, 0]) { - children(); - } -}; - /** * Validates the config values, checking if it match the critical constraints. * @param Number length - The nominal size of a track element. @@ -324,7 +258,8 @@ module printConfig(length, width, lane, height, radius, base) { echo(join([ "", str("-- RC Track System ------------"), - str("Version: ", projectVersion), + str("Scale: ", PROJECT_SCALE), + str("Version: ", printVersion()), str("-- Track elements -------------"), str("Track section length: ", length / 10, "cm"), str("Curve section length: ", getCurveLength(length) / 10, "cm"), @@ -354,7 +289,7 @@ module printConfig(length, width, lane, height, radius, base) { str("Flag thickness: ", flagThickness, "mm"), str("-- Printer settings -----------"), str("Nozzle diameter: ", nozzleWidth, "mm"), - str("Print layer: ", printResolution, "mm"), + str("Print layer: ", layerHeight, "mm"), str("Print tolerance: ", printTolerance, "mm"), str("Printer's length: ", printerLength / 10, "cm"), str("Printer's width: ", printerWidth / 10, "cm"), @@ -372,6 +307,3 @@ minWidth = shells(2); // The ratios applied to the base unit value used to design the barrier holder stripHeightRatio = 3; stripIndentRatio = 0.5; - -// The angle of a typical curve -curveAngle = 90; diff --git a/scale-24/config/version.scad b/scale-24/config/version.scad new file mode 100644 index 0000000..af98c39 --- /dev/null +++ b/scale-24/config/version.scad @@ -0,0 +1,32 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/24 to 1/32 scale RC cars. + * + * Version of the project. + * + * @author jsconan + */ + +PROJECT_VERSION = "0.5.0"; +PROJECT_SCALE = "1/24 to 1/32"; diff --git a/scale-24/doc/rctrack-24.jpg b/scale-24/doc/rctrack-24.jpg new file mode 100644 index 0000000..c75aab5 Binary files /dev/null and b/scale-24/doc/rctrack-24.jpg differ diff --git a/scale-24/post-render-dist.sh b/scale-24/post-render-dist.sh new file mode 100755 index 0000000..864fd27 --- /dev/null +++ b/scale-24/post-render-dist.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A sample of post-processing script that can be called once the models have been rendered. +# +# To use it as a skeleton for your own script, please first run the following commands: +# cp post-render-dist.sh post-render.sh +# chmod +x post-render.sh +# +# It will copy the sample to the file `post-render.sh` and make sure it is executable. +# Then, you can modify the copy and add your own commands. +# +# @author jsconan +# + +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +stlpath="${project}/dist/stl/" +zippath="stl-scale-24.zip" +logpath="${project}/dist/zip.log" + +# Post process the rendered files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-render script: zip files" +dummy=$( + cd "${stlpath}" + rm *.zip > /dev/null + zip -r "${zippath}" * +) +printmessage "${C_MSG}===========================================" diff --git a/scale-24/post-slice-dist.sh b/scale-24/post-slice-dist.sh new file mode 100755 index 0000000..0b0f864 --- /dev/null +++ b/scale-24/post-slice-dist.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A sample of post-processing script that can be called once the models have been sliced. +# +# To use it as a skeleton for your own script, please first run the following commands: +# cp post-slice-dist.sh post-slice.sh +# chmod +x post-slice.sh +# +# It will copy the sample to the file `post-slice.sh` and make sure it is executable. +# Then, you can modify the copy and add your own commands. +# +# @author jsconan +# + +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +gcodepath="${project}/dist/gcode/" +sdcardpath="/PATH/TO/SD/CARD" # <-- CHANGE THIS! +logpath="${project}/dist/gcode-sync.log" + +# Post process the sliced files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-slice script: copy Gcode to the SDcard" +date > ${logpath} +createpath "${sdcardpath}" +rsync -ahvt --no-links --delete --partial --force --modify-window=1 --exclude=.DS_Store --log-file=${logpath} "${gcodepath}" "${sdcardpath}" +printmessage "${C_MSG}===========================================" diff --git a/scale-24/render.sh b/scale-24/render.sh index 7cc7587..f6cc1a8 100755 --- a/scale-24/render.sh +++ b/scale-24/render.sh @@ -37,13 +37,14 @@ barrierHeight= sampleSize= # script config -scriptpath=$(dirname $0) -project=$(pwd) -srcpath=${project} -dstpath=${project}/output -configpath=${srcpath}/config -partpath=${srcpath}/parts -platepath=${srcpath}/plates +scriptpath="$(dirname $0)" +project="$(pwd)" +srcpath="${project}" +dstpath="${project}/dist/stl" +slcpath="${project}/dist/gcode" +configpath="${srcpath}/config" +partpath="${srcpath}/parts" +platepath="${srcpath}/plates" format= parallel= showConfig= @@ -53,20 +54,16 @@ renderUnibody= renderSamples= renderPlates= cleanUp= +slice= # include libs source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" -# Renders the files from a path. -# -# @param sourcepath - The path of the folder containing the SCAD files to render. -# @param destpath - The path to the output folder. +# Builds the list of config parameters. # @param right - Right oriented or left oriented -# @param prefix - Optional prefix added to the output fil name -# @param suffix - Optional suffix added to the output fil name -renderpath() { - local rightOriented=$3 - scadrenderall "$1" "$2" "$4" "$5" \ +paramlist() { + local rightOriented=$1 + local params=( "$(varif "trackSectionLength" ${trackSectionLength})" \ "$(varif "trackSectionWidth" ${trackSectionWidth})" \ "$(varif "trackLaneWidth" ${trackLaneWidth})" \ @@ -74,6 +71,19 @@ renderpath() { "$(varif "barrierHeight" ${barrierHeight})" \ "$(varif "sampleSize" ${sampleSize})" \ "$(varif "rightOriented" ${rightOriented})" + ) + echo "${params[@]}" +} + +# Renders the files from a path. +# +# @param sourcepath - The path of the folder containing the SCAD files to render. +# @param destpath - The path to the output folder. +# @param right - Right oriented or left oriented +# @param prefix - Optional prefix added to the output fil name +# @param suffix - Optional suffix added to the output fil name +renderpath() { + scadrenderall "$1" "$2" "$4" "$5" --quiet $(paramlist $3) } # Renders the files from a path, taking care of the curves. @@ -91,10 +101,14 @@ renderpathall() { # Display the render config showconfig() { + local input="${configpath}/print.scad" + local output="${dstpath}/print.echo" local config="${dstpath}/config.txt" createpath "${dstpath}" "output" - printmessage "${C_MSG}Will generates the track elements with respect to the following config:" - renderpath "${configpath}/print.scad" "${dstpath}" 2>&1 | sed -e '1,4d' | sed -e :a -e '$d;N;2,3ba' -e 'P;D' > "${config}" + printmessage "${C_MSG}The track elements would be generated with respect to the following config:" + scadecho "${input}" "${dstpath}" "" "" $(paramlist) > /dev/null + sed '1d; $d' "${output}" > "${config}" + rm "${output}" > /dev/null cat "${config}" } @@ -143,7 +157,7 @@ while (( "$#" )); do trackLaneWidth=$2 shift ;; - "-s"|"--sample") + "-m"|"--sample") sampleSize=$2 shift ;; @@ -155,6 +169,9 @@ while (( "$#" )); do parallel=$2 shift ;; + "-s"|"--slice") + slice=1 + ;; "-c"|"--clean") cleanUp=1 ;; @@ -175,9 +192,10 @@ while (( "$#" )); do echo -e "${C_MSG} -t --track ${C_RST}Set the actual width of a track lane (physical width, used for the arches)" echo -e "${C_MSG} -b --height ${C_RST}Set the height of the track barrier" echo -e "${C_MSG} -r --radius ${C_RST}Set the radius of the track inner curve" - echo -e "${C_MSG} -s --sample ${C_RST}Set the size of sample element" + echo -e "${C_MSG} -m --sample ${C_RST}Set the size of sample element" echo -e "${C_MSG} -f --format ${C_RST}Set the output format" echo -e "${C_MSG} -p --parallel ${C_RST}Set the number of parallel processes" + echo -e "${C_MSG} -s --slice ${C_RST}Slice the rendered files using the default configuration" echo -e "${C_MSG} -c --clean ${C_RST}Clean up the output folder before rendering" echo exit 0 @@ -229,8 +247,16 @@ scadprocesses "${parallel}" if [ "${cleanUp}" != "" ]; then printmessage "${C_CTX}Cleaning up the output folder" rm -rf "${dstpath}" + + if [ "${slice}" != "" ]; then + printmessage "${C_CTX}Cleaning up the slicer output folder" + rm -rf "${slcpath}" + fi fi +# make sure the config exists +distfile "${configpath}/config.scad" + # show the config if [ "${showConfig}" != "" ]; then showconfig @@ -263,3 +289,14 @@ if [ "${renderSamples}" != "" ]; then renderpathall "${partpath}/samples" "${dstpath}/samples" fi +# run a post-render script +if [ -x "${scriptpath}/post-render.sh" ]; then + printmessage "${C_CTX}Calling the post-render script" + "${scriptpath}/post-render.sh" +fi + +# slice the rendered files +if [ "${slice}" != "" ]; then + printmessage "${C_CTX}Slicing the rendered files" + ./slice.sh +fi diff --git a/scale-24/shapes/accessories.scad b/scale-24/shapes/accessories.scad index 2a01fbf..97fdd64 100644 --- a/scale-24/shapes/accessories.scad +++ b/scale-24/shapes/accessories.scad @@ -110,7 +110,7 @@ function getAccessoryStraightMastWidth(wall, base) = * @returns Number */ function getAccessoryFlagLength(width, thickness, mast) = - width + mast / 2 + printResolution + thickness + width + mast / 2 + layerHeight + thickness ; /** @@ -338,14 +338,14 @@ module accessoryBentMast(width, height, wall, base, thickness) { * @param Number wave - The height of the wave */ module accessoryFlag(width, height, thickness, mast, wave = 0) { - distance = printResolution; + distance = layerHeight; ringHeight = height / 4; ringInterval = height - ringHeight; ringOffset = apothem(n=mastFacets, r=getMastRadius(mast)) + distance + thickness; type = wave ? "S" : "V"; rotateZ(270) { - translateY((mast - width) / 2 - printResolution) { + translateY((mast - width) / 2 - layerHeight) { translateZ(ringOffset) { mastRings( width = mast, diff --git a/scale-24/shapes/arch.scad b/scale-24/shapes/arch.scad index 00a19b5..52832ff 100644 --- a/scale-24/shapes/arch.scad +++ b/scale-24/shapes/arch.scad @@ -75,7 +75,7 @@ module archTower(length, thickness, base, wall) { thickness = thickness + printTolerance; holderHeight = getBarrierHolderHeight(base); clipHeight = getBarrierHolderHeight(base, wall + printTolerance); - indent = getBarrierStripIndent(base) + printResolution; + indent = getBarrierStripIndent(base) + layerHeight; length = length / 2; translateX(-clipHeight / 2) { diff --git a/scale-24/shapes/connector.scad b/scale-24/shapes/connector.scad index 0ad8156..5dbd1b3 100644 --- a/scale-24/shapes/connector.scad +++ b/scale-24/shapes/connector.scad @@ -45,7 +45,7 @@ module barrierHolderToUnibodyConnector(length, height, thickness, base) { unibodyLineY = height - holderHeight - base * 2; holderLineY = holderHeight - base * 1.5; unibodyTopWidth = unibodyWidth - base - holderLineY * (unibodyLineX / unibodyLineY) * 2; - indent = getBarrierStripIndent(base) + printResolution; + indent = getBarrierStripIndent(base) + layerHeight; length = length / 2; distribute(intervalX=length, center=true) { @@ -59,7 +59,7 @@ module barrierHolderToUnibodyConnector(length, height, thickness, base) { } translate([length / 2, 0, height - holderLinkHeight]) { barrierLink( - height = holderLinkHeight + printResolution + 1, + height = holderLinkHeight + layerHeight + 1, base = base, distance = printTolerance ); diff --git a/scale-24/shapes/curved.scad b/scale-24/shapes/curved.scad index f580cf8..67e004b 100644 --- a/scale-24/shapes/curved.scad +++ b/scale-24/shapes/curved.scad @@ -42,7 +42,7 @@ function getCurvedBarrierLength(length, width, base, ratio) = radius = getCurveRadius(length, ratio), rotationAngle = getCurveRotationAngle(angle), projectedWidth = width * cos(rotationAngle) / 2, - projectedLink = getBarrierLinkLength(base) * cos(curveAngle + rotationAngle) + projectedLink = getBarrierLinkLength(base) * cos(CURVE_ANGLE + rotationAngle) ) getChordLength(angle, radius) + width / 2 + projectedWidth + max(0, projectedLink - projectedWidth) @@ -62,7 +62,7 @@ function getCurvedBarrierWidth(length, width, base, ratio) = radius = getCurveRadius(length, ratio), rotationAngle = getCurveRotationAngle(angle), projectedWidth = width * sin(rotationAngle) / 2, - projectedLink = getBarrierLinkLength(base) * sin(curveAngle + rotationAngle) + projectedLink = getBarrierLinkLength(base) * sin(CURVE_ANGLE + rotationAngle) ) getChordHeight(angle, radius) + width / 2 + projectedWidth + max(0, projectedLink - projectedWidth) @@ -115,13 +115,12 @@ module curvedBarrierNotch(radius, thickness, base, distance = 0) { } /** - * Place a curved element with respect to the length and the ratio. - * @param Number length - The length of a track element. + * Places a curved element. * @param Number radius - The radius of the curve. * @param Number angle - The angle of the curve. - * @param Number z - An option Z-axis translation + * @param Number z - An option Z-axis translation. */ -module placeCurvedElement(length, radius, angle, z = 0) { +module placeCurvedElement(radius, angle, z=0) { translate([0, getChordHeight(angle, radius) / 2 - radius, z]) { rotateZ(getCurveRotationAngle(angle)) { children(); @@ -138,7 +137,7 @@ module placeCurvedElement(length, radius, angle, z = 0) { * @param Number right - Is the curve oriented to the right? */ module curvedLinks(radius, angle, linkHeight, base, right = false) { - remainingAngle = curveAngle - angle; + remainingAngle = CURVE_ANGLE - angle; maleLinkDirection = right ? 180 : 0; maleLinkPosition = right ? 270 : -remainingAngle; femaleLinkDirection = right ? 90 : -90; @@ -148,7 +147,7 @@ module curvedLinks(radius, angle, linkHeight, base, right = false) { translateY(radius) { rotateZ(maleLinkDirection) { barrierLink( - height = linkHeight - printResolution, + height = linkHeight - layerHeight, base = base ); } @@ -160,7 +159,7 @@ module curvedLinks(radius, angle, linkHeight, base, right = false) { translate([radius, 0, -1]) { rotateZ(femaleLinkDirection) { barrierLink( - height = linkHeight + printResolution + 1, + height = linkHeight + layerHeight + 1, base = base, distance = printTolerance ); @@ -170,19 +169,6 @@ module curvedLinks(radius, angle, linkHeight, base, right = false) { } } -/** - * Extrudes the profile on the expected circle path. - * @param Number radius - The radius of the curve. - * @param Number angle - The extrusion angle. - */ -module extrudeCurvedProfile(radius, angle) { - rotate_extrude(angle=angle, convexity=10) { - translateX(radius) { - children(); - } - } -} - /** * Draws the main shape of a curved barrier holder. * @param Number length - The length of the element. @@ -196,7 +182,7 @@ module curvedBarrierMain(length, thickness, base, ratio = 1, right = false) { angle = getCurveAngle(ratio); linkHeight = getBarrierHolderLinkHeight(base); - placeCurvedElement(length=length, radius=radius, angle=angle) { + placeCurvedElement(radius=radius, angle=angle) { curvedLinks(radius=radius, angle=angle, linkHeight=linkHeight, base=base, right=right) { extrudeCurvedProfile(radius=radius, angle=angle) { barrierHolderProfile( @@ -222,7 +208,7 @@ module curvedBarrierUnibody(length, height, thickness, base, ratio = 1, right = angle = getCurveAngle(ratio); linkHeight = getBarrierUnibodyLinkHeight(height, base); - placeCurvedElement(length=length, radius=radius, angle=angle) { + placeCurvedElement(radius=radius, angle=angle) { curvedLinks(radius=radius, angle=angle, linkHeight=linkHeight, base=base, right=right) { extrudeCurvedProfile(radius=radius, angle=angle) { barrierUnibodyProfile( @@ -257,7 +243,7 @@ module curvedBarrierHolder(length, thickness, base, ratio = 1, right = false) { ratio = ratio, right = right ); - placeCurvedElement(length=length, radius=radius, angle=angle, z=minThickness) { + placeCurvedElement(radius=radius, angle=angle, z=minThickness) { difference() { pipeSegment( r = radius + thickness / 2, diff --git a/scale-24/shapes/straight.scad b/scale-24/shapes/straight.scad index e352d65..5db42ba 100644 --- a/scale-24/shapes/straight.scad +++ b/scale-24/shapes/straight.scad @@ -78,7 +78,7 @@ module barrierBody(length, height, thickness, base, notches = 1) { module straightLinkMale(length, linkHeight, base) { translateX(-length / 2) { barrierLink( - height = linkHeight - printResolution, + height = linkHeight - layerHeight, base = base ); } @@ -96,7 +96,7 @@ module straightLinkFemale(length, linkHeight, base) { children(); translate([length / 2, 0, -1]) { barrierLink( - height = linkHeight + printResolution + 1, + height = linkHeight + layerHeight + 1, base = base, distance = printTolerance ); @@ -118,18 +118,6 @@ module straightLinks(length, linkHeight, base) { } } -/** - * Extrudes the profile on the expected linear length. - * @param Number length - The length of the element. - */ -module extrudeStraightProfile(length) { - rotate([90, 0, 90]) { - linear_extrude(height=length, center=true, convexity=10) { - children(); - } - } -} - /** * Draws the main shape of a straight barrier holder. * @param Number length - The length of the element. diff --git a/scale-24/shapes/uturn.scad b/scale-24/shapes/uturn.scad index abad44d..33460c1 100644 --- a/scale-24/shapes/uturn.scad +++ b/scale-24/shapes/uturn.scad @@ -87,7 +87,7 @@ module uTurnBarrierHolder(length, height, thickness, base, gap, right = false) { towerWidth = nozzleAligned(thickness + minWidth); towerHeight = getBarrierBodyInnerHeight(height, base) / 2; interval = (getBarrierHolderWidth(base) + gap) / 2; - indent = getBarrierStripIndent(base) + printResolution; + indent = getBarrierStripIndent(base) + layerHeight; dir = right ? -1 : 1; length = length / 2; diff --git a/scale-24/slice.sh b/scale-24/slice.sh index 4f239c2..2705fb3 100755 --- a/scale-24/slice.sh +++ b/scale-24/slice.sh @@ -29,20 +29,26 @@ # # script config +scriptpath="$(dirname $0)" configpath="config/config.ini" -configdefault="config/config-dist.ini" + +# include libs +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" # defines the config path -if [ "${configpath}" != "" ] && [ ! -f "${configpath}" ]; then - printmessage "${C_ERR}Warning! The config for Slic3r does not exist.\nWill use the default one" - cp "${configdefault}" "${configpath}" -fi +distfile "${configpath}" # redirect to the lib utils "$(dirname $0)/../lib/camelSCAD/scripts/slice.sh" \ - --input "output" \ - --output "dist" \ + --input "dist/stl" \ + --output "dist/gcode" \ --config "${configpath}" \ --prusaslicer \ --recurse \ "$@" + +# run a post-slice script +if [ -x "${scriptpath}/post-slice.sh" ]; then + printmessage "${C_CTX}Calling the post-slice script" + "${scriptpath}/post-slice.sh" +fi diff --git a/scale-64/README.md b/scale-64/README.md new file mode 100644 index 0000000..d650d2e --- /dev/null +++ b/scale-64/README.md @@ -0,0 +1,191 @@ +# 1/64 to 1/76 scale RC-track system + +A printable race track systems for remote controlled cars from scale 1/64 to 1/76. + + + +- [At a glance](#Ataglance) + - [Split tiles](#Splittiles) + - [Full tiles](#Fulltiles) +- [Configuration](#Configuration) +- [Render the parts](#Rendertheparts) +- [Post-scripts](#Post-scripts) + + + + +## At a glance + +The project contains designs for a modular race track system aimed at remote controlled cars. The parts are designed using a scripting language, processed by [OpenSCAD](https://openscad.org/about.html). There is no ready to use 3D model files in the source code. If you are interested in such files, please look at the [released versions](https://github.com/jsconan/rc-tracks/releases) which contains 3D model files built with default parameters. However, if you want to customize these parts, tailoring them with your measures, you should rather download the source code and then tweak the configuration files before generating your own 3D model files. + +> **Note:** the scales are given as an estimate, not all scales have been tested. The `1/64 to 1/76` variant has been tested with `1/76` scale models. + +This variant contains a set of track barriers and ground tiles that can be assembled together in order to design a race track. To keep the track in place, each barrier comes with a fastener hole allowing to screw or nail it to a board. As the barriers, as well as the tiles, are modular, you can design tracks of various sizes. The only limit is the size of your printer. + +There are multiple ways of using this modular system: + +- barriers only +- ground tiles only with another set of barriers +- both barriers and ground tiles +- full tiles printed with ground and barriers together + +![RC track](./doc/rctrack-64.jpg) + +### Split tiles + +The base variant relies on split parts, barriers and ground, to be assembled together. This allows to print each part in a different color. However, this variant may take longer to be printed, and this makes the build less easier as each single part must be added and fastened separately. This is a good choice when the race track is intended to be fixed on a board, the barriers have holes for screwing or nailing the track to a support. + +![assembling track sections](./doc/track-sections.gif) + +### Full tiles + +An additional variant is proposed, with full tiles printed in place, containing both the ground and the barrier. This variant is a bit faster to be printed, and it makes it easier to build the race track. However, each tile will come in a single color. but it could still be painted if needed. This variant also have holes for screwing or nailing the track to a support. + +![full tiles](./doc/full-tiles.gif) + +### Printing tweaks + +Depending on the printed material, the surface may not be rough enough for the car wheels to grip. This can be fixed by sanding the printed tiles. This can also be fixed by tweaking the print in order to give the tiles ground a bit more grip. + +Using [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer), the print model can be adjusted so that a part of it has a different setting. For example, we can change how the last layer of the tile ground is printed. A good choice is to turn off the top layer infill, then change the infill pattern for this layer only. + +From the PrusaSlicer GUI, do a right-click on the model, then add a **Height range modifier**. + +![adding an height range modifier](./doc/adding-custom-layer.png) + +Select the newly added layer range, then set the right position. With respect to the default config, the ground is 0.8mm thick, and each layer is 0.2mm, so we need to position the modifier on the layer 0.6 to 0.8. + +![custom layer position](./doc/custom-layer-position.png) + +As wee want to tweak the infill, right-click on the range, and add an infill from the menu. + +![custom layer infill](./doc/custom-layer-add-infill.png) + +Finally, we need to switch off the top layer infill and set a different infill for this particular layer. Make sure to set `0` to the **Top solid layers** entry. Then select a fill pattern for the regular infill. As a suggestion, the **Hilbert curve** with a 50% density gives a decent grip and a pretty nice finish. + +![custom layer settings](./doc/custom-layer-settings.png) + +Note: this tweak applies from the version 2.3 of the software. + +This tweak could also apply to the original software, say [Slic3r](https://slic3r.org/). But the settings may differ slightly. + +## Configuration + +The configuration may be changed locally. To not collide with changes in the main implementation, the configuration files are not versioned. Instead, you will find `-dist` files that contain a copy of the typical configuration. + +From a fresh copy of the project, you will need first to create these configuration files. The easiest way is to call the `init.sh` script, that will take care of this for you. The configuration files will also be checked and created if needed each time the `render.sh` script is called. + +This initial creation of the configuration files could also be done manually. Here is how: + +1. Go to the `config` folder +2. Copy any of the files having a `-dist` suffix in their name to a file without this suffix. + + _Example:_ copy `config-dist.scad` to `config.scad` + +## Render the parts + +The parts are all located into the `parts` folder. They can all be opened separately in [OpenSCAD](https://openscad.org/) and rendered. + +However, it is possible to render all parts in batch. The script `render.sh` takes care of this. + +This is a command-line tool, which accept several parameters. By default, it will render the preset selected in the config. + +It is possible to select another preset, as well as set a different number of cells for the containers. + +The parameter `-h` make it show the help. + +Running the command `render.sh -h` will show this message: + +``` +Renders OpenSCAD files + Usage: + ./render.sh [command] [-h|--help] [-o|--option value] files + + a, all Render all elements (default) + b, barriers Render the sets of barriers + e, elements Render the elements + g, ground Render the ground tiles + f, tiles Render the full tiles + t, tools Render the tools + c, config Show the config values + -h, --help Show this help + -t --track Set the width of the track lane + -w, --width Set the width of the track barriers + -b --height Set the height of the track barriers + -k --chunks Set the number of barrier chunks per track section + -g --ground Set the thickness of the ground tiles + -d --diameter Set the diameter of the barrier fasteners + -hd --headDiameter Set the diameter of the barrier fasteners head + -hh --headHeight Set the height of the barrier fasteners head + -u --upsideDown Flip the ground tiles to print them upside down + -q --quantity Set the quantity of elements to print per set + -f --format Set the output format + -p --parallel Set the number of parallel processes + -s --slice Slice the rendered files using the default configuration + -c --clean Clean up the output folder before rendering +``` + +The STL files are rendered to the `dist/stl` folder. + +If the slicer [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer) is installed, running the command `render.sh -s` will produce the [G-code](https://en.wikipedia.org/wiki/G-code) from the rendered STL files and using the setting from the file `config/config.ini`. Out of the box, it is produce instruction for PETG and a 0.2mm layer height. + +## Post-scripts + +When using the built-in script to render/slice the models in batch, you can also add custom post-processing scripts. There is one for `render.sh` and one for `slice.sh`. They are respectively named `post-render.sh` and `post-slice.sh`. + +As these script can be defined locally, they are not part of the versioned content. Instead, you can find sample files at `post-render-dist.sh` and `post-slice-dist.sh`. To use them, you need to: + +- copy the dist file to a local file, for example: `cp post-render-dist.sh post-render.sh`. +- you need to make sure the file is executable: `chmod +x post-render.sh`. +- finally, add you own commands to the copy. + +As an example: + +- The script used to zip the rendered files: + +```sh +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +stlpath="${project}/dist/stl/" +zippath="stl-scale-64.zip" +logpath="${project}/dist/zip.log" + +# Post process the rendered files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-render script: zip files" +dummy=$( + cd "${stlpath}" + rm *.zip > /dev/null + zip -r "${zippath}" * +) +printmessage "${C_MSG}===========================================" +``` + +- The script used to copy the sliced files to a SD-card: + +```sh +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +gcodepath="${project}/dist/gcode/" +sdcardpath="/PATH/TO/SD/CARD" # <-- CHANGE THIS! +logpath="${project}/dist/gcode-sync.log" + +# Post process the sliced files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-slice script: copy Gcode to the SDcard" +date > ${logpath} +createpath "${sdcardpath}" +rsync -ahvt --no-links --delete --partial --force --modify-window=1 --exclude=.DS_Store --log-file=${logpath} "${gcodepath}" "${sdcardpath}" +printmessage "${C_MSG}===========================================" +``` diff --git a/scale-64/config/config-dist.ini b/scale-64/config/config-dist.ini new file mode 100644 index 0000000..8e836f6 --- /dev/null +++ b/scale-64/config/config-dist.ini @@ -0,0 +1,278 @@ +# generated by PrusaSlicer 2.4.0+x64 on 2022-01-15 at 22:16:29 UTC +avoid_crossing_perimeters = 0 +avoid_crossing_perimeters_max_detour = 0 +bed_custom_model = +bed_custom_texture = +bed_shape = 0x0,250x0,250x210,0x210 +bed_temperature = 60 +before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n +between_objects_gcode = +bottom_fill_pattern = monotonic +bottom_solid_layers = 4 +bottom_solid_min_thickness = 0.5 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_fan_speed = 100 +bridge_flow_ratio = 0.95 +bridge_speed = 25 +brim_separation = 0.1 +brim_type = outer_only +brim_width = 0 +clip_multipart_objects = 1 +color_change_gcode = M600\nG1 E0.4 F1500 ; prime after color change +colorprint_heights = +compatible_printers_condition_cummulative = "printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4";"nozzle_diameter[0]!=0.8 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)" +complete_objects = 0 +cooling = 1 +cooling_tube_length = 5 +cooling_tube_retraction = 91.5 +default_acceleration = 1000 +default_filament_profile = "Prusament PLA" +default_print_profile = 0.15mm QUALITY @MK3 +deretract_speed = 0 +disable_fan_first_layers = 1 +dont_support_bridges = 0 +draft_shield = disabled +duplicate_distance = 6 +elefant_foot_compensation = 0.2 +end_filament_gcode = "; Filament-specific end gcode" +end_gcode = G4 ; wait\nM221 S100 ; reset flow\nM900 K0 ; reset LA\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3|@0.25 nozzle MK3).*/}M907 E538 ; reset extruder motor current{endif}\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)}{endif} ; Move print head up\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors +ensure_vertical_shell_thickness = 1 +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 +external_perimeters_first = 0 +extra_loading_move = -2 +extra_perimeters = 0 +extruder_clearance_height = 20 +extruder_clearance_radius = 45 +extruder_colour = "" +extruder_offset = 0x0 +extrusion_axis = E +extrusion_multiplier = 1 +extrusion_width = 0.45 +fan_always_on = 1 +fan_below_layer_time = 100 +filament_colour = #FF8000 +filament_cooling_final_speed = 3.4 +filament_cooling_initial_speed = 2.2 +filament_cooling_moves = 4 +filament_cost = 30.24 +filament_density = 1.24 +filament_deretract_speed = nil +filament_diameter = 1.75 +filament_load_time = 0 +filament_loading_speed = 28 +filament_loading_speed_start = 3 +filament_max_volumetric_speed = 15 +filament_minimal_purge_on_wipe_tower = 15 +filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" +filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" +filament_retract_before_travel = nil +filament_retract_before_wipe = nil +filament_retract_layer_change = nil +filament_retract_length = nil +filament_retract_lift = nil +filament_retract_lift_above = nil +filament_retract_lift_below = nil +filament_retract_restart_extra = nil +filament_retract_speed = nil +filament_settings_id = "Prusament PLA" +filament_soluble = 0 +filament_spool_weight = 201 +filament_toolchange_delay = 0 +filament_type = PLA +filament_unload_time = 0 +filament_unloading_speed = 90 +filament_unloading_speed_start = 100 +filament_vendor = Prusa Polymers +filament_wipe = nil +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_acceleration = 800 +first_layer_acceleration_over_raft = 0 +first_layer_bed_temperature = 60 +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 20 +first_layer_speed_over_raft = 30 +first_layer_temperature = 215 +full_fan_speed_layer = 4 +fuzzy_skin = none +fuzzy_skin_point_dist = 0.8 +fuzzy_skin_thickness = 0.3 +gap_fill_enabled = 1 +gap_fill_speed = 40 +gcode_comments = 0 +gcode_flavor = marlin +gcode_label_objects = 1 +gcode_resolution = 0.0125 +high_current_on_filament_swap = 0 +host_type = octoprint +infill_acceleration = 1000 +infill_anchor = 2.5 +infill_anchor_max = 12 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +interface_shells = 0 +ironing = 0 +ironing_flowrate = 15% +ironing_spacing = 0.1 +ironing_speed = 15 +ironing_type = top +layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] +layer_height = 0.2 +machine_limits_usage = emit_to_gcode +machine_max_acceleration_e = 5000,5000 +machine_max_acceleration_extruding = 1250,1250 +machine_max_acceleration_retracting = 1250,1250 +machine_max_acceleration_travel = 1500,1250 +machine_max_acceleration_x = 1000,960 +machine_max_acceleration_y = 1000,960 +machine_max_acceleration_z = 200,200 +machine_max_feedrate_e = 120,120 +machine_max_feedrate_x = 200,100 +machine_max_feedrate_y = 200,100 +machine_max_feedrate_z = 12,12 +machine_max_jerk_e = 4.5,4.5 +machine_max_jerk_x = 8,8 +machine_max_jerk_y = 8,8 +machine_max_jerk_z = 0.4,0.4 +machine_min_extruding_rate = 0,0 +machine_min_travel_rate = 0,0 +max_fan_speed = 100 +max_layer_height = 0.25 +max_print_height = 210 +max_print_speed = 200 +max_volumetric_speed = 0 +min_fan_speed = 100 +min_layer_height = 0.07 +min_print_speed = 15 +min_skirt_length = 4 +mmu_segmented_region_max_width = 0 +notes = +nozzle_diameter = 0.4 +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode +overhangs = 1 +parking_pos_retraction = 92 +pause_print_gcode = M601 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 60 +perimeters = 2 +physical_printer_settings_id = +post_process = +print_host = +print_settings_id = 0.20mm SPEED @MK3 +printer_model = MK3 +printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n +printer_settings_id = Original Prusa i3 MK3 +printer_technology = FFF +printer_variant = 0.4 +printer_vendor = +printhost_apikey = +printhost_cafile = +raft_contact_distance = 0.2 +raft_expansion = 1.5 +raft_first_layer_density = 90% +raft_first_layer_expansion = 3 +raft_layers = 0 +remaining_times = 1 +resolution = 0 +retract_before_travel = 1 +retract_before_wipe = 0% +retract_layer_change = 1 +retract_length = 0.8 +retract_length_toolchange = 4 +retract_lift = 0.4 +retract_lift_above = 0 +retract_lift_below = 209 +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 35 +seam_position = nearest +silent_mode = 1 +single_extruder_multi_material = 0 +single_extruder_multi_material_priming = 0 +skirt_distance = 2 +skirt_height = 3 +skirts = 1 +slice_closing_radius = 0.049 +slicing_mode = regular +slowdown_below_layer_time = 15 +small_perimeter_speed = 25 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 200 +spiral_vase = 0 +standby_temperature_delta = -5 +start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0" +start_gcode = M862.3 P "[printer_model]" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM115 U3.10.0 ; tell printer latest fw version\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Z0.2 F720\nG1 Y-3 F1000 ; go outside print area\nG92 E0\nG1 X60 E9 F1000 ; intro line\nG1 X100 E12.5 F1000 ; intro line\nG92 E0\nM221 S{if layer_height<0.075}100{else}95{endif}\n\n; Don't change E values below. Excessive value can damage the printer.\n{if print_settings_id=~/.*(DETAIL @MK3|QUALITY @MK3).*/}M907 E430 ; set extruder motor current{endif}\n{if print_settings_id=~/.*(SPEED @MK3|DRAFT @MK3).*/}M907 E538 ; set extruder motor current{endif} +support_material = 0 +support_material_angle = 0 +support_material_auto = 1 +support_material_bottom_contact_distance = 0 +support_material_bottom_interface_layers = 0 +support_material_buildplate_only = 0 +support_material_closing_radius = 2 +support_material_contact_distance = 0.2 +support_material_enforce_layers = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 0 +support_material_interface_layers = 2 +support_material_interface_pattern = rectilinear +support_material_interface_spacing = 0.2 +support_material_interface_speed = 80% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_style = grid +support_material_synchronize_layers = 0 +support_material_threshold = 50 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +temperature = 215 +template_custom_gcode = +thick_bridges = 0 +thin_walls = 0 +threads = 16 +thumbnails = +toolchange_gcode = +top_fill_pattern = monotonic +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 50 +top_solid_layers = 6 +top_solid_min_thickness = 0.7 +travel_speed = 180 +travel_speed_z = 12 +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 1 +wipe_into_infill = 0 +wipe_into_objects = 0 +wipe_tower = 1 +wipe_tower_bridging = 10 +wipe_tower_brim_width = 2 +wipe_tower_no_sparse_layers = 0 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 170 +wipe_tower_y = 125 +wiping_volumes_extruders = 70,70 +wiping_volumes_matrix = 0 +xy_size_compensation = 0 +z_offset = 0 diff --git a/scale-64/config/config-dist.scad b/scale-64/config/config-dist.scad new file mode 100644 index 0000000..00e58c0 --- /dev/null +++ b/scale-64/config/config-dist.scad @@ -0,0 +1,71 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Local configuration for the project. + * + * @author jsconan + */ + +// The dimensions and constraints of a track element +trackLaneWidth = 120; // The width of the track lane (the distance between the barriers) +trackGroundThickness = .8; // The thickness of a track tile (track ground) +barrierWidth = 6; // The width of the barriers +barrierHeight = 8; // The height of the barriers +barrierChunks = 4; // The number of barrier chunks per section +fastenerDiameter = 2; // The diameter of the fasteners that can be used for the barriers +fastenerHeadDiameter = 4; // The diameter of the fasteners head +fastenerHeadHeight = 1; // The height of the fasteners head +startLines = 2; // The number of starting lines +startPositions = 2; // The number of starting positions on a same line +shiftStartPositions = false; // Tells if the positions on a same starting line should be shifted + +// Options for the ready to print models +printGroundUpsideDown = true; // Flip the ground tiles to print them upside down +printQuantity = 1; // Quantity of elements to print per set +showConfig = 0; // Show the config when rendering a model. The render script uses it to extract the config + +// Colors applied to the elements when previewed. +// This will be used for the animations and other pictures, but this won't have effect on the ready to print elements. +colorGround = "#444"; // Color of the ground tiles +colorTile = "#468"; // Color of the full tiles +colorDecoration = "#eed"; // Color of the ground tiles decoration +colorPeg = "#aaa"; // Color of the barrier pegs +colorBarrier = "#88a"; // Color of the barriers, no matter the coordinate +colorEven = "#eec"; // Color of the barriers, when placed at an even coordinate +colorOdd = "#c24"; // Color of the barriers, when placed at an odd coordinate + +// Options for the animations +defaultScaleFrom = vector3D(.1); // Origin scale factor for the models when animating +defaultScaleTo = vector3D(1); // Target scale factor for the models when animating +defaultRotateFrom = [-RIGHT, -RIGHT, RIGHT]; // Origin rotation angles for the models when animating +defaultRotateTo = vector3D(0); // Target rotation angles for the models when animating +defaultTranslateFrom = [-200, 150, 150]; // Origin position for the models when animating +defaultTranslateTo = ORIGIN_3D; // Target position for the models when animating +defaultPresentation = ORIGIN_3D; // Position to present the models +defaultSlideTo = [200, 150, 150]; // Target position for the models when sliding +presentationSteps = 2; // Number of steps applied to present a model +animateSteps = 1; // Number of steps applied for one animation move +slideSteps = 1; // Number of steps applied to slide a model +showSteps = 0; // Show the expected number of steps for the whole animation diff --git a/scale-64/config/constants.scad b/scale-64/config/constants.scad new file mode 100644 index 0000000..a436085 --- /dev/null +++ b/scale-64/config/constants.scad @@ -0,0 +1,32 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for RC cars of various scales. + * + * Local constants for the project. + * + * @author jsconan + */ + +// The number of fastener holes per barrier chunks +FASTENER_HOLES = 1; diff --git a/scale-64/config/helpers.scad b/scale-64/config/helpers.scad new file mode 100644 index 0000000..a183569 --- /dev/null +++ b/scale-64/config/helpers.scad @@ -0,0 +1,92 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Local helper functions for the project. + * + * @author jsconan + */ + +/** + * Computes the overall width of a track section. + * @param Number laneWidth - The width of a track lane. + * @param Number barrierWidth - The width of the barriers. + * @returns Number + */ +function getTrackSectionWidth(laneWidth, barrierWidth) = laneWidth + barrierWidth * 2; + +/** + * Computes the overall length of a track section. + * @param Number laneWidth - The width of a track lane. + * @param Number barrierWidth - The width of the barriers. + * @returns Number + */ +function getTrackSectionLength(laneWidth, barrierWidth) = getTrackSectionWidth(laneWidth, barrierWidth) + laneWidth / 4; + +/** + * Computes the width of the track lane from the given track section length and width. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @returns Number + */ +function getTrackLaneWidth(width, barrierWidth) = width - barrierWidth * 2; + +/** + * Computes the length of a barrier chunk. + * @param Number laneWidth - The width of a track lane. + * @param Number barrierWidth - The width of the barriers. + * @param Number barrierChunks - The number barriers per track section. + * @returns Number + */ +function getBarrierLength(laneWidth, barrierWidth, barrierChunks) = getTrackSectionLength(laneWidth, barrierWidth) / barrierChunks; + +/** + * Computes the angle of a curve with respect to the ratio. + * @param Number ratio - The ratio of the curve. + * @returns Number + */ +function getCurveAngle(ratio) = + let( + ratio = abs(ratio) + ) + CURVE_ANGLE / (ratio < 1 ? 1 / ratio : ratio > 1 ? ratio * 2 : 1) +; + +/** + * Computes the inner radius of a curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveInnerRadius(length, width, ratio=1) = length * (ratio - 1) + (length - width) / 2; + +/** + * Computes the outer radius of a curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveOuterRadius(length, width, ratio=1) = width + getCurveInnerRadius(length=length, width=width, ratio=ratio); diff --git a/scale-64/config/setup.scad b/scale-64/config/setup.scad new file mode 100644 index 0000000..20aa195 --- /dev/null +++ b/scale-64/config/setup.scad @@ -0,0 +1,155 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Setup the project. + * + * @author jsconan + */ + +// Bootstrap the project using the global config +include <../../config/setup.scad> + +// Defines the project's version +include + +// Include the config for the project +include +include +include + +// Include the shapes for the barriers +include <../shapes/barriers/helpers.scad> +include <../shapes/barriers/profiles.scad> +include <../shapes/barriers/fragments.scad> +include <../shapes/barriers/straight.scad> +include <../shapes/barriers/curved.scad> +include <../shapes/barriers/elements.scad> + +// Include the shapes for the ground tiles +include <../shapes/grounds/helpers.scad> +include <../shapes/grounds/profiles.scad> +include <../shapes/grounds/fragments.scad> +include <../shapes/grounds/straight.scad> +include <../shapes/grounds/curved.scad> +include <../shapes/grounds/elements.scad> + +// Include the shapes for the full tiles +include <../shapes/tiles/profiles.scad> +include <../shapes/tiles/fragments.scad> +include <../shapes/tiles/straight.scad> +include <../shapes/tiles/curved.scad> +include <../shapes/tiles/elements.scad> + +// Include the shapes for the animations +include <../shapes/animations/helpers.scad> +include <../shapes/animations/operators.scad> +include <../shapes/animations/straight.scad> +include <../shapes/animations/curved.scad> + +// The overall length of a track section (size of a tile in the track) +trackSectionLength = getTrackSectionLength(trackLaneWidth, barrierWidth); + +// The overall width of a track section (size of a tile in the track) +trackSectionWidth = getTrackSectionWidth(trackLaneWidth, barrierWidth); + +// The length of a barrier chunk +barrierLength = getBarrierLength(trackLaneWidth, barrierWidth, barrierChunks); + +// Show the config values +if (showConfig) { + let( + barrierBaseUnit = getBarrierBaseUnit(barrierWidth, barrierHeight), + trackSectionPadding = (trackSectionLength - trackSectionWidth) / 2, + tightCurveInnerRadius = getCurveInnerRadius(trackSectionLength, trackSectionWidth, 1) + barrierWidth, + tightCurveOuterRadius = getCurveOuterRadius(trackSectionLength, trackSectionWidth, 1) - barrierWidth, + largeCurveInnerRadius = getCurveInnerRadius(trackSectionLength, trackSectionWidth, 2) + barrierWidth, + largeCurveOuterRadius = getCurveOuterRadius(trackSectionLength, trackSectionWidth, 2) - barrierWidth + ) { + echo(join([ + "", + str("-- RC Track System ------------------"), + str("Scale: ", PROJECT_SCALE), + str("Version: ", printVersion()), + str("-- Track elements -------------------"), + str("Track lane width: ", trackLaneWidth / 10, "cm"), + str("Track section length: ", trackSectionLength / 10, "cm"), + str("Track section width: ", trackSectionWidth / 10, "cm"), + str("Track section padding: ", trackSectionPadding / 10, "cm"), + str("Tight curve inner radius: ", tightCurveInnerRadius / 10, "cm"), + str("Tight curve outer radius: ", tightCurveOuterRadius / 10, "cm"), + str("Large curve inner radius: ", largeCurveInnerRadius / 10, "cm"), + str("Large curve outer radius: ", largeCurveOuterRadius / 10, "cm"), + str("Barrier width: ", barrierWidth, "mm"), + str("Barrier height: ", barrierHeight, "mm"), + str("Barrier length: ", barrierLength, "mm"), + str("Barrier chunks: ", barrierChunks, " per section"), + str("Barrier base value: ", barrierBaseUnit, "mm"), + str("Barrier fastener diameter ", fastenerDiameter, "mm"), + str("Barrier fastener head diameter ", fastenerHeadDiameter, "mm"), + str("Barrier fastener head height ", fastenerHeadHeight, "mm"), + str("Ground thickness: ", trackGroundThickness, "mm"), + str("-- Printer settings -----------------"), + str("Nozzle diameter: ", nozzleWidth, "mm"), + str("Print layer: ", layerHeight, "mm"), + str("Print tolerance: ", printTolerance, "mm"), + str("Printer's length: ", printerLength / 10, "cm"), + str("Printer's width: ", printerWidth / 10, "cm"), + str("Print interval: ", printInterval, "mm"), + "" + ], str(chr(13), chr(10)))); + } +} + +// Validate the config values, checking if they match the critical constraints. +let( + barrierLinkLength = getBarrierLinkLength(barrierWidth, barrierHeight), + barrierPegDiameter = getBarrierPegDiameter(barrierWidth, barrierHeight), + barrierBaseUnit = getBarrierBaseUnit(barrierWidth, barrierHeight) +) { + assert( + barrierLength > barrierLinkLength * 2 + barrierPegDiameter + shells(8), + "The size of a barrier chunk is too small! Please increase the track lane or reduce the number of chunks per track section." + ); + assert( + !(barrierChunks % 2), + "The number of chunks per track section must be a factor of 2." + ); + assert( + barrierWidth > fastenerDiameter + barrierBaseUnit * 2, + "The diameter of the barrier fasteners is too large to fit into the barrier chunks!" + ); + assert( + barrierWidth > fastenerHeadDiameter + barrierBaseUnit, + "The diameter of the barrier fasteners head is too large to fit into the barrier chunks!" + ); + assert( + barrierHeight > fastenerHeadHeight * 2 + barrierBaseUnit, + "The height of the barrier fasteners head is too large to fit into the barrier chunks!" + ); + assert( + trackGroundThickness > layers(2), + "The ground thickness is too small, please increase it!" + ); +} diff --git a/scale-64/config/version.scad b/scale-64/config/version.scad new file mode 100644 index 0000000..e362479 --- /dev/null +++ b/scale-64/config/version.scad @@ -0,0 +1,32 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2020-2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Version of the project. + * + * @author jsconan + */ + +PROJECT_VERSION = "1.0.0"; +PROJECT_SCALE = "1/64 to 1/76"; diff --git a/scale-64/doc/adding-custom-layer.png b/scale-64/doc/adding-custom-layer.png new file mode 100644 index 0000000..0ac3f86 Binary files /dev/null and b/scale-64/doc/adding-custom-layer.png differ diff --git a/scale-64/doc/custom-layer-add-infill.png b/scale-64/doc/custom-layer-add-infill.png new file mode 100644 index 0000000..01f1ff2 Binary files /dev/null and b/scale-64/doc/custom-layer-add-infill.png differ diff --git a/scale-64/doc/custom-layer-position.png b/scale-64/doc/custom-layer-position.png new file mode 100644 index 0000000..bdf5e8c Binary files /dev/null and b/scale-64/doc/custom-layer-position.png differ diff --git a/scale-64/doc/custom-layer-settings.png b/scale-64/doc/custom-layer-settings.png new file mode 100644 index 0000000..7cd075a Binary files /dev/null and b/scale-64/doc/custom-layer-settings.png differ diff --git a/scale-64/doc/full-tiles.gif b/scale-64/doc/full-tiles.gif new file mode 100644 index 0000000..04ec01b Binary files /dev/null and b/scale-64/doc/full-tiles.gif differ diff --git a/scale-64/doc/rctrack-64.jpg b/scale-64/doc/rctrack-64.jpg new file mode 100644 index 0000000..603255b Binary files /dev/null and b/scale-64/doc/rctrack-64.jpg differ diff --git a/scale-64/doc/track-sections.gif b/scale-64/doc/track-sections.gif new file mode 100644 index 0000000..def4db5 Binary files /dev/null and b/scale-64/doc/track-sections.gif differ diff --git a/scale-64/parts/barriers/barrier-curve-1-enlarged.scad b/scale-64/parts/barriers/barrier-curve-1-enlarged.scad new file mode 100644 index 0000000..b4256c0 --- /dev/null +++ b/scale-64/parts/barriers/barrier-curve-1-enlarged.scad @@ -0,0 +1,67 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track parts: a set of barrier chunks for an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + innerCurveLength = getCurvedBarrierLength( + getCurveInnerBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getCurveInnerBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + outerCurveLength = getCurvedBarrierLength( + getEnlargedCurveOuterBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + straightLength = getStraightBarrierLength(barrierLength, barrierWidth, barrierHeight); + + innerCurveChunks = getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio) * printQuantity; + outerCurveChunks = getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio) * printQuantity; + straightChunks = getEnlargedCurveSideBarrierChunks(barrierChunks, ratio) * 2 * printQuantity; + + innerCurveInterval = getGridWidth(innerCurveLength, barrierWidth, quantity=innerCurveChunks, line=printQuantity); + outerCurveInterval = getGridWidth(outerCurveLength, barrierWidth, quantity=outerCurveChunks, line=printQuantity); + straightInterval = getGridWidth(straightLength, barrierWidth, quantity=straightChunks, line=printQuantity); + + // Draws the ready to print model + translateY((straightInterval + outerCurveInterval) / 2) { + straightBarrierSet(quantity=straightChunks, line=printQuantity); + } + enlargedCurveBarrierSet(ratio=ratio, quantity=outerCurveChunks, line=printQuantity); + translateY(-(innerCurveInterval + outerCurveInterval) / 2) { + innerCurveBarrierSet(ratio=ratio, quantity=innerCurveChunks, line=printQuantity); + } + +} diff --git a/scale-64/parts/barriers/barrier-curve-1.scad b/scale-64/parts/barriers/barrier-curve-1.scad new file mode 100644 index 0000000..249c5b6 --- /dev/null +++ b/scale-64/parts/barriers/barrier-curve-1.scad @@ -0,0 +1,61 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track parts: a set of barrier chunks for a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + innerCurveLength = getCurvedBarrierLength( + getCurveInnerBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getCurveInnerBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + outerCurveLength = getCurvedBarrierLength( + getCurveOuterBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getCurveOuterBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + + innerCurveChunks = getCurveInnerBarrierChunks(barrierChunks, ratio) * printQuantity; + outerCurveChunks = getCurveOuterBarrierChunks(barrierChunks, ratio) * printQuantity; + + innerCurveInterval = getGridWidth(innerCurveLength, barrierWidth, quantity=innerCurveChunks, line=printQuantity); + outerCurveInterval = getGridWidth(outerCurveLength, barrierWidth, quantity=outerCurveChunks, line=printQuantity); + + // Draws the ready to print model + outerCurveBarrierSet(ratio=ratio, quantity=outerCurveChunks, line=printQuantity); + translateY(-(innerCurveInterval + outerCurveInterval) / 2) { + innerCurveBarrierSet(ratio=ratio, quantity=innerCurveChunks, line=printQuantity); + } + +} diff --git a/scale-64/parts/barriers/barrier-curve-2.scad b/scale-64/parts/barriers/barrier-curve-2.scad new file mode 100644 index 0000000..6b033bc --- /dev/null +++ b/scale-64/parts/barriers/barrier-curve-2.scad @@ -0,0 +1,61 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track parts: a set of barrier chunks for a large curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 2; + innerCurveLength = getCurvedBarrierLength( + getCurveInnerBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getCurveInnerBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + outerCurveLength = getCurvedBarrierLength( + getCurveOuterBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio), + getCurveAngle(ratio) / getCurveOuterBarrierChunks(barrierChunks, ratio), + barrierWidth, barrierHeight + ); + + innerCurveChunks = getCurveInnerBarrierChunks(barrierChunks, ratio) * printQuantity; + outerCurveChunks = getCurveOuterBarrierChunks(barrierChunks, ratio) * printQuantity; + + innerCurveInterval = getGridWidth(innerCurveLength, barrierWidth, quantity=innerCurveChunks, line=printQuantity); + outerCurveInterval = getGridWidth(outerCurveLength, barrierWidth, quantity=outerCurveChunks, line=printQuantity); + + // Draws the ready to print model + outerCurveBarrierSet(ratio=ratio, quantity=outerCurveChunks, line=printQuantity); + translateY(-(innerCurveInterval + outerCurveInterval) / 2) { + innerCurveBarrierSet(ratio=ratio, quantity=innerCurveChunks, line=printQuantity); + } + +} diff --git a/scale-64/parts/barriers/barrier-pegs.scad b/scale-64/parts/barriers/barrier-pegs.scad new file mode 100644 index 0000000..f1580de --- /dev/null +++ b/scale-64/parts/barriers/barrier-pegs.scad @@ -0,0 +1,43 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a set of pegs to fasten the barrier chunks to the track sections. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + pegsQuantity = getStraightBarrierChunks(barrierChunks, ratio) * 2; + + // Draws the ready to print model + barrierPegSet(quantity=printQuantity * pegsQuantity); + +} diff --git a/scale-64/parts/barriers/barrier-straight.scad b/scale-64/parts/barriers/barrier-straight.scad new file mode 100644 index 0000000..97171c5 --- /dev/null +++ b/scale-64/parts/barriers/barrier-straight.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track parts: a set of barrier chunks for a straight section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + straightBarrierSet(quantity=getStraightBarrierChunks(barrierChunks, 1) * 2 * printQuantity, line=printQuantity); + +} diff --git a/scale-64/parts/elements/barrier-curve-1-enlarged.scad b/scale-64/parts/elements/barrier-curve-1-enlarged.scad new file mode 100644 index 0000000..d4f5744 --- /dev/null +++ b/scale-64/parts/elements/barrier-curve-1-enlarged.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for the outer curve of an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + enlargedCurveBarrierSet(ratio=1, quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/barrier-curve-1-inner.scad b/scale-64/parts/elements/barrier-curve-1-inner.scad new file mode 100644 index 0000000..f2dee50 --- /dev/null +++ b/scale-64/parts/elements/barrier-curve-1-inner.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for the inner curve of a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + innerCurveBarrierSet(ratio=1, quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/barrier-curve-1-outer.scad b/scale-64/parts/elements/barrier-curve-1-outer.scad new file mode 100644 index 0000000..3bb3e22 --- /dev/null +++ b/scale-64/parts/elements/barrier-curve-1-outer.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for the outer curve of a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + outerCurveBarrierSet(ratio=1, quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/barrier-curve-2-inner.scad b/scale-64/parts/elements/barrier-curve-2-inner.scad new file mode 100644 index 0000000..d19d45d --- /dev/null +++ b/scale-64/parts/elements/barrier-curve-2-inner.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for the inner curve of an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + innerCurveBarrierSet(ratio=2, quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/barrier-curve-2-outer.scad b/scale-64/parts/elements/barrier-curve-2-outer.scad new file mode 100644 index 0000000..37974b7 --- /dev/null +++ b/scale-64/parts/elements/barrier-curve-2-outer.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for the outer curve of an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + outerCurveBarrierSet(ratio=2, quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/barrier-peg.scad b/scale-64/parts/elements/barrier-peg.scad new file mode 100644 index 0000000..a0df2a6 --- /dev/null +++ b/scale-64/parts/elements/barrier-peg.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a peg to fasten the barrier chunks to the track sections. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + barrierPegSet(quantity=1); + +} diff --git a/scale-64/parts/elements/barrier-straight.scad b/scale-64/parts/elements/barrier-straight.scad new file mode 100644 index 0000000..62b957d --- /dev/null +++ b/scale-64/parts/elements/barrier-straight.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a barrier chunk for a straight section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + straightBarrierSet(quantity=1, line=1); + +} diff --git a/scale-64/parts/elements/ground-curve-1-enlarged.scad b/scale-64/parts/elements/ground-curve-1-enlarged.scad new file mode 100644 index 0000000..2b2447b --- /dev/null +++ b/scale-64/parts/elements/ground-curve-1-enlarged.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a tight curved track section with extra space. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + enlargedCurveTrackSectionGround(ratio=1); + +} diff --git a/scale-64/parts/elements/ground-curve-1-half.scad b/scale-64/parts/elements/ground-curve-1-half.scad new file mode 100644 index 0000000..e425082 --- /dev/null +++ b/scale-64/parts/elements/ground-curve-1-half.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a tight curved track section with a half size. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + curvedTrackSectionGround(ratio=.5); + +} diff --git a/scale-64/parts/elements/ground-curve-1.scad b/scale-64/parts/elements/ground-curve-1.scad new file mode 100644 index 0000000..542da34 --- /dev/null +++ b/scale-64/parts/elements/ground-curve-1.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + curvedTrackSectionGround(ratio=1); + +} diff --git a/scale-64/parts/elements/ground-curve-2.scad b/scale-64/parts/elements/ground-curve-2.scad new file mode 100644 index 0000000..1c18b85 --- /dev/null +++ b/scale-64/parts/elements/ground-curve-2.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + curvedTrackSectionGround(ratio=2); + +} diff --git a/scale-64/parts/elements/ground-starting.scad b/scale-64/parts/elements/ground-starting.scad new file mode 100644 index 0000000..aa7fc32 --- /dev/null +++ b/scale-64/parts/elements/ground-starting.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a starting track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + startingTrackSectionGround(); + +} diff --git a/scale-64/parts/elements/ground-straight-half.scad b/scale-64/parts/elements/ground-straight-half.scad new file mode 100644 index 0000000..d8d0f2d --- /dev/null +++ b/scale-64/parts/elements/ground-straight-half.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a straight track section with a half size. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + straightTrackSectionGround(ratio=.5); + +} diff --git a/scale-64/parts/elements/ground-straight-quarter.scad b/scale-64/parts/elements/ground-straight-quarter.scad new file mode 100644 index 0000000..85b5de6 --- /dev/null +++ b/scale-64/parts/elements/ground-straight-quarter.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a straight track section with a quarter size. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + straightTrackSectionGround(ratio=.25); + +} diff --git a/scale-64/parts/elements/ground-straight.scad b/scale-64/parts/elements/ground-straight.scad new file mode 100644 index 0000000..97f5161 --- /dev/null +++ b/scale-64/parts/elements/ground-straight.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a straight track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + straightTrackSectionGround(ratio=1); + +} diff --git a/scale-64/parts/ground/ground-curve-1-enlarged.scad b/scale-64/parts/ground/ground-curve-1-enlarged.scad new file mode 100644 index 0000000..9df76b7 --- /dev/null +++ b/scale-64/parts/ground/ground-curve-1-enlarged.scad @@ -0,0 +1,50 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a tight curved track section with extra space. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + sideBarrierChunks = getEnlargedCurveSideBarrierChunks(barrierChunks, ratio); + innerBarrierChunks = getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio); + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio); + pegsQuantity = sideBarrierChunks * 2 + innerBarrierChunks + outerBarrierChunks; + + // Draws the ready to print model + enlargedCurveTrackSectionGround(ratio=ratio); + translateY(-getPrintInterval(outerRadius / 2)) { + barrierPegSet(quantity=pegsQuantity, line=pegsQuantity); + } + +} diff --git a/scale-64/parts/ground/ground-curve-1.scad b/scale-64/parts/ground/ground-curve-1.scad new file mode 100644 index 0000000..7a36ad1 --- /dev/null +++ b/scale-64/parts/ground/ground-curve-1.scad @@ -0,0 +1,49 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + innerBarrierChunks = getCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getCurveOuterBarrierChunks(barrierChunks, ratio); + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio); + pegsQuantity = innerBarrierChunks + outerBarrierChunks; + + // Draws the ready to print model + curvedTrackSectionGround(ratio=ratio); + translateY(-getPrintInterval(sin(getCurveAngle(ratio)) * outerRadius / 2)) { + barrierPegSet(quantity=pegsQuantity, line=pegsQuantity); + } + +} diff --git a/scale-64/parts/ground/ground-curve-2.scad b/scale-64/parts/ground/ground-curve-2.scad new file mode 100644 index 0000000..d678b3f --- /dev/null +++ b/scale-64/parts/ground/ground-curve-2.scad @@ -0,0 +1,49 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 2; + innerBarrierChunks = getCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getCurveOuterBarrierChunks(barrierChunks, ratio); + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio); + pegsQuantity = innerBarrierChunks + outerBarrierChunks; + + // Draws the ready to print model + curvedTrackSectionGround(ratio=ratio); + translateY(-getPrintInterval(sin(getCurveAngle(ratio)) * outerRadius / 2)) { + barrierPegSet(quantity=pegsQuantity, line=pegsQuantity); + } + +} diff --git a/scale-64/parts/ground/ground-starting.scad b/scale-64/parts/ground/ground-starting.scad new file mode 100644 index 0000000..1d53521 --- /dev/null +++ b/scale-64/parts/ground/ground-starting.scad @@ -0,0 +1,45 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a starting track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + pegsQuantity = getStraightBarrierChunks(barrierChunks, 1) * 2; + + // Draws the ready to print model + startingTrackSectionGround(); + translateY(-getPrintInterval(trackSectionWidth / 2)) { + barrierPegSet(quantity=pegsQuantity, line=pegsQuantity); + } + +} diff --git a/scale-64/parts/ground/ground-straight.scad b/scale-64/parts/ground/ground-straight.scad new file mode 100644 index 0000000..d077fe3 --- /dev/null +++ b/scale-64/parts/ground/ground-straight.scad @@ -0,0 +1,46 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a ground tile for a straight track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + pegsQuantity = getStraightBarrierChunks(barrierChunks, ratio) * 2; + + // Draws the ready to print model + straightTrackSectionGround(ratio=ratio); + translateY(-getPrintInterval(trackSectionWidth / 2)) { + barrierPegSet(quantity=pegsQuantity, line=pegsQuantity); + } + +} diff --git a/scale-64/parts/tiles/tile-curve-1-enlarged.scad b/scale-64/parts/tiles/tile-curve-1-enlarged.scad new file mode 100644 index 0000000..dfb40da --- /dev/null +++ b/scale-64/parts/tiles/tile-curve-1-enlarged.scad @@ -0,0 +1,42 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a full tile for a tight curved track section with extra space. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + + // Draws the ready to print model + enlargedCurveTrackTile(ratio=ratio); + +} diff --git a/scale-64/parts/tiles/tile-curve-1.scad b/scale-64/parts/tiles/tile-curve-1.scad new file mode 100644 index 0000000..58e4ec9 --- /dev/null +++ b/scale-64/parts/tiles/tile-curve-1.scad @@ -0,0 +1,42 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a full tile for a tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + + // Draws the ready to print model + curvedTrackTile(ratio=ratio); + +} diff --git a/scale-64/parts/tiles/tile-curve-2.scad b/scale-64/parts/tiles/tile-curve-2.scad new file mode 100644 index 0000000..20f999f --- /dev/null +++ b/scale-64/parts/tiles/tile-curve-2.scad @@ -0,0 +1,42 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a full tile for an enlarged curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 2; + + // Draws the ready to print model + curvedTrackTile(ratio=ratio); + +} diff --git a/scale-64/parts/tiles/tile-starting.scad b/scale-64/parts/tiles/tile-starting.scad new file mode 100644 index 0000000..dd62c45 --- /dev/null +++ b/scale-64/parts/tiles/tile-starting.scad @@ -0,0 +1,40 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a full tile for a starting track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + startingTrackTile(); + +} diff --git a/scale-64/parts/tiles/tile-straight.scad b/scale-64/parts/tiles/tile-straight.scad new file mode 100644 index 0000000..c293abe --- /dev/null +++ b/scale-64/parts/tiles/tile-straight.scad @@ -0,0 +1,42 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track part: a full tile for a straight track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + + // Draws the ready to print model + straightTrackTile(ratio=ratio); + +} diff --git a/scale-64/parts/tools/barrier-peg-extractor.scad b/scale-64/parts/tools/barrier-peg-extractor.scad new file mode 100644 index 0000000..41096c1 --- /dev/null +++ b/scale-64/parts/tools/barrier-peg-extractor.scad @@ -0,0 +1,88 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track tool: a barrier peg extractor. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +/** + * Draws the shape of the barrier peg extractor. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fastener. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegExtractor(width, height, diameter, thickness, distance=0) { + // Prepare the parameters for the polygon + pegDiameter = getBarrierPegDiameter(width, height); + + jawLength = pegDiameter * 5; + jawWidth = pegDiameter * 3; + radius = pegDiameter / 2; + handleHeight = thickness * 6; + handleWidth = jawWidth + (handleHeight + radius + distance) * 2; + handleLength = jawLength * 2; + + remainingLength = jawLength - radius + ALIGN; + remainingWidth = jawWidth; + brushHeight = handleHeight + ALIGN2; + + jawPoints = outline(path([ + ["P", radius, radius], + ["C", radius, 90, 270], + ["L", remainingLength, radius - remainingWidth / 2], + ["V", remainingWidth], + ]), distance); + + difference() { + cushion([handleLength, handleWidth, handleHeight], r=radius, center=true); + translateZ(-brushHeight / 2) { + simplePolyhedron( + bottom = jawPoints, + top = outline(jawPoints, brushHeight), + distance = zAxis3D(brushHeight) + ); + } + } +} + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + barrierPegExtractor( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + thickness = trackGroundThickness, + distance = printTolerance + ); + +} diff --git a/scale-64/parts/tools/barrier-peg-remover.scad b/scale-64/parts/tools/barrier-peg-remover.scad new file mode 100644 index 0000000..7a316aa --- /dev/null +++ b/scale-64/parts/tools/barrier-peg-remover.scad @@ -0,0 +1,104 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Ready to print track tool: a barrier peg remover. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +/** + * Draws the profile of the barrier peg remover. + * + * To get the final shape, rotate_extrude(angle=360, convexity=10) must be applied. + * + * @param Number diameter - The diameter of the fastener. + * @param Number headDiameter - The diameter of the fastener head. + * @param Number headHeight - The height of the fastener head. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegRemoverProfile(diameter, headDiameter, headHeight, distance=0) { + // Uncomment to debug: + // %rectangle([width, height]); + + // Prepare the parameters for the polygon + headRadius = max(headDiameter, diameter) / 2 + distance; + holeRadius = diameter / 2 + distance; + radius = headRadius * 2; + pocket = diameter / 4; + height = headRadius * 4; + + remainingRadius = radius - holeRadius; + remainingTopRadius = radius - headRadius; + remainingHeadRadius = headRadius - holeRadius; + remainingHeight = height - headHeight - pocket * 3; + + // Draw the profile + polygon(path([ + ["P", holeRadius, -height / 2], + ["H", remainingRadius], + ["V", pocket], + ["L", -pocket, pocket], + ["V", remainingHeight], + ["L", pocket, pocket], + ["V", headHeight], + ["H", -remainingTopRadius], + ["V", -headHeight], + ["H", -remainingHeadRadius], + ]), convexity = 10); +} + +/** + * Draws the shape of the barrier peg remover. + * @param Number diameter - The diameter of the fastener. + * @param Number headDiameter - The diameter of the fastener head. + * @param Number headHeight - The height of the fastener head. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegRemover(diameter, headDiameter, headHeight, distance=0) { + rotate_extrude(angle=DEGREES, convexity=10) { + barrierPegRemoverProfile( + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = distance + ); + } +} + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Draws the ready to print model + barrierPegRemover( + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + distance = 0 + ); + +} diff --git a/scale-64/pictures.sh b/scale-64/pictures.sh new file mode 100755 index 0000000..785a7e4 --- /dev/null +++ b/scale-64/pictures.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A race track system for 1/64 to 1/76 scale RC cars. +# +# Generates the pictures for the documentation of the project. +# +# @author jsconan +# + +# script config +scriptpath="$(dirname $0)" +project="$(pwd)" +srcpath="${project}/pictures" +dstpath="${project}/dist/pictures" +tmppath="${project}/tmp" +configpath="${project}/config" + +# include libs +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# options +mask="*.${scadext}" +imgext="png" +vidext="gif" +framerate=15 +imgstep=8 +imgwidth=640 +imgheight=480 +theme="Starnight" + +# prepate the output folder +createpath "${dstpath}" "output" +createpath "${tmppath}" "tmp" + +# make sure the config exists +distfile "${configpath}/config.scad" + +# list the pictures to render +printmessage "Processing rendering from ${C_SEL}${srcpath}${C_RST}..." +foldermustcontain "${srcpath}" "${mask}" "render" +list=($(find "${srcpath}" -maxdepth 1 -name "${mask}")) + +for filename in "${list[@]}"; do + name=$(basename "${filename%.*}" ) + showsteps="${tmppath}/${name}.${echoext}" + picture= + + # get the number of steps + scadecho "${filename}" "${tmppath}" "" "" showSteps=1 > /dev/null + step=$(sed 's/[^0-9]*//g' "${showsteps}") + + if [ "$step" != "" ]; then + picture="${dstpath}/${name}.${vidext}" + + # compute the number of images to render + length=$((${step} * ${imgstep})) + + # generate each image of the amimation + printmessage "${C_RST}Will render ${C_SEL}${length}${C_RST} frames from ${C_SEL}${filename}${C_RST}" + scadpreview "${filename}" "${tmppath}" "${imgext}" "" "" --quiet --animate ${length} --projection p --colorscheme "${theme}" --imgsize ${imgwidth},${imgheight} + + # produce the video + printmessage "${C_RST}Will render a video of ${C_SEL}${length}${C_RST} frames with a rate of ${C_SEL}${framerate}${C_RST} images per seconds" + ffmpeg -framerate ${framerate} -i "${tmppath}/${name}%5d.${imgext}" "${picture}" -y + else + picture="${dstpath}/${name}.${imgext}" + + # generate a single image + printmessage "${C_RST}Will render a picture from ${C_SEL}${filename}${C_RST}" + scadpreview "${filename}" "${dstpath}" "${imgext}" "" "" --quiet --projection p --colorscheme "${theme}" --imgsize ${imgwidth},${imgheight} + fi + + # clean up the place + rm "${tmppath}/${name}"*."${imgext}" 2> /dev/null + rm "${showsteps}" 2> /dev/null + + if [ -f "${picture}" ]; then + printmessage "${C_RST}Picture rendered at ${C_SEL}${picture}${C_RST}" + fi +done diff --git a/scale-64/pictures/enlarged-curve-section.scad b/scale-64/pictures/enlarged-curve-section.scad new file mode 100644 index 0000000..3e2b37d --- /dev/null +++ b/scale-64/pictures/enlarged-curve-section.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * An assembled enlarged curve track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + enlargedCurveSection(1); + +} diff --git a/scale-64/pictures/enlarged-curve-tile.scad b/scale-64/pictures/enlarged-curve-tile.scad new file mode 100644 index 0000000..39aff50 --- /dev/null +++ b/scale-64/pictures/enlarged-curve-tile.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * A complete enlarged curve track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + enlargedCurveTrackTile(1); + +} diff --git a/scale-64/pictures/full-tiles.scad b/scale-64/pictures/full-tiles.scad new file mode 100644 index 0000000..174871e --- /dev/null +++ b/scale-64/pictures/full-tiles.scad @@ -0,0 +1,103 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Animated examples for each type of full tile. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Prepare the list of animations +list = buildAnimationList([ + getAnimationThresholds("starting", 1, 1), + getAnimationThresholds("straight", 1, 1), + getAnimationThresholds("enlarged", 1, 1), + getAnimationThresholds("curve", 1, 1), + getAnimationThresholds("curve", 2, 1), +]); +steps = getAnimationSteps(list); +count = len(list); + +// Show the number of steps for all animations +if (showSteps) { + echo(steps); +} + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Process the animations + for (i = [0 : count - 1]) { + type = list[i][0]; + ratio = list[i][1]; + start = list[i][2]; + present = list[i][3]; + end = list[i][4]; + + startThreshold = interpolationThreshold(step=start, steps=steps); + endThreshold = interpolationThreshold(step=present, steps=steps); + + presentSteps(from=start, to=end, steps=steps) { + if (type == "starting") { + animatedStraightTile( + start = startThreshold, + end = endThreshold, + ratio = ratio, + starting = true + ); + } + if (type == "straight") { + animatedStraightTile( + start = startThreshold, + end = endThreshold, + ratio = ratio, + starting = false + ); + } + if (type == "enlarged") { + animatedEnlargedCurveTile( + start = startThreshold, + end = endThreshold, + ratio = ratio + ); + } + if (type == "curve") { + animatedCurvedTile( + start = startThreshold, + end = endThreshold, + ratio = ratio + ); + } + } + } + +} diff --git a/scale-64/pictures/large-curved-section.scad b/scale-64/pictures/large-curved-section.scad new file mode 100644 index 0000000..23f14bd --- /dev/null +++ b/scale-64/pictures/large-curved-section.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * An assembled large curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + curvedSection(2); + +} diff --git a/scale-64/pictures/large-curved-tile.scad b/scale-64/pictures/large-curved-tile.scad new file mode 100644 index 0000000..b3246b9 --- /dev/null +++ b/scale-64/pictures/large-curved-tile.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * A complete large curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + curvedTrackTile(2); + +} diff --git a/scale-64/pictures/starting-section.scad b/scale-64/pictures/starting-section.scad new file mode 100644 index 0000000..53df93b --- /dev/null +++ b/scale-64/pictures/starting-section.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * An assembled starting track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + straightSection(1, starting=true); + +} diff --git a/scale-64/pictures/starting-tile.scad b/scale-64/pictures/starting-tile.scad new file mode 100644 index 0000000..f0274f9 --- /dev/null +++ b/scale-64/pictures/starting-tile.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * A complete starting track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + startingTrackTile(); + +} diff --git a/scale-64/pictures/straight-section.scad b/scale-64/pictures/straight-section.scad new file mode 100644 index 0000000..0079c21 --- /dev/null +++ b/scale-64/pictures/straight-section.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * An assembled straight track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + straightSection(1); + +} diff --git a/scale-64/pictures/straight-tile.scad b/scale-64/pictures/straight-tile.scad new file mode 100644 index 0000000..652530c --- /dev/null +++ b/scale-64/pictures/straight-tile.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * A complete straight track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + straightTrackTile(1); + +} diff --git a/scale-64/pictures/tight-curved-section.scad b/scale-64/pictures/tight-curved-section.scad new file mode 100644 index 0000000..8c68c26 --- /dev/null +++ b/scale-64/pictures/tight-curved-section.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * An assembled tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + curvedSection(1); + +} diff --git a/scale-64/pictures/tight-curved-tile.scad b/scale-64/pictures/tight-curved-tile.scad new file mode 100644 index 0000000..7f7d263 --- /dev/null +++ b/scale-64/pictures/tight-curved-tile.scad @@ -0,0 +1,47 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * A complete tight curved track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + curvedTrackTile(1); + +} diff --git a/scale-64/pictures/track-sections.scad b/scale-64/pictures/track-sections.scad new file mode 100644 index 0000000..7d0395d --- /dev/null +++ b/scale-64/pictures/track-sections.scad @@ -0,0 +1,106 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Animated examples of assembly for each type of track section. + * + * @author jsconan + */ + +// Import the project's setup. +include <../config/setup.scad> + +// Override the default config +printGroundUpsideDown = false; + +// Setup the viewport +$vpr = [55, 0, 25]; +$vpt = [0, 0, 0]; +$vpd = 500; + +// Prepare the list of animations +list = buildAnimationList([ + getAnimationThresholds("starting", 1, getStraightSectionSteps(1)), + getAnimationThresholds("straight", 1, getStraightSectionSteps(1)), + getAnimationThresholds("enlarged", 1, getEnlargedCurveSectionSteps(1)), + getAnimationThresholds("curve", 1, getCurveSectionSteps(1)), + getAnimationThresholds("curve", 2, getCurveSectionSteps(2)), +]); +steps = getAnimationSteps(list); +count = len(list); + +// Show the number of steps for all animations +if (showSteps) { + echo(steps); +} + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + // Process the animations + for (i = [0 : count - 1]) { + type = list[i][0]; + ratio = list[i][1]; + start = list[i][2]; + present = list[i][3]; + end = list[i][4]; + + startThreshold = interpolationThreshold(step=start, steps=steps); + endThreshold = interpolationThreshold(step=present, steps=steps); + + presentSteps(from=start, to=end, steps=steps) { + if (type == "starting") { + animatedStraightSection( + start = startThreshold, + end = endThreshold, + ratio = ratio, + starting = true + ); + } + if (type == "straight") { + animatedStraightSection( + start = startThreshold, + end = endThreshold, + ratio = ratio, + starting = false + ); + } + if (type == "enlarged") { + animatedEnlargedCurveSection( + start = startThreshold, + end = endThreshold, + ratio = ratio + ); + } + if (type == "curve") { + animatedCurvedSection( + start = startThreshold, + end = endThreshold, + ratio = ratio + ); + } + } + } + +} diff --git a/scale-64/post-render-dist.sh b/scale-64/post-render-dist.sh new file mode 100755 index 0000000..17cb18a --- /dev/null +++ b/scale-64/post-render-dist.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A sample of post-processing script that can be called once the models have been rendered. +# +# To use it as a skeleton for your own script, please first run the following commands: +# cp post-render-dist.sh post-render.sh +# chmod +x post-render.sh +# +# It will copy the sample to the file `post-render.sh` and make sure it is executable. +# Then, you can modify the copy and add your own commands. +# +# @author jsconan +# + +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +stlpath="${project}/dist/stl/" +zippath="stl-scale-64.zip" +logpath="${project}/dist/zip.log" + +# Post process the rendered files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-render script: zip files" +dummy=$( + cd "${stlpath}" + rm *.zip > /dev/null + zip -r "${zippath}" * +) +printmessage "${C_MSG}===========================================" diff --git a/scale-64/post-slice-dist.sh b/scale-64/post-slice-dist.sh new file mode 100755 index 0000000..0b0f864 --- /dev/null +++ b/scale-64/post-slice-dist.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A sample of post-processing script that can be called once the models have been sliced. +# +# To use it as a skeleton for your own script, please first run the following commands: +# cp post-slice-dist.sh post-slice.sh +# chmod +x post-slice.sh +# +# It will copy the sample to the file `post-slice.sh` and make sure it is executable. +# Then, you can modify the copy and add your own commands. +# +# @author jsconan +# + +# Bootstrap the script +scriptpath=$(dirname $0) +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Script config +project=$(pwd) +gcodepath="${project}/dist/gcode/" +sdcardpath="/PATH/TO/SD/CARD" # <-- CHANGE THIS! +logpath="${project}/dist/gcode-sync.log" + +# Post process the sliced files +printmessage "${C_MSG}===========================================" +printmessage "${C_MSG}Post-slice script: copy Gcode to the SDcard" +date > ${logpath} +createpath "${sdcardpath}" +rsync -ahvt --no-links --delete --partial --force --modify-window=1 --exclude=.DS_Store --log-file=${logpath} "${gcodepath}" "${sdcardpath}" +printmessage "${C_MSG}===========================================" diff --git a/scale-64/render.sh b/scale-64/render.sh new file mode 100755 index 0000000..cdce439 --- /dev/null +++ b/scale-64/render.sh @@ -0,0 +1,306 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A race track system for 1/64 to 1/76 scale RC cars. +# +# Generates the STL files for the project. +# +# @author jsconan +# + +# application params +trackLaneWidth= +trackGroundThickness= +barrierWidth= +barrierHeight= +barrierChunks= +fastenerDiameter= +fastenerHeadDiameter= +fastenerHeadHeight= +printGroundUpsideDown= +printQuantity= + +# script config +scriptpath="$(dirname $0)" +project="$(pwd)" +srcpath="${project}" +dstpath="${project}/dist/stl" +slcpath="${project}/dist/gcode" +configpath="${srcpath}/config" +partpath="${srcpath}/parts" +format= +parallel= +cleanUp= +slice= +renderBarriers= +renderElements= +renderGround= +renderTiles= +renderTools= +renderAll=1 + +# include libs +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# Builds the list of config parameters. +paramlist() { + local params=( + "$(varif "trackLaneWidth" ${trackLaneWidth})" + "$(varif "trackGroundThickness" ${trackGroundThickness})" + "$(varif "barrierWidth" ${barrierWidth})" + "$(varif "barrierHeight" ${barrierHeight})" + "$(varif "barrierChunks" ${barrierChunks})" + "$(varif "fastenerDiameter" ${fastenerDiameter})" + "$(varif "fastenerHeadDiameter" ${fastenerHeadDiameter})" + "$(varif "fastenerHeadHeight" ${fastenerHeadHeight})" + "$(varif "printGroundUpsideDown" ${printGroundUpsideDown})" + "$(varif "printQuantity" ${printQuantity})" + ) + echo "${params[@]}" +} + +# Renders the files from a path. +# +# @param sourcepath - The path of the folder containing the SCAD files to render. +# @param destpath - The path to the output folder. +# @param prefix - Optional prefix added to the output file name +# @param suffix - Optional suffix added to the output file name +renderpath() { + scadrenderall "$1" "$2" "$3" "$4" --quiet $(paramlist) +} + +# Renders the files from a path. +# +# @param sourcepath - The path of the folder containing the SCAD files to render. +# @param destpath - The path to the output folder. +renderpathall() { + if [ "${renderBarriers}" != "" ] || \ + [ "${renderElements}" != "" ] || \ + [ "${renderGround}" != "" ] || \ + [ "${renderTiles}" != "" ] || \ + [ "${renderTools}" != "" ] || \ + [ "${renderAll}" != "" ]; then + printmessage "${C_MSG}Rendering track elements" + else + printmessage "${C_MSG}Nothing will be rendered" + fi + if [ "${renderBarriers}" == "1" ] || [ "${renderAll}" == "1" ]; then + printmessage "${C_MSG}- sets of barriers" + renderpath "$1/barriers" "$2/barriers" + fi + if [ "${renderElements}" == "1" ] || [ "${renderAll}" == "1" ]; then + printmessage "${C_MSG}- all elements" + renderpath "$1/elements" "$2/elements" + fi + if [ "${renderGround}" == "1" ] || [ "${renderAll}" == "1" ]; then + printmessage "${C_MSG}- ground tiles" + renderpath "$1/ground" "$2/ground" + fi + if [ "${renderTiles}" == "1" ] || [ "${renderAll}" == "1" ]; then + printmessage "${C_MSG}- full tiles" + renderpath "$1/tiles" "$2/tiles" + fi + if [ "${renderTools}" == "1" ] || [ "${renderAll}" == "1" ]; then + printmessage "${C_MSG}- tools" + renderpath "$1/tools" "$2/tools" + fi +} + +# Display the render config +showconfig() { + local input="${configpath}/setup.scad" + local output="${dstpath}/setup.echo" + local config="${dstpath}/config.txt" + createpath "${dstpath}" "output" + printmessage "${C_MSG}The track elements would be generated with respect to the following config:" + scadecho "${input}" "${dstpath}" "" "" showConfig=1 $(paramlist) > /dev/null + sed '1d; $d' "${output}" > "${config}" + rm "${output}" > /dev/null + cat "${config}" +} + +# load parameters +while (( "$#" )); do + case $1 in + "a"|"all") + renderAll=1 + ;; + "c"|"config") + renderAll= + ;; + "b"|"barriers") + renderBarriers=1 + renderAll= + ;; + "e"|"elements") + renderElements=1 + renderAll= + ;; + "g"|"ground") + renderGround=1 + renderAll= + ;; + "f"|"tiles") + renderTiles=1 + renderAll= + ;; + "t"|"tools") + renderTools=1 + renderAll= + ;; + "-t"|"--track") + trackLaneWidth=$2 + shift + ;; + "-w"|"--width") + barrierWidth=$2 + shift + ;; + "-b"|"--height") + barrierHeight=$2 + shift + ;; + "-k"|"--chunks") + barrierChunks=$2 + shift + ;; + "-g"|"--ground") + trackGroundThickness=$2 + shift + ;; + "-d"|"--diameter") + fastenerDiameter=$2 + shift + ;; + "-hd"|"--headDiameter") + fastenerHeadDiameter=$2 + shift + ;; + "-hh"|"--headHeight") + fastenerHeadHeight=$2 + shift + ;; + "-u"|"--upsideDown") + printGroundUpsideDown=$2 + shift + ;; + "-q"|"--quantity") + printQuantity=$2 + shift + ;; + "-f"|"--format") + format=$2 + shift + ;; + "-p"|"--parallel") + parallel=$2 + shift + ;; + "-s"|"--slice") + slice=1 + ;; + "-c"|"--clean") + cleanUp=1 + ;; + "-h"|"--help") + echo -e "${C_INF}Renders OpenSCAD files${C_RST}" + echo -e " ${C_INF}Usage:${C_RST}" + echo -e "${C_CTX}\t$0 [command] [-h|--help] [-o|--option value] files${C_RST}" + echo + echo -e "${C_MSG} a, all ${C_RST}Render all elements (default)" + echo -e "${C_MSG} b, barriers ${C_RST}Render the sets of barriers" + echo -e "${C_MSG} e, elements ${C_RST}Render the elements" + echo -e "${C_MSG} g, ground ${C_RST}Render the ground tiles" + echo -e "${C_MSG} f, tiles ${C_RST}Render the full tiles" + echo -e "${C_MSG} t, tools ${C_RST}Render the tools" + echo -e "${C_MSG} c, config ${C_RST}Show the config values" + echo -e "${C_MSG} -h, --help ${C_RST}Show this help" + echo -e "${C_MSG} -t --track ${C_RST}Set the width of the track lane" + echo -e "${C_MSG} -w, --width ${C_RST}Set the width of the track barriers" + echo -e "${C_MSG} -b --height ${C_RST}Set the height of the track barriers" + echo -e "${C_MSG} -k --chunks ${C_RST}Set the number of barrier chunks per track section" + echo -e "${C_MSG} -g --ground ${C_RST}Set the thickness of the ground tiles" + echo -e "${C_MSG} -d --diameter ${C_RST}Set the diameter of the barrier fasteners" + echo -e "${C_MSG} -hd --headDiameter ${C_RST}Set the diameter of the barrier fasteners head" + echo -e "${C_MSG} -hh --headHeight ${C_RST}Set the height of the barrier fasteners head" + echo -e "${C_MSG} -u --upsideDown ${C_RST}Flip the ground tiles to print them upside down" + echo -e "${C_MSG} -q --quantity ${C_RST}Set the quantity of elements to print per set" + echo -e "${C_MSG} -f --format ${C_RST}Set the output format" + echo -e "${C_MSG} -p --parallel ${C_RST}Set the number of parallel processes" + echo -e "${C_MSG} -s --slice ${C_RST}Slice the rendered files using the default configuration" + echo -e "${C_MSG} -c --clean ${C_RST}Clean up the output folder before rendering" + echo + exit 0 + ;; + *) + ls $1 >/dev/null 2>&1 + if [ "$?" == "0" ]; then + srcpath=$1 + else + printerror "Unknown parameter ${1}" + fi + ;; + esac + shift +done + +# check OpenSCAD +scadcheck + +# defines the output format +scadformat "${format}" + +# defines the number of parallel processes +scadprocesses "${parallel}" + +# clean up the output +if [ "${cleanUp}" != "" ]; then + printmessage "${C_CTX}Cleaning up the output folder" + rm -rf "${dstpath}" + + if [ "${slice}" != "" ]; then + printmessage "${C_CTX}Cleaning up the slicer output folder" + rm -rf "${slcpath}" + fi +fi + +# make sure the config exists +distfile "${configpath}/config.scad" + +# show the config +showconfig + +# render the files +renderpathall "${partpath}" "${dstpath}" + +# run a post-render script +if [ -x "${scriptpath}/post-render.sh" ]; then + printmessage "${C_CTX}Calling the post-render script" + "${scriptpath}/post-render.sh" +fi + +# slice the rendered files +if [ "${slice}" != "" ]; then + printmessage "${C_CTX}Slicing the rendered files" + ./slice.sh +fi diff --git a/scale-64/shapes/animations/curved.scad b/scale-64/shapes/animations/curved.scad new file mode 100644 index 0000000..d86c355 --- /dev/null +++ b/scale-64/shapes/animations/curved.scad @@ -0,0 +1,302 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the animated curved models. + * + * @author jsconan + */ + +/** + * Animates the construction of a curved section. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + */ +module animatedCurvedSection(start, end, domain, ratio=1) { + sizeRatio = max(1, ratio); + elements = getCurveSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + i = elements[step][1]; + inner = elements[step][2]; + + barrierX = getCurveBarrierX(i, ratio, inner); + barrierY = getCurveBarrierY(i, ratio, inner); + rotation = getCurveRotation(i, ratio, inner); + + if (element == "peg") { + animateStep( + step = step, + translateTo = [barrierX, barrierY, 0], + steps=steps, start=start, end=end, domain=domain + ) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + animateStep( + step = step, + translateTo = [barrierX, barrierY, trackGroundThickness], + rotateTo = zAxis3D(rotation), + steps=steps, start=start, end=end, domain=domain + ) { + if (inner) { + innerCurveBarrierSet(sizeRatio); + } else { + outerCurveBarrierSet(sizeRatio); + } + } + } + } + if (element == "ground") { + animateStep(step=step, steps=steps, start=start, end=end, domain=domain) { + curvedTrackSectionGround(ratio=ratio); + } + } + } +} + +/** + * Animates the construction of an enlarged curve section. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + */ +module animatedEnlargedCurveSection(start, end, domain, ratio=1) { + sizeRatio = max(1, ratio); + elements = getEnlargedCurveSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + type = elements[step][1]; + i = elements[step][2]; + + if (type == "side") { + right = elements[step][3]; + barrierX = getEnlargedCurveSideBarrierX(i, ratio, right); + barrierY = getEnlargedCurveSideBarrierY(i, ratio, right); + rotation = getEnlargedCurveSideRotation(i, ratio, right); + + if (element == "peg") { + animateStep( + step = step, + translateTo = [barrierX, barrierY, 0], + steps=steps, start=start, end=end, domain=domain + ) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + animateStep( + step = step, + translateTo = [barrierX, barrierY, trackGroundThickness], + rotateTo = zAxis3D(rotation), + steps=steps, start=start, end=end, domain=domain + ) { + straightBarrierSet(); + } + } + } + } + if (type == "curve") { + inner = elements[step][3]; + barrierX = getEnlargedCurveBarrierX(i, ratio, inner); + barrierY = getEnlargedCurveBarrierY(i, ratio, inner); + rotation = getEnlargedCurveRotation(i, ratio, inner); + + if (element == "peg") { + animateStep( + step = step, + translateTo = [barrierX, barrierY, 0], + steps=steps, start=start, end=end, domain=domain + ) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + animateStep( + step = step, + translateTo = [barrierX, barrierY, trackGroundThickness], + rotateTo = zAxis3D(rotation), + steps=steps, start=start, end=end, domain=domain + ) { + if (inner) { + innerCurveBarrierSet(sizeRatio); + } else { + enlargedCurveBarrierSet(sizeRatio); + } + } + } + } + } + if (element == "ground") { + animateStep(step=step, steps=steps, start=start, end=end, domain=domain) { + enlargedCurveTrackSectionGround(ratio=ratio); + } + } + } +} + +/** + * Animates the construction of a curved full tile. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + */ +module animatedCurvedTile(start, end, domain, ratio=1) { + animateStep(step=0, steps=1, start=start, end=end, domain=domain) { + curvedTrackTile(ratio=ratio); + } +} + +/** + * Animates the construction of an enlarged curve full tile. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + */ +module animatedEnlargedCurveTile(start, end, domain, ratio=1) { + animateStep(step=0, steps=1, start=start, end=end, domain=domain) { + enlargedCurveTrackTile(ratio=ratio); + } +} + +/** + * An assembled curved section. + * @param Number [ratio] - The size factor. + */ +module curvedSection(ratio=1) { + sizeRatio = max(1, ratio); + elements = getCurveSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + i = elements[step][1]; + inner = elements[step][2]; + + barrierX = getCurveBarrierX(i, ratio, inner); + barrierY = getCurveBarrierY(i, ratio, inner); + rotation = getCurveRotation(i, ratio, inner); + + if (element == "peg") { + translate([barrierX, barrierY, 0]) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + translate([barrierX, barrierY, trackGroundThickness]) { + rotate(zAxis3D(rotation)) { + if (inner) { + innerCurveBarrierSet(sizeRatio); + } else { + outerCurveBarrierSet(sizeRatio); + } + } + } + } + } + if (element == "ground") { + curvedTrackSectionGround(ratio=ratio); + } + } +} + +/** + * An assembled enlarged curve section. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveSection(ratio=1) { + sizeRatio = max(1, ratio); + elements = getEnlargedCurveSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + type = elements[step][1]; + i = elements[step][2]; + + if (type == "side") { + right = elements[step][3]; + barrierX = getEnlargedCurveSideBarrierX(i, ratio, right); + barrierY = getEnlargedCurveSideBarrierY(i, ratio, right); + rotation = getEnlargedCurveSideRotation(i, ratio, right); + + if (element == "peg") { + translate([barrierX, barrierY, 0]) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + translate([barrierX, barrierY, trackGroundThickness]) { + rotate(zAxis3D(rotation)) { + straightBarrierSet(); + } + } + } + } + } + if (type == "curve") { + inner = elements[step][3]; + barrierX = getEnlargedCurveBarrierX(i, ratio, inner); + barrierY = getEnlargedCurveBarrierY(i, ratio, inner); + rotation = getEnlargedCurveRotation(i, ratio, inner); + + if (element == "peg") { + translate([barrierX, barrierY, 0]) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + translate([barrierX, barrierY, trackGroundThickness]) { + rotate(zAxis3D(rotation)) { + if (inner) { + innerCurveBarrierSet(sizeRatio); + } else { + enlargedCurveBarrierSet(sizeRatio); + } + } + } + } + } + } + if (element == "ground") { + enlargedCurveTrackSectionGround(ratio=ratio); + } + } +} diff --git a/scale-64/shapes/animations/helpers.scad b/scale-64/shapes/animations/helpers.scad new file mode 100644 index 0000000..51ee9a9 --- /dev/null +++ b/scale-64/shapes/animations/helpers.scad @@ -0,0 +1,350 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the helper functions for the animations. + * + * @author jsconan + */ + +/** + * Gets the list of steps needed to build a straight section. + * @param Number [ratio] - The size ratio. + * @returns Vector + */ +function getStraightSectionSteps(ratio=1) = + let( + chunks = getStraightBarrierChunks(barrierChunks, ratio) + ) + concat( + [ for (i = [0 : chunks - 1] ) ["peg", i, false] ], + [ for (i = [0 : chunks - 1] ) ["peg", i, true] ], + [ ["ground", 0, false] ], + [ for (i = [0 : chunks - 1] ) ["barrier", i, false] ], + [ for (i = [0 : chunks - 1] ) ["barrier", i, true] ] + ) +; + +/** + * Gets the list of steps needed to build a curve section. + * @param Number [ratio] - The size ratio. + * @returns Vector + */ +function getCurveSectionSteps(ratio=1) = + let( + inner = getCurveInnerBarrierChunks(barrierChunks, ratio), + outer = getCurveOuterBarrierChunks(barrierChunks, ratio) + ) + concat( + [ for (i = [0 : inner - 1] ) ["peg", i, true] ], + [ for (i = [0 : outer - 1] ) ["peg", i, false] ], + [ ["ground", 0, false] ], + [ for (i = [0 : inner - 1] ) ["barrier", i, true] ], + [ for (i = [0 : outer - 1] ) ["barrier", i, false] ] + ) +; + +/** + * Gets the list of steps needed to build an enlarged curve section. + * @param Number [ratio] - The size ratio. + * @returns Vector + */ +function getEnlargedCurveSectionSteps(ratio=1) = + let( + side = getEnlargedCurveSideBarrierChunks(barrierChunks, ratio), + inner = getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio), + outer = getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio) + ) + concat( + [ for (i = [0 : inner - 1] ) ["peg", "curve", i, true] ], + [ for (i = [0 : side - 1] ) ["peg", "side", i, true] ], + [ for (i = [0 : outer - 1] ) ["peg", "curve", i, false] ], + [ for (i = [0 : side - 1] ) ["peg", "side", i, false] ], + [ ["ground", "ground", 0, false] ], + [ for (i = [0 : inner - 1] ) ["barrier", "curve", i, true] ], + [ for (i = [0 : side - 1] ) ["barrier", "side", i, true] ], + [ for (i = [0 : outer - 1] ) ["barrier", "curve", i, false] ], + [ for (i = [0 : side - 1] ) ["barrier", "side", i, false] ] + ) +; + +/** + * Gets the thresholds for an animation. + * @param String type - The type of the animation. This represents the name of a model. + * @param Number ratio - The size ratio. + * @param Vector|Number steps - The number of steps, or the list of steps. + * @returns Vector + */ +function getAnimationThresholds(type, ratio, steps) = + let( + steps = is_list(steps) ? len(steps) : float(steps), + start = 0, + present = start + steps, + end = present + presentationSteps + slideSteps + ) + [type, ratio, start, present, end] +; + +/** + * Builds a list of animations, adjusting the stat and end thresholds to make sure they are coming in serie. + * @param Vector list - The list of animation thresholds to adjust. + * @returns Vector + */ +function buildAnimationList(list) = + let( + list = array(list), + count = len(list) + ) + [ + for (i = [0 : count - 1]) + let( + type = list[i][0], + ratio = list[i][1], + start = list[i][2], + present = list[i][3], + end = list[i][4], + last = vsum(i > 0 ? [for (j = [0 : i - 1]) list[j][4]] : []) + ) + [type, ratio, start + last, present + last, end + last] + ] +; + +/** + * Gets the overall number of steps to process all animations from the given list. + * @param Vector list - The list of animation thresholds to sum. + * @returns Number + */ +function getAnimationSteps(list) = + let( + list = array(list), + count = len(list) + ) + list[count - 1][4] +; + +/** + * Gets the X-coordinate of a straight barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the male link (default on the left). + * @returns Number + */ +function getStraightBarrierX(i, ratio=1, right=false) = + let( + barrierLength = getBarrierLength(trackLaneWidth, barrierWidth, barrierChunks), + sectionLength = getStraightLength(trackSectionLength, ratio), + barrierX = right ? (barrierLength - sectionLength) / 2 : (sectionLength - barrierLength) / 2 + ) + barrierX + i * barrierLength * (right ? 1 : -1) +; + +/** + * Gets the Y-coordinate of a straight barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the male link (default on the left). + * @returns Number + */ +function getStraightBarrierY(i, ratio=1, right=false) = + let( + barrierY = (trackSectionWidth - barrierWidth) / 2 + ) + right ? -barrierY : barrierY +; + +/** + * Gets the angle of a straight barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the male link (default on the left). + * @returns Number + */ +function getStraightRotation(i, ratio=1, right=false) = right ? STRAIGHT : 0; + +/** + * Gets the X-coordinate of a curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getCurveBarrierX(i, ratio=1, inner=false) = + let( + sizeRatio = max(1, ratio), + angle = getCurveAngle(ratio), + innerRadius = getCurveInnerRadius(length=trackSectionLength, width=trackSectionWidth, ratio=sizeRatio), + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=sizeRatio), + radius = inner ? getCurveInnerBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=sizeRatio) + : getCurveOuterBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=sizeRatio), + chunks = inner ? getCurveInnerBarrierChunks(barrierChunks, ratio) + : getCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks, + rotation = interval * i + interval / 2 + ) + radius * cos(inner ? angle - rotation : rotation) + (outerRadius - cos(angle) * innerRadius) / 2 - outerRadius +; + +/** + * Gets the Y-coordinate of a curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getCurveBarrierY(i, ratio=1, inner=false) = + let( + sizeRatio = max(1, ratio), + angle = getCurveAngle(ratio), + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=sizeRatio), + radius = inner ? getCurveInnerBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=sizeRatio) + : getCurveOuterBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=sizeRatio), + chunks = inner ? getCurveInnerBarrierChunks(barrierChunks, ratio) + : getCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks, + rotation = interval * i + interval / 2 + ) + radius * sin(inner ? angle - rotation : rotation) - (sin(angle) * outerRadius) / 2 +; + +/** + * Gets the angle of a curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getCurveRotation(i, ratio=1, inner=false) = + let( + angle = getCurveAngle(ratio), + chunks = inner ? getCurveInnerBarrierChunks(barrierChunks, ratio) + : getCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks + ) + (inner ? angle - interval * (i + 1) : interval * i) - getCurveRotationAngle(interval) +; + +/** + * Gets the X-coordinate of an enlarged curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getEnlargedCurveBarrierX(i, ratio=1, inner=false) = + let( + angle = CURVE_ANGLE, + innerRadius = getCurveInnerRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + side = inner ? 0 : getEnlargedCurveSide(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + radius = inner ? getEnlargedCurveInnerBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=ratio) + : getEnlargedCurveOuterBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=ratio), + chunks = inner ? getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio) + : getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks, + rotation = interval * i + interval / 2 + ) + radius * cos(inner ? angle - rotation : rotation) - outerRadius / 2 + side +; + +/** + * Gets the Y-coordinate of an enlarged curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getEnlargedCurveBarrierY(i, ratio=1, inner=false) = + let( + angle = CURVE_ANGLE, + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + side = inner ? 0 : getEnlargedCurveSide(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + radius = inner ? getEnlargedCurveInnerBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=ratio) + : getEnlargedCurveOuterBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=ratio), + chunks = inner ? getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio) + : getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks, + rotation = interval * i + interval / 2 + ) + radius * sin(inner ? angle - rotation : rotation) - outerRadius / 2 + side +; + +/** + * Gets the angle of an enlarged curved barrier given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [inner] - Tells if this is the inner or the outer curve (default: inner). + * @returns Number + */ +function getEnlargedCurveRotation(i, ratio=1, inner=false) = + let( + angle = getCurveAngle(ratio), + chunks = inner ? getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio) + : getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio), + interval = angle / chunks + ) + (inner ? angle - interval * (i + 1) : interval * i) - getCurveRotationAngle(interval) +; + +/** + * Gets the X-coordinate of a side barrier for an enlarged curve given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the barrier (default on the left). + * @returns Number + */ +function getEnlargedCurveSideBarrierX(i, ratio=1, right=false) = + let( + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + sideOffset = outerRadius / 2, + sidePosition = getEnlargedCurveSideBarrierPosition(length=trackSectionLength, width=trackSectionWidth, barrierWidth=barrierWidth, ratio=ratio) - sideOffset, + barrierLength = getBarrierLength(trackLaneWidth, barrierWidth, barrierChunks), + sectionLength = getStraightLength(trackSectionLength, ratio), + barrierX = (sectionLength - barrierLength) / 2 - sideOffset + ) + right ? sidePosition : barrierX - i * barrierLength +; + +/** + * Gets the Y-coordinate of a side barrier for an enlarged curve given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the barrier (default on the left). + * @returns Number + */ +function getEnlargedCurveSideBarrierY(i, ratio=1, right=false) = + let( + outerRadius = getCurveOuterRadius(length=trackSectionLength, width=trackSectionWidth, ratio=ratio), + barrierLength = getBarrierLength(trackLaneWidth, barrierWidth, barrierChunks) + ) + right ? (barrierLength - outerRadius) / 2 + i * barrierLength : (outerRadius - barrierWidth) / 2 +; + +/** + * Gets the angle of a side barrier for an enlarged curve given its position. + * @param Number i - The position of the barrier on its side. + * @param Number [ratio] - The size ratio. + * @param Boolean [right] - Tells on which side is the barrier (default on the left). + * @returns Number + */ +function getEnlargedCurveSideRotation(i, ratio=1, right=false) = right ? -RIGHT : 0; diff --git a/scale-64/shapes/animations/operators.scad b/scale-64/shapes/animations/operators.scad new file mode 100644 index 0000000..f3c2254 --- /dev/null +++ b/scale-64/shapes/animations/operators.scad @@ -0,0 +1,140 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the operators for the animations. + * + * @author jsconan + */ + +/** + * Animates child modules with respect to the supplied coordinates. + * @param Vector [translateFrom] - The coordinates from where starts to interpolate the translation. + * @param Vector [translateTo] - The coordinates to where ends to interpolate the translation. + * @param Vector [rotateFrom] - The coordinates from where starts to interpolate the rotation. + * @param Vector [rotateTo] - The coordinates to where ends to interpolate the rotation. + * @param Vector [scaleFrom] - The coordinates from where starts to interpolate the scaling. + * @param Vector [scaleTo] - The coordinates to where ends to interpolate the scaling. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Vector [translateValues] - A list of coordinates composing the range to interpolate the translation. + * @param Vector [translateRange] - A pre-built interpolation range for the translation. + * @param Vector [rotateValues] - A list of coordinates composing the range to interpolate the rotation. + * @param Vector [rotateRange] - A pre-built interpolation range for the rotation. + * @param Vector [scaleValues] - A list of coordinates composing the range to interpolate the scaling. + * @param Vector [scaleRange] - A pre-built interpolation range for the scaling. + */ +module animate( + translateFrom=defaultTranslateFrom, translateTo=defaultTranslateTo, + rotateFrom=defaultRotateFrom, rotateTo=defaultRotateTo, + scaleFrom=defaultScaleFrom, scaleTo=defaultScaleTo, + start, end, + translateValues, translateRange, + rotateValues, rotateRange, + scaleValues, scaleRange +) { + presentAnimate(start=start) { + translateAnimate(from=translateFrom, to=translateTo, values=translateValues, range=translateRange, start=start, end=end) { + rotateAnimate(from=rotateFrom, to=rotateTo, values=rotateValues, range=rotateRange, start=start, end=end) { + scaleAnimate(from=scaleFrom, to=scaleTo, values=scaleValues, range=scaleRange, start=start, end=end) { + children(); + } + } + } + } +} + +/** + * Animates child modules for a particular step. + * @param Number step - The step to animate. + * @param Number steps - The overall number of expected animated teps. + * @param Vector [translateTo] - The coordinates to where ends to interpolate the translation. + * @param Vector [rotateTo] - The coordinates to where ends to interpolate the rotation. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain used to compute the thresholds (default: 100). + */ +module animateStep(step, steps, translateTo, rotateTo, start, end, domain) { + animate( + translateTo = translateTo, + rotateTo = rotateTo, + start = interpolationThreshold(step=step, steps=steps, start=start, end=end, domain=domain), + end = interpolationThreshold(step=step + animateSteps, steps=steps, start=start, end=end, domain=domain) + ) { + children(); + } +} + +/** + * Slides the child modules for a particular step. + * @param Number step - The step to animate. + * @param Number steps - The overall number of expected animated teps. + */ +module animateSlide(step, steps) { + start = interpolationThreshold(step=step, steps=steps); + end = interpolationThreshold(step=step + slideSteps, steps=steps); + + translateAnimate( + from = defaultPresentation, + to = defaultSlideTo, + start = start, + end = end + ) { + rotateAnimate( + from = defaultRotateTo, + to = defaultRotateFrom, + start = start, + end = end + ) { + scaleAnimate( + from = defaultScaleTo, + to = defaultScaleFrom, + start = start, + end = end + ) { + children(); + } + } + } +} + +/** + * Presents the child modules between particular steps. + * @param Number from - The first step from which present the child modules. + * @param Number to - The last step to which present the child modules. + * @param Number steps - The overall number of expected animated teps. + */ +module presentSteps(from, to, steps) { + let( + slide = to - slideSteps, + start = interpolationThreshold(step=from, steps=steps), + end = interpolationThreshold(step=to, steps=steps) + ) { + presentAnimate(start=start, end=end) { + animateSlide(step=slide, steps=steps) { + children(); + } + } + } +} diff --git a/scale-64/shapes/animations/straight.scad b/scale-64/shapes/animations/straight.scad new file mode 100644 index 0000000..11eabf2 --- /dev/null +++ b/scale-64/shapes/animations/straight.scad @@ -0,0 +1,143 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the animated straight models. + * + * @author jsconan + */ + +/** + * Animates the construction of a straight section. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + * @param Boolean [starting] - Should the ground be the starting variant. + */ +module animatedStraightSection(start, end, domain, ratio=1, starting=false) { + elements = getStraightSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + i = elements[step][1]; + right = elements[step][2]; + + barrierX = getStraightBarrierX(i, ratio, right); + barrierY = getStraightBarrierY(i, ratio, right); + rotation = getStraightRotation(i, ratio, right); + + if (element == "peg") { + animateStep( + step = step, + translateTo=[barrierX, barrierY, 0], + steps=steps, start=start, end=end, domain=domain + ) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + animateStep( + step = step, + translateTo = [barrierX, barrierY, trackGroundThickness], + rotateTo = zAxis3D(rotation), + steps=steps, start=start, end=end, domain=domain + ) { + straightBarrierSet(); + } + } + } + if (element == "ground") { + animateStep(step=step, steps=steps, start=start, end=end, domain=domain) { + if (starting) { + startingTrackSectionGround(); + } else { + straightTrackSectionGround(ratio=ratio); + } + } + } + } +} + +/** + * Animates the construction of a straight full tile. + * @param Number [start] - The start threshold under what the from-coordinates will persist and above what it will be interpolated. + * @param Number [end] - The end threshold above what the to-coordinates will persist and under what it will be interpolated. + * @param Number [domain] - The percentage domain applied to compute the percentage ratio for the thresholds (default: 100). + * @param Number [ratio] - The size factor. + * @param Boolean [starting] - Should the ground be the starting variant. + */ +module animatedStraightTile(start, end, domain, ratio=1, starting=false) { + animateStep(step=0, steps=1, start=start, end=end, domain=domain) { + if (starting) { + startingTrackTile(); + } else { + straightTrackTile(ratio=ratio); + } + } +} + +/** + * An assembled straight section. + * @param Number [ratio] - The size factor. + * @param Boolean [starting] - Should the ground be the starting variant. + */ +module straightSection(ratio=1, starting=false) { + elements = getStraightSectionSteps(ratio); + steps = len(elements); + + for (step = [0 : steps - 1]) { + element = elements[step][0]; + i = elements[step][1]; + right = elements[step][2]; + + barrierX = getStraightBarrierX(i, ratio, right); + barrierY = getStraightBarrierY(i, ratio, right); + rotation = getStraightRotation(i, ratio, right); + + if (element == "peg") { + translate([barrierX, barrierY, 0]) { + barrierPegSet(); + } + } + if (element == "barrier") { + color(even(i) ? colorEven : colorOdd) { + translate([barrierX, barrierY, trackGroundThickness]) { + rotate(zAxis3D(rotation)) { + straightBarrierSet(); + } + } + } + } + if (element == "ground") { + if (starting) { + startingTrackSectionGround(); + } else { + straightTrackSectionGround(ratio=ratio); + } + } + } +} diff --git a/scale-64/shapes/barriers/curved.scad b/scale-64/shapes/barriers/curved.scad new file mode 100644 index 0000000..ec5e0ae --- /dev/null +++ b/scale-64/shapes/barriers/curved.scad @@ -0,0 +1,151 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the curved barriers. + * + * @author jsconan + */ + +/** + * Adds the links to a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Boolean [right] - Tells on which side is the male link (default on the left). + */ +module curvedLinks(radius, angle, width, height, right=false) { + linkHeight = getBarrierLinkHeight(width, height) - layerHeight; + + linkRotationMale = right ? CURVE_ANGLE : 0; + linkPositionMale = right ? [radius, 0, -height / 2] : [0, radius, -height / 2]; + linkDirectionMale = right ? 0 : angle - CURVE_ANGLE; + + linkRotationFemale = right ? CURVE_ANGLE : -CURVE_ANGLE; + linkPositionFemale = right ? [radius, 0, -height / 2 - ALIGN] : [radius, 0, -height / 2 - ALIGN]; + linkDirectionFemale = right ? angle : 0; + + rotateZ(linkDirectionMale) { + translate(linkPositionMale) { + rotateZ(linkRotationMale) { + barrierLink( + width = width, + height = linkHeight, + distance = -printTolerance, + neckDistance = printTolerance + ); + } + } + } + difference() { + children(); + rotateZ(linkDirectionFemale) { + translate(linkPositionFemale) { + rotateZ(linkRotationFemale) { + barrierLink( + width = width, + height = linkHeight + ALIGN, + distance = printTolerance, + neckDistance = 0 + ); + } + } + } + } +} + +/** + * Adds the fastener holes to a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [holes] - The number of holes to drill. + */ +module curvedFastenerHoles(radius, angle, width, height, diameter, headDiameter, headHeight, holes=FASTENER_HOLES) { + holeSectorAngle = angle * (holes - 1) / holes; + + difference() { + children(); + rotateZ((angle - holeSectorAngle) / 2) { + repeatRotate(angle=holeSectorAngle, count=holes) { + translateX(radius) { + barrierFastenerHole( + width = width, + height = height, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = 0 + ); + } + } + } + } +} + +/** + * Draws the body of a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + */ +module curvedBarrierBody(radius, angle, width, height) { + extrudeCurvedProfile(radius=radius, angle=angle) { + barrierProfile( + width = width, + height = height, + distance = 0 + ); + } +} + +/** + * Draws the shape of a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Boolean [right] - Tells on which side is the male link (default on the left). + * @param Number [holes] - The number of holes to drill. + */ +module curvedBarrier(radius, angle, width, height, diameter, headDiameter, headHeight, right=false, holes=FASTENER_HOLES) { + translateY(-radius) { + rotateZ(getCurveRotationAngle(angle)) { + curvedFastenerHoles(radius=radius, angle=angle, width=width, height=height, diameter=diameter, headDiameter=headDiameter, headHeight=headHeight, holes=holes) { + curvedLinks(radius=radius, angle=angle, width=width, height=height, right=right) { + curvedBarrierBody(radius=radius, angle=angle, width=width, height=height); + } + } + } + } +} diff --git a/scale-64/shapes/barriers/elements.scad b/scale-64/shapes/barriers/elements.scad new file mode 100644 index 0000000..5e9da46 --- /dev/null +++ b/scale-64/shapes/barriers/elements.scad @@ -0,0 +1,164 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the ready to print shapes for the barriers. + * + * @author jsconan + */ + +/** + * A set of pegs to fasten the barrier chunks to the track sections. + * @param Number [quantity] - The number of elements to print. + * @param Number [line] - The max number of elements per lines. + */ +module barrierPegSet(quantity=1, line=undef) { + radius = getBarrierPegDiameter(barrierWidth, barrierHeight) + trackGroundThickness * 2; + pegHeight = getBarrierPegHeight(barrierWidth, barrierHeight, trackGroundThickness); + + placeElements(length=radius, width=radius, quantity=quantity, line=line) { + translateZ(pegHeight / 2) { + color(colorPeg) { + barrierPeg( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + thickness = trackGroundThickness, + distance = 0 + ); + } + } + } +} + +/** + * A set of barrier chunks for a straight track section. + * @param Number [quantity] - The number of elements to print. + * @param Number [line] - The max number of elements per lines. + */ +module straightBarrierSet(quantity=1, line=undef) { + length = getStraightBarrierLength(barrierLength, barrierWidth, barrierHeight); + + placeElements(length=length, width=barrierWidth, quantity=quantity, line=line) { + translateZ(barrierHeight / 2) { + color(colorBarrier) { + straightBarrier( + length = barrierLength, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight + ); + } + } + } +} + +/** + * A set of barrier chunks for the inner curve of a curved track section. + * @param Number [ratio] - The size factor. + * @param Number [quantity] - The number of elements to print. + * @param Number [line] - The max number of elements per lines. + */ +module innerCurveBarrierSet(ratio=1, quantity=1, line=undef) { + radius = getCurveInnerBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio); + angle = getCurveAngle(ratio) / getCurveInnerBarrierChunks(barrierChunks, ratio); + length = getCurvedBarrierLength(radius, angle, barrierWidth, barrierHeight); + + placeElements(length=length, width=barrierWidth, quantity=quantity, line=line) { + translateZ(barrierHeight / 2) { + color(colorBarrier) { + curvedBarrier( + radius = radius, + angle = angle, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + right = true + ); + } + } + } +} + +/** + * A set of barrier chunks for the outer curve of a curved track section. + * @param Number [ratio] - The size factor. + * @param Number [quantity] - The number of elements to print. + * @param Number [line] - The max number of elements per lines. + */ +module outerCurveBarrierSet(ratio=1, quantity=1, line=undef) { + radius = getCurveOuterBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio); + angle = getCurveAngle(ratio) / getCurveOuterBarrierChunks(barrierChunks, ratio); + length = getCurvedBarrierLength(radius, angle, barrierWidth, barrierHeight); + + placeElements(length=length, width=barrierWidth, quantity=quantity, line=line) { + translateZ(barrierHeight / 2) { + color(colorBarrier) { + curvedBarrier( + radius = radius, + angle = angle, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + right = false + ); + } + } + } +} + +/** + * A set of barrier chunks for the outer curve of an enlarged curved track section. + * @param Number [ratio] - The size factor. + * @param Number [quantity] - The number of elements to print. + * @param Number [line] - The max number of elements per lines. + */ +module enlargedCurveBarrierSet(ratio=1, quantity=1, line=undef) { + radius = getEnlargedCurveOuterBarrierPosition(trackSectionLength, trackSectionWidth, barrierWidth, ratio); + angle = getCurveAngle(ratio) / getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio); + length = getCurvedBarrierLength(radius, angle, barrierWidth, barrierHeight); + + placeElements(length=length, width=barrierWidth, quantity=quantity, line=line) { + translateZ(barrierHeight / 2) { + color(colorBarrier) { + curvedBarrier( + radius = radius, + angle = angle, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + right = false + ); + } + } + } +} diff --git a/scale-64/shapes/barriers/fragments.scad b/scale-64/shapes/barriers/fragments.scad new file mode 100644 index 0000000..4763e65 --- /dev/null +++ b/scale-64/shapes/barriers/fragments.scad @@ -0,0 +1,90 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the fragments for the barriers. + * + * @author jsconan + */ + +/** + * Draws the shape of a barrier link. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number [distance] - An additional distance added to the outline of the shape. + * @param Number [neckDistance] - An additional distance added to the neck of the link. + * @param Boolean [center] - The shape is centered vertically. + */ +module barrierLink(width, height, distance=0, neckDistance=0, center=false) { + linear_extrude(height=height, center=center, convexity=10) { + barrierLinkProfile( + width = width, + height = height, + distance = distance, + neckDistance = neckDistance + ); + } +} + +/** + * Draws the shape of a barrier peg. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fastener. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPeg(width, height, diameter, thickness, distance=0) { + rotate_extrude(angle=DEGREES, convexity=10) { + barrierPegProfile( + width = width, + height = height, + diameter = diameter, + thickness = thickness, + distance = distance + ); + } +} + +/** + * Draws the shape of a barrier fastening hole. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [distance] - An additional distance added to the outline of the shape. + */ +module barrierFastenerHole(width, height, diameter, headDiameter, headHeight, distance=0) { + rotate_extrude(angle=DEGREES, convexity=10) { + barrierFastenerHoleProfile( + width = width, + height = height, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = distance + ); + } +} diff --git a/scale-64/shapes/barriers/helpers.scad b/scale-64/shapes/barriers/helpers.scad new file mode 100644 index 0000000..1b0fe1e --- /dev/null +++ b/scale-64/shapes/barriers/helpers.scad @@ -0,0 +1,140 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the helper functions for the barriers. + * + * @author jsconan + */ + +/** + * Computes the base unit value used to design the barrier shape. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @returns Number + */ +function getBarrierBaseUnit(width, height) = min(width, height) / 4; + +/** + * Computes the size of the offset for the barrier shape. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @returns Number + */ +function getBarrierOffset(width, height) = getBarrierBaseUnit(width, height) / 4; + +/** + * Computes the outer length of a barrier link. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @param Number [distance] - An additional distance added to the outline of the barrier link. + * @returns Number + */ +function getBarrierLinkLength(width, height, distance=0) = getBarrierBaseUnit(width, height) * 1.5 + distance; + +/** + * Computes the outer width of a barrier link. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @param Number [distance] - An additional distance added to the outline of the barrier link. + * @returns Number + */ +function getBarrierLinkWidth(width, height, distance=0) = (getBarrierBaseUnit(width, height) + distance) * 2; + +/** + * Computes the height of a barrier link. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @returns Number + */ +function getBarrierLinkHeight(width, height) = layerAligned(height - getBarrierBaseUnit(width, height)); + +/** + * Computes the diameter of the barrier pegs. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @returns Number + */ +function getBarrierPegDiameter(width, height) = width - getBarrierBaseUnit(width, height) - shells(2); + +/** + * Computes the height of the barrier pegs that plugs into the barriers. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @returns Number + */ +function getBarrierPegInnerHeight(width, height) = layerAligned(getBarrierBaseUnit(width, height) * 1.5); + +/** + * Computes the overall height of the barrier pegs. + * @param Number width - The width of the barriers. + * @param Number height - The height of the barriers. + * @param Number thickness - The thickness of the ground. + * @returns Number + */ +function getBarrierPegHeight(width, height, thickness) = getBarrierPegInnerHeight(width, height) + thickness; + +/** + * Gets the outer length of the shape of a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @returns Number + */ +function getStraightBarrierLength(length, width, height) = length + getBarrierLinkLength(width, height); + +/** + * Gets the outer width of the shape of a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @returns Number + */ +function getStraightBarrierWidth(length, width, height) = width; + +/** + * Gets the outer length of the shape of a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @returns Number + */ +function getCurvedBarrierLength(radius, angle, width, height) = + getChordLength(angle, radius + width / 2) + + getBarrierLinkLength(width, height) * cos(angle / 2) + + (getBarrierLinkWidth(width, height) - width) / 2 * cos(RIGHT - angle / 2) +; + +/** + * Gets the outer width of the shape of a curved barrier. + * @param Number radius - The radius of the curve. + * @param Number angle - The extrusion angle. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @returns Number + */ +function getCurvedBarrierWidth(radius, angle, width, height) = + getChordHeight(angle, radius + width / 2) + width * sin(RIGHT - angle / 2) +; diff --git a/scale-64/shapes/barriers/profiles.scad b/scale-64/shapes/barriers/profiles.scad new file mode 100644 index 0000000..8b50dc1 --- /dev/null +++ b/scale-64/shapes/barriers/profiles.scad @@ -0,0 +1,185 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the profiles for the barriers. + * + * @author jsconan + */ + +/** + * Draws the profile of a barrier. + * + * To get the final shape, linear_extrude(height=length, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierProfile(width, height, distance=0) { + // Uncomment to debug: + // %rectangle(vadd([width, height], distance * 2)); + + // Compute the base values + baseUnit = getBarrierBaseUnit(width, height); + barrierOffset = getBarrierOffset(width, height); + + // Prepare the parameters for the polygon + barrierTopWidth = width - barrierOffset * 2; + barrierSlopeWidth = barrierOffset; + barrierSlopeHeight = baseUnit - barrierOffset; + barrierOuterSide = baseUnit / 2; + barrierInnerSide = height - (barrierSlopeHeight + barrierOuterSide + barrierOffset * 2) * 2; + + // Draw the profile + polygon(outline(path([ + // top left + ["P", -barrierTopWidth / 2, height / 2], + ["L", -barrierOffset, -barrierOffset], + ["V", -barrierOuterSide], + ["L", barrierSlopeWidth, -barrierSlopeHeight], + ["L", barrierOffset, -barrierOffset], + // middle left + ["V", -barrierInnerSide], + // bottom left + ["L", -barrierOffset, -barrierOffset], + ["L", -barrierSlopeWidth, -barrierSlopeHeight], + ["V", -barrierOuterSide], + ["L", barrierOffset, -barrierOffset], + // bottom + ["H", barrierTopWidth], + // bottom right + ["L", barrierOffset, barrierOffset], + ["V", barrierOuterSide], + ["L", -barrierSlopeWidth, barrierSlopeHeight], + ["L", -barrierOffset, barrierOffset], + // middle right + ["V", barrierInnerSide], + // top right + ["L", barrierOffset, barrierOffset], + ["L", barrierSlopeWidth, barrierSlopeHeight], + ["V", barrierOuterSide], + ["L", -barrierOffset, barrierOffset], + ]), distance), convexity = 10); +} + +/** + * Draws the profile of a barrier fastening hole. + * + * To get the final shape, rotate_extrude(angle=360, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fastener. + * @param Number headDiameter - The diameter of the fastener head. + * @param Number headHeight - The height of the fastener head. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierFastenerHoleProfile(width, height, diameter, headDiameter, headHeight, distance=0) { + // Uncomment to debug: + // %rectangle([headDiameter + distance * 2, height]); + + // Prepare the parameters for the polygon + alignedHeight = height + ALIGN2; + headRadius = max(headDiameter, diameter) / 2 + distance; + radius = diameter / 2 + distance; + pegRadius = getBarrierPegDiameter(width, height) / 2 + distance; + pegHeight = getBarrierPegInnerHeight(width, height) + layerHeight + ALIGN; + remainingRadius = pegRadius - radius; + remainingPegHeight = pegHeight - remainingRadius; + remainingHeight = alignedHeight - headHeight - pegHeight; + remainingWidth = headRadius - radius; + + // Draw the profile + polygon(path([ + ["P", 0, alignedHeight / 2], + ["V", -alignedHeight], + ["H", pegRadius], + ["V", remainingPegHeight], + ["L", -remainingRadius, remainingRadius], + ["V", remainingHeight], + ["H", remainingWidth], + ["V", headHeight], + ]), convexity = 10); +} + +/** + * Draws the profile of a barrier link. + * + * To get the final shape, linear_extrude(height=height, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number [distance] - An additional distance added to the outline of the profile. + * @param Number [neckDistance] - An additional distance added to the neck of the link. + */ +module barrierLinkProfile(width, height, distance=0, neckDistance=0) { + base = getBarrierBaseUnit(width, height); + neckAlign = abs(distance); + neckLength = base / 2 + neckAlign + abs(neckDistance); + neckWidth = base; + + translateX(neckAlign) { + linkProfile( + neck = [neckLength, neckWidth], + bulb = base, + distance = distance + ); + } +} + +/** + * Draws the profile of a barrier peg. + * + * To get the final shape, rotate_extrude(angle=360, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fastener. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegProfile(width, height, diameter, thickness, distance=0) { + // Prepare the parameters for the polygon + pegDiameter = getBarrierPegDiameter(width, height); + pegHeight = getBarrierPegHeight(width, height, thickness); + radius = diameter / 2 + distance; + pegRadius = pegDiameter / 2 + distance; + pegFootRadius = pegRadius + thickness; + remainingRadius = pegRadius - radius; + remainingFootRadius = pegFootRadius - radius; + remainingHeight = pegHeight - remainingRadius - thickness; + + // Uncomment to debug: + // %rectangle([pegDiameter, pegHeight]); + + // Draw the profile + polygon(path([ + ["P", radius, pegHeight / 2], + ["V", -pegHeight], + ["H", remainingFootRadius], + ["L", -thickness, thickness], + ["V", remainingHeight], + ]), convexity = 10); +} diff --git a/scale-64/shapes/barriers/straight.scad b/scale-64/shapes/barriers/straight.scad new file mode 100644 index 0000000..acb84d2 --- /dev/null +++ b/scale-64/shapes/barriers/straight.scad @@ -0,0 +1,121 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the straight barriers. + * + * @author jsconan + */ + +/** + * Adds the links to a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + */ +module straightLinks(length, width, height) { + linkHeight = getBarrierLinkHeight(width, height); + + translate([-length, 0, -height] / 2) { + barrierLink( + width = width, + height = linkHeight - layerHeight, + distance = -printTolerance, + neckDistance = printTolerance + ); + } + difference() { + children(); + translate([length, 0, -height - ALIGN2] / 2) { + barrierLink( + width = width, + height = linkHeight + layerHeight + ALIGN, + distance = printTolerance, + neckDistance = 0 + ); + } + } +} + +/** + * Adds the fastener holes to a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [holes] - The number of holes to drill. + */ +module straightFastenerHoles(length, width, height, diameter, headDiameter, headHeight, holes=FASTENER_HOLES) { + interval = length / holes; + + difference() { + children(); + repeat(count=holes, intervalX=interval, center=true) { + barrierFastenerHole( + width = width, + height = height, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = 0 + ); + } + } +} + +/** + * Draws the body of a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + */ +module straightBarrierBody(length, width, height) { + extrudeStraightProfile(length=length) { + barrierProfile( + width = width, + height = height, + distance = 0 + ); + } +} + +/** + * Draws the shape of a straight barrier. + * @param Number length - The length of the barrier. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [holes] - The number of holes to drill. + */ +module straightBarrier(length, width, height, diameter, headDiameter, headHeight, holes=FASTENER_HOLES) { + straightFastenerHoles(length=length, width=width, height=height, diameter=diameter, headDiameter=headDiameter, headHeight=headHeight, holes=holes) { + straightLinks(length=length, width=width, height=height) { + straightBarrierBody(length=length, width=width, height=height); + } + } +} diff --git a/scale-64/shapes/grounds/curved.scad b/scale-64/shapes/grounds/curved.scad new file mode 100644 index 0000000..bd33cb3 --- /dev/null +++ b/scale-64/shapes/grounds/curved.scad @@ -0,0 +1,295 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the curved ground tiles. + * + * @author jsconan + */ + +/** + * Draws the shape of a curved ground. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number angle - The angle of the curve. + * @param Number [ratio] - The size factor. + */ +module curvedGround(length, width, thickness, angle, ratio=1) { + linear_extrude(height=thickness, center=true, convexity=10) { + curvedGroundProfile( + length = length, + width = width, + angle = angle, + ratio = ratio + ); + } +} + +/** + * Draws the shape of an enlarged curve ground. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveGround(length, width, thickness, ratio=1) { + linear_extrude(height=thickness, center=true, convexity=10) { + enlargedCurveGroundProfile( + length = length, + width = width, + ratio = ratio + ); + } +} + +/** + * Draws the shape of the holes for a curved ground. + * @param Number radius - The radius of the curve at the position of the holes. + * @param Number angle - The angle of the curve. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + */ +module curvedGroundHoles(radius, angle, thickness, barrierWidth, barrierHeight, barrierChunks) { + holeSectorAngle = angle * (barrierChunks - 1) / barrierChunks; + + rotateZ((angle - holeSectorAngle) / 2) { + repeatRotate(angle=holeSectorAngle, count=barrierChunks) { + translateX(radius) { + barrierPegHole( + width = barrierWidth, + height = barrierHeight, + thickness = thickness, + distance = printTolerance + ); + } + } + } +} + +/** + * Draws the shape of a curved ground tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + */ +module curvedGroundTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, ratio=1) { + sizeRatio = max(1, ratio); + angle = getCurveAngle(ratio); + innerRadius = getCurveInnerRadius(length=length, width=width, ratio=sizeRatio); + outerRadius = getCurveOuterRadius(length=length, width=width, ratio=sizeRatio); + barrierInnerPosition = getCurveInnerBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=sizeRatio); + barrierOuterPosition = getCurveOuterBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=sizeRatio); + innerBarrierChunks = getCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getCurveOuterBarrierChunks(barrierChunks, ratio); + + centerX = (outerRadius - cos(angle) * innerRadius) / 2 - outerRadius; + centerY = -(sin(angle) * outerRadius) / 2; + + module maleLink() { + barrierLinkGround( + width = barrierWidth, + height = barrierHeight, + thickness = thickness + ); + } + + module femaleLink() { + barrierLinkGroundHole( + width = barrierWidth, + height = barrierHeight + ); + } + + translate([centerX, centerY, 0]) { + difference() { + // Tile body + curvedGround( + length = length, + width = width, + thickness = thickness, + angle = angle, + ratio = sizeRatio + ); + // Fastener holes + curvedGroundHoles( + radius = barrierInnerPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = innerBarrierChunks + ); + curvedGroundHoles( + radius = barrierOuterPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = outerBarrierChunks + ); + // Barrier link holes + translate([barrierOuterPosition, 0, -barrierHeight / 2]) { + rotateZ(-CURVE_ANGLE) { + femaleLink(); + } + } + rotateZ(angle) { + translate([barrierInnerPosition, 0, -barrierHeight / 2]) { + rotateZ(CURVE_ANGLE) { + femaleLink(); + } + } + } + } + // Barrier links + translateX(barrierInnerPosition) { + rotateZ(-CURVE_ANGLE) { + maleLink(); + } + } + rotateZ(angle) { + translateX(barrierOuterPosition) { + rotateZ(CURVE_ANGLE) { + maleLink(); + } + } + } + } +} + +/** + * Draws the shape of an enlarged curve ground tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveGroundTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, ratio=1) { + angle = CURVE_ANGLE; + side = getEnlargedCurveSide(length=length, width=width, ratio=ratio); + sideOffset = side / 2; + innerRadius = getCurveInnerRadius(length=length, width=width, ratio=ratio); + outerRadius = getCurveOuterRadius(length=length, width=width, ratio=ratio); + barrierSidePosition = getEnlargedCurveSideBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio) - sideOffset; + barrierInnerPosition = getEnlargedCurveInnerBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio); + barrierOuterPosition = getEnlargedCurveOuterBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio); + sideBarrierChunks = getEnlargedCurveSideBarrierChunks(barrierChunks, ratio); + innerBarrierChunks = getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio); + + module maleLink() { + barrierLinkGround( + width = barrierWidth, + height = barrierHeight, + thickness = thickness + ); + } + + module femaleLink() { + barrierLinkGroundHole( + width = barrierWidth, + height = barrierHeight + ); + } + + translate([-outerRadius, -outerRadius, 0] / 2) { + difference() { + // Tile body + enlargedCurveGround( + length = length, + width = width, + thickness = thickness, + ratio = ratio + ); + // Fastener holes + translate([sideOffset, sideOffset, 0]) { + repeatRotate(count=2, angle=-CURVE_ANGLE) { + translateY(barrierSidePosition) { + straightGroundHolesLine( + length = side, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = sideBarrierChunks + ); + } + } + } + curvedGroundHoles( + radius = barrierInnerPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = innerBarrierChunks + ); + translate([side, side, 0]) { + curvedGroundHoles( + radius = barrierOuterPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = outerBarrierChunks + ); + } + // Barrier link holes + translate([side + barrierOuterPosition, 0, -barrierHeight / 2]) { + rotateZ(-CURVE_ANGLE) { + femaleLink(); + } + } + rotateZ(angle) { + translate([barrierInnerPosition, 0, -barrierHeight / 2]) { + rotateZ(CURVE_ANGLE) { + femaleLink(); + } + } + } + } + // Barrier links + translateX(barrierInnerPosition) { + rotateZ(-CURVE_ANGLE) { + maleLink(); + } + } + rotateZ(angle) { + translateX(side + barrierOuterPosition) { + rotateZ(CURVE_ANGLE) { + maleLink(); + } + } + } + } +} diff --git a/scale-64/shapes/grounds/elements.scad b/scale-64/shapes/grounds/elements.scad new file mode 100644 index 0000000..62b621f --- /dev/null +++ b/scale-64/shapes/grounds/elements.scad @@ -0,0 +1,128 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the ready to print shapes for the ground tiles. + * + * @author jsconan + */ + +/** + * A ground tile of a straight track section. + * @param Number [ratio] - The size factor. + */ +module straightTrackSectionGround(ratio=1) { + translateZ(trackGroundThickness / 2) { + flipElement(printGroundUpsideDown) { + color(colorGround) { + straightGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = ratio + ); + } + } + } +} + +/** + * A ground tile of a starting track section. + */ +module startingTrackSectionGround() { + translateZ(trackGroundThickness / 2) { + color(colorGround) { + straightGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 1 + ); + } + translateZ((trackGroundThickness + layerHeight) / 2) { + color(colorDecoration) { + startingGroundTileDecoration( + length = trackSectionLength, + width = trackSectionWidth, + thickness = layerHeight, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + startPositions = startPositions, + startLines = startLines, + shiftPositions = shiftStartPositions + ); + } + } + } +} + +/** + * A ground tile of a curved track section. + * @param Number [ratio] - The size factor. + */ +module curvedTrackSectionGround(ratio=1) { + translateZ(trackGroundThickness / 2) { + flipElement(printGroundUpsideDown) { + color(colorGround) { + curvedGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = ratio + ); + } + } + } +} + +/** + * A ground tile of a curved track section with extra space. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveTrackSectionGround(ratio=1) { + translateZ(trackGroundThickness / 2) { + flipElement(printGroundUpsideDown) { + color(colorGround) { + enlargedCurveGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = ratio + ); + } + } + } +} diff --git a/scale-64/shapes/grounds/fragments.scad b/scale-64/shapes/grounds/fragments.scad new file mode 100644 index 0000000..893a700 --- /dev/null +++ b/scale-64/shapes/grounds/fragments.scad @@ -0,0 +1,87 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the fragments for the ground tiles. + * + * @author jsconan + */ + +/** + * Draws the shape of a peg hole for the track ground. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegHole(width, height, thickness, distance=0) { + rotate_extrude(angle=DEGREES, convexity=10) { + barrierPegHoleProfile( + width = width, + height = height, + thickness = thickness, + distance = distance + ); + } +} + +/** + * Draws the shape of a starting block. + * @param Number length - The length of the block. + * @param Number width - The width of the block. + * @param Number height - The height of the block. + * @param Number thickness - The thickness of the outline. + * @param Number [distance] - An additional distance added to the outline of the profile. + * @param Boolean [center] - The shape is centered vertically. + */ +module startingBlock(length, width, height, thickness, distance=0, center=false) { + linear_extrude(height=height, center=center, convexity=10) { + startingBlockProfile( + length = length, + width = width, + thickness = thickness, + distance = distance + ); + } +} + +/** + * Draws the shape of finish line. + * @param Number length - The length of the line. + * @param Number width - The width of the line. + * @param Number height - The height of the line. + * @param Number lines - The number of lines inside the pattern. + * @param Number [distance] - An additional distance added to the outline of the profile. + * @param Boolean [center] - The shape is centered vertically. + */ +module finishLine(length, width, height, lines=2, distance=0, center=false) { + linear_extrude(height=height, center=center, convexity=10) { + finishLineProfile( + length = length, + width = width, + lines = lines, + distance = distance + ); + } +} diff --git a/scale-64/shapes/grounds/helpers.scad b/scale-64/shapes/grounds/helpers.scad new file mode 100644 index 0000000..0976e55 --- /dev/null +++ b/scale-64/shapes/grounds/helpers.scad @@ -0,0 +1,154 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the helper functions for the ground tiles. + * + * @author jsconan + */ + +/** + * Computes the length of the outer side of an enlarged curved track. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveSide(length, width, ratio=1) = length * ratio / 2; + +/** + * Computes the inner radius of a curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveInnerRadius(length, width, ratio=1) = getCurveInnerRadius(length=length, width=width, ratio=ratio); + +/** + * Computes the outer radius of an enlarged curved track. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveOuterRadius(length, width, ratio=1) = getCurveOuterRadius(length=length, width=width, ratio=ratio) - getEnlargedCurveSide(length=length, width=width, ratio=ratio); + +/** + * Computes the position of the inner barrier of a curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveInnerBarrierPosition(length, width, barrierWidth, ratio=1) = getCurveInnerRadius(length=length, width=width, ratio=ratio) + barrierWidth / 2; + +/** + * Computes the position of the outer barrier of a curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveOuterBarrierPosition(length, width, barrierWidth, ratio=1) = getCurveOuterRadius(length=length, width=width, ratio=ratio) - barrierWidth / 2; + +/** + * Computes the position of the side barrier of an enlarged curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveSideBarrierPosition(length, width, barrierWidth, ratio=1) = getCurveOuterRadius(length=length, width=width, ratio=ratio) - barrierWidth / 2; + +/** + * Computes the position of the inner barrier of an enlarged curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveInnerBarrierPosition(length, width, barrierWidth, ratio=1) = getEnlargedCurveInnerRadius(length=length, width=width, ratio=ratio) + barrierWidth / 2; + +/** + * Computes the position of the outer barrier of an enlarged curve given the ratio. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number barrierWidth - The width of the barriers. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveOuterBarrierPosition(length, width, barrierWidth, ratio=1) = getEnlargedCurveOuterRadius(length=length, width=width, ratio=ratio) - barrierWidth / 2; + +/** + * Computes the number of barrier chunks for a straight section given the ratio. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getStraightBarrierChunks(barrierChunks, ratio=1) = barrierChunks * abs(ratio); + +/** + * Computes the number of barrier chunks for an inner curved section given the ratio. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveInnerBarrierChunks(barrierChunks, ratio=1) = ratio < 1 ? 1 : barrierChunks / 2; + +/** + * Computes the number of barrier chunks for an outer curved section given the ratio. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getCurveOuterBarrierChunks(barrierChunks, ratio=1) = ratio == 1 ? barrierChunks : barrierChunks / 2; + +/** + * Computes the number of barrier chunks for the straight sides of large curve track. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveSideBarrierChunks(barrierChunks, ratio=1) = getStraightBarrierChunks(barrierChunks, ratio) / 2; + +/** + * Computes the number of barrier chunks for the inner curve of large curve track. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio=1) = getCurveInnerBarrierChunks(barrierChunks, ratio) * ratio; + +/** + * Computes the number of barrier chunks for the outer curve of large curve track. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + * @returns Number + */ +function getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio=1) = ratio == 1 ? barrierChunks / 2 : barrierChunks; diff --git a/scale-64/shapes/grounds/profiles.scad b/scale-64/shapes/grounds/profiles.scad new file mode 100644 index 0000000..c0f009d --- /dev/null +++ b/scale-64/shapes/grounds/profiles.scad @@ -0,0 +1,170 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the profiles for the ground tiles. + * + * @author jsconan + */ + +/** + * Draws the profile of a peg hole for the track ground. + * + * To get the final shape, rotate_extrude(angle=360, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module barrierPegHoleProfile(width, height, thickness, distance=0) { + // Prepare the parameters for the polygon + pegDiameter = getBarrierPegDiameter(width, height); + pegRadius = pegDiameter / 2 + distance; + pegFootRadius = pegRadius + thickness; + alignedHeight = thickness + ALIGN2; + + // Uncomment to debug: + // %rectangle([pegFootRadius * 2, thickness]); + + // Draw the profile + polygon(path([ + ["P", 0, alignedHeight / 2], + ["V", -alignedHeight], + ["H", pegFootRadius], + ["V", ALIGN], + ["L", -thickness, thickness], + ["V", ALIGN], + ]), convexity = 10); +} + +/** + * Draws the profile of a curved ground tile. + * + * To get the final shape, linear_extrude(height=height, convexity=10) must be applied. + * + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number angle - The angle of the curve. + * @param Number [ratio] - The size factor. + */ +module curvedGroundProfile(length, width, angle, ratio=1) { + innerRadius = getCurveInnerRadius(length=length, width=width, ratio=ratio); + outerRadius = getCurveOuterRadius(length=length, width=width, ratio=ratio); + startX = cos(angle) * innerRadius; + startY = sin(angle) * innerRadius; + + polygon(path([ + ["P", startX, startY], + ["C", innerRadius, angle, 0], + ["H", width], + ["C", outerRadius, 0, angle], + ]), convexity = 10); +} + +/** + * Draws the profile of an enlarged curve ground tile. + * + * To get the final shape, linear_extrude(height=height, convexity=10) must be applied. + * + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveGroundProfile(length, width, ratio=1) { + innerRadius = getEnlargedCurveInnerRadius(length=length, width=width, ratio=ratio); + outerRadius = getEnlargedCurveOuterRadius(length=length, width=width, ratio=ratio); + side = getEnlargedCurveSide(length=length, width=width, ratio=ratio); + angle = CURVE_ANGLE; + startX = cos(angle) * innerRadius; + startY = sin(angle) * innerRadius; + + polygon(path([ + ["P", startX, startY], + ["C", innerRadius, angle, 0], + ["H", width], + ["V", side], + ["C", outerRadius, 0, angle], + ["H", -side], + ]), convexity = 10); +} + +/** + * Draws the profile of a starting block. + * + * To get the final shape, linear_extrude(height=height, convexity=10) must be applied. + * + * @param Number length - The length of the block. + * @param Number width - The width of the block. + * @param Number thickness - The thickness of the outline. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module startingBlockProfile(length, width, thickness, distance=0) { + // Uncomment to debug: + // %translateY(thickness - width / 2) rectangle([length, width]); + + // Prepare the parameters for the polygon + innerLength = length - thickness * 2; + innerWidth = width - thickness; + + // Draw the profile + polygon(path([ + ["P", length / 2, 0], + ["H", -length], + ["V", -width], + ["H", thickness], + ["V", innerWidth], + ["H", innerLength], + ["V", -innerWidth], + ["H", thickness], + ]), convexity = 10); +} + +/** + * Draws the profile of finish line. + * + * To get the final shape, linear_extrude(height=height, convexity=10) must be applied. + * + * @param Number length - The length of the line. + * @param Number width - The width of the line. + * @param Number lines - The number of lines inside the pattern. + * @param Number [distance] - An additional distance added to the outline of the profile. + */ +module finishLineProfile(length, width, lines=2, distance=0) { + // Uncomment to debug: + // %translateY(-width / 2) rectangle([length, width]); + + // Prepare the parameters for the polygon + lines = max(2, lines); + tileWidth = width / lines; + cols = floor(length / tileWidth); + tileLength = length / cols; + + // Draw the profile + translateY(-width / 2) { + repeatAlternate2D(countX=cols, countY=lines, intervalX=xAxis3D(tileLength), intervalY=yAxis3D(tileWidth), center=true) { + rectangle([tileLength + ALIGN, tileWidth + ALIGN]); + } + } +} diff --git a/scale-64/shapes/grounds/straight.scad b/scale-64/shapes/grounds/straight.scad new file mode 100644 index 0000000..c34e834 --- /dev/null +++ b/scale-64/shapes/grounds/straight.scad @@ -0,0 +1,222 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the straight ground tiles. + * + * @author jsconan + */ + +/** + * Draws the shape for a line of holes. + * @param Number length - The length of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + */ +module straightGroundHolesLine(length, thickness, barrierWidth, barrierHeight, barrierChunks) { + barrierLength = length / barrierChunks; + + repeat(intervalX=barrierLength, count=barrierChunks, center=true) { + barrierPegHole( + width = barrierWidth, + height = barrierHeight, + thickness = thickness, + distance = printTolerance + ); + } +} + +/** + * Draws the shape of the holes for a straight ground. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + */ +module straightGroundHoles(length, width, thickness, barrierWidth, barrierHeight, barrierChunks) { + barrierPosition = (width - barrierWidth) / 2; + + repeatRotate(count=2) { + translateY(barrierPosition) { + straightGroundHolesLine( + length = length, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks + ); + } + } +} + +/** + * Draws the shape of the link hole for a ground tile. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + */ +module barrierLinkGroundHole(width, height) { + barrierLink( + width = width, + height = height, + distance = printTolerance * 2, + neckDistance = 0 + ); +} + +/** + * Draws the shape of the link for a ground tile. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the link. + */ +module barrierLinkGround(width, height, thickness) { + rotateZ(STRAIGHT) { + linear_extrude(height=thickness, center=true, convexity=10) { + barrierLinkProfile( + width = width, + height = height, + distance = 0, + neckDistance = printTolerance + ); + } + } +} + +/** + * Draws the shape of a straight ground tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number [ratio] - The size factor. + */ +module straightGroundTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, ratio=1) { + overallLength = getStraightLength(length, ratio); + overallChunks = getStraightBarrierChunks(barrierChunks, ratio); + + difference() { + // Tile body + box([overallLength, width, thickness], center=true); + // Fastener holes + straightGroundHoles( + length = overallLength, + width = width, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = overallChunks + ); + // Barrier link holes + repeatRotate(count=2) { + translate([overallLength, width - barrierWidth, -barrierHeight] / 2) { + barrierLinkGroundHole( + width = barrierWidth, + height = barrierHeight + ); + } + } + } + // Barrier links + repeatRotate(count=2) { + translate([overallLength, barrierWidth - width, 0] / 2) { + barrierLinkGround( + width = barrierWidth, + height = barrierHeight, + thickness = thickness + ); + } + } +} + +/** + * Draws the shape of the decoration for a starting ground tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number startPositions - The number of parallel starting blocks. + * @param Number startLines - The number of starting lines. + * @param Boolean shiftPositions - Tells if the positions on a same starting line should be shifted. + */ +module startingGroundTileDecoration(length, width, thickness, barrierWidth, barrierHeight, startPositions=2, startLines=2, shiftPositions=false) { + // Prepare the parameters + laneWidth = getTrackLaneWidth(width, barrierWidth); + finishLineWidth = laneWidth / 10; + finishLineArea = finishLineWidth * 2; + finishLinePosition = length / 2; + startingArea = length - finishLineArea; + startingBlockLength = laneWidth / (startPositions + 1); + startingBlockWidth = laneWidth / 10; + startingBlockThickness = getBarrierBaseUnit(barrierWidth, barrierHeight); + startingBlockIntervalX = laneWidth / startPositions; + startingBlockIntervalY = startingArea / startLines; + startingBlockShift = shiftPositions ? startingBlockWidth : 0; + startingBlockPosition = length / 2 + startingArea - length; + + // Uncomment to debug: + // %rectangle([length, width]); + // %translateX((startingArea - length) / 2) rectangle([startingArea, laneWidth]); + // %translateX((length - finishLineArea) / 2) rectangle([finishLineArea, laneWidth]); + + // Render the finish line + translateX(finishLinePosition) { + rotateZ(-RIGHT) { + finishLine( + length = laneWidth, + width = finishLineWidth, + height = thickness, + lines = 2, + distance = 0, + center = true + ); + } + } + + // Render the starting blocks + translateX(startingBlockPosition) { + rotateZ(-RIGHT) { + repeat(count=startLines, interval=yAxis3D(-startingBlockIntervalY), center=false) { + translateY(-startingBlockShift * (floor(startPositions / 2) - (1 - startPositions % 2) * .5)) { + repeat(count=startPositions, interval=[startingBlockIntervalX, -startingBlockShift, 0], center=true) { + startingBlock( + length = startingBlockLength, + width = startingBlockWidth, + height = thickness, + thickness = startingBlockThickness, + distance = 0, + center = true + ); + } + } + } + } + } +} diff --git a/scale-64/shapes/tiles/curved.scad b/scale-64/shapes/tiles/curved.scad new file mode 100644 index 0000000..8251f70 --- /dev/null +++ b/scale-64/shapes/tiles/curved.scad @@ -0,0 +1,351 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the curved full tiles. + * + * @author jsconan + */ + +/** + * Draws the shape of the holes for a curved tile. + * @param Number radius - The radius of the curve at the position of the holes. + * @param Number angle - The angle of the curve. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + */ +module curvedTileHoles(radius, angle, thickness, barrierWidth, barrierHeight, barrierChunks, diameter, headDiameter, headHeight) { + holeSectorAngle = angle * (barrierChunks - 1) / barrierChunks; + + rotateZ((angle - holeSectorAngle) / 2) { + repeatRotate(angle=holeSectorAngle, count=barrierChunks) { + translateX(radius) { + tileHole( + width = barrierWidth, + height = barrierHeight, + thickness = thickness, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = printTolerance + ); + } + } + } +} + +/** + * Draws the shape of a curved full tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [ratio] - The size factor. + */ +module curvedTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, diameter, headDiameter, headHeight, ratio=1) { + sizeRatio = max(1, ratio); + angle = getCurveAngle(ratio); + innerRadius = getCurveInnerRadius(length=length, width=width, ratio=sizeRatio); + outerRadius = getCurveOuterRadius(length=length, width=width, ratio=sizeRatio); + barrierInnerPosition = getCurveInnerBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=sizeRatio); + barrierOuterPosition = getCurveOuterBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=sizeRatio); + innerBarrierChunks = getCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getCurveOuterBarrierChunks(barrierChunks, ratio); + linkHeight = getBarrierLinkHeight(barrierWidth, barrierHeight); + + centerX = (outerRadius - cos(angle) * innerRadius) / 2 - outerRadius; + centerY = -(sin(angle) * outerRadius) / 2; + + module maleLink() { + tileLink( + width = barrierWidth, + height = linkHeight - layerHeight, + thickness = thickness, + distance = -printTolerance, + neckDistance = printTolerance + ); + } + + module femaleLink() { + tileLink( + width = barrierWidth, + height = linkHeight + layerHeight, + thickness = thickness + ALIGN, + distance = printTolerance, + neckDistance = 0 + ); + } + + translate([centerX, centerY, 0]) { + difference() { + union() { + // Tile body + translateZ(-thickness / 2) { + curvedGround( + length = length, + width = width, + thickness = thickness, + angle = angle, + ratio = sizeRatio + ); + } + // Barriers body + translateZ(barrierHeight / 2) { + curvedBarrierBody( + radius = barrierInnerPosition, + angle = angle, + width = barrierWidth, + height = barrierHeight + ); + curvedBarrierBody( + radius = barrierOuterPosition, + angle = angle, + width = barrierWidth, + height = barrierHeight + ); + } + } + // Fastener holes + curvedTileHoles( + radius = barrierInnerPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = innerBarrierChunks, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + ); + curvedTileHoles( + radius = barrierOuterPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = outerBarrierChunks, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + ); + // Barrier link holes + translateX(barrierOuterPosition) { + rotateZ(-CURVE_ANGLE) { + femaleLink(); + } + } + rotateZ(angle) { + translateX(barrierInnerPosition) { + rotateZ(CURVE_ANGLE) { + femaleLink(); + } + } + } + } + // Barrier links + translateX(barrierInnerPosition) { + rotateZ(CURVE_ANGLE) { + maleLink(); + } + } + rotateZ(angle) { + translateX(barrierOuterPosition) { + rotateZ(-CURVE_ANGLE) { + maleLink(); + } + } + } + } +} + +/** + * Draws the shape of an enlarged curve full tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, diameter, headDiameter, headHeight, ratio=1) { + angle = CURVE_ANGLE; + side = getEnlargedCurveSide(length=length, width=width, ratio=ratio); + sideOffset = side / 2; + innerRadius = getCurveInnerRadius(length=length, width=width, ratio=ratio); + outerRadius = getCurveOuterRadius(length=length, width=width, ratio=ratio); + barrierSidePosition = getEnlargedCurveSideBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio) - sideOffset; + barrierInnerPosition = getEnlargedCurveInnerBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio); + barrierOuterPosition = getEnlargedCurveOuterBarrierPosition(length=length, width=width, barrierWidth=barrierWidth, ratio=ratio); + sideBarrierChunks = getEnlargedCurveSideBarrierChunks(barrierChunks, ratio); + innerBarrierChunks = getEnlargedCurveInnerBarrierChunks(barrierChunks, ratio); + outerBarrierChunks = getEnlargedCurveOuterBarrierChunks(barrierChunks, ratio); + linkHeight = getBarrierLinkHeight(barrierWidth, barrierHeight); + barrierLength = length / barrierChunks; + + module maleLink() { + tileLink( + width = barrierWidth, + height = linkHeight - layerHeight, + thickness = thickness, + distance = -printTolerance, + neckDistance = printTolerance + ); + } + + module femaleLink() { + tileLink( + width = barrierWidth, + height = linkHeight + layerHeight, + thickness = thickness + ALIGN, + distance = printTolerance, + neckDistance = 0 + ); + } + + translate([-outerRadius, -outerRadius, 0] / 2) { + difference() { + union() { + // Tile body + translateZ(-thickness / 2) { + enlargedCurveGround( + length = length, + width = width, + thickness = thickness, + ratio = ratio + ); + } + // Barriers body + translateZ(barrierHeight / 2) { + curvedBarrierBody( + radius = barrierInnerPosition, + angle = angle, + width = barrierWidth, + height = barrierHeight + ); + translate([side, side, 0]) { + curvedBarrierBody( + radius = barrierOuterPosition, + angle = angle, + width = barrierWidth, + height = barrierHeight + ); + } + translate([sideOffset, sideOffset, 0]) { + repeatRotate(count=2, angle=-CURVE_ANGLE) { + translateY(barrierSidePosition) { + straightBarrierBody( + length = side, + width = barrierWidth, + height = barrierHeight + ); + } + } + } + } + } + // Fastener holes + curvedTileHoles( + radius = barrierInnerPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = innerBarrierChunks, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + ); + translate([side, side, 0]) { + curvedTileHoles( + radius = barrierOuterPosition, + angle = angle, + thickness = thickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = innerBarrierChunks, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + ); + } + translate([sideOffset, sideOffset, 0]) { + repeatRotate(count=2, angle=-CURVE_ANGLE) { + translateY(barrierSidePosition) { + repeat(intervalX=barrierLength, count=sideBarrierChunks, center=true) { + tileHole( + width = barrierWidth, + height = barrierHeight, + thickness = thickness, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = printTolerance + ); + } + } + } + } + // Barrier link holes + translateX(side + barrierOuterPosition) { + rotateZ(-CURVE_ANGLE) { + femaleLink(); + } + } + rotateZ(angle) { + translateX(barrierInnerPosition) { + rotateZ(CURVE_ANGLE) { + femaleLink(); + } + } + } + } + // Barrier links + translateX(barrierInnerPosition) { + rotateZ(CURVE_ANGLE) { + maleLink(); + } + } + rotateZ(angle) { + translateX(side + barrierOuterPosition) { + rotateZ(-CURVE_ANGLE) { + maleLink(); + } + } + } + } +} diff --git a/scale-64/shapes/tiles/elements.scad b/scale-64/shapes/tiles/elements.scad new file mode 100644 index 0000000..4aa541e --- /dev/null +++ b/scale-64/shapes/tiles/elements.scad @@ -0,0 +1,134 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the ready to print shapes for the full tiles. + * + * @author jsconan + */ + +/** + * A full tile of a straight track section. + * @param Number [ratio] - The size factor. + */ +module straightTrackTile(ratio=1) { + translateZ(trackGroundThickness / 2) { + color(colorTile) { + straightTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = ratio + ); + } + } +} + +/** + * A full tile of a starting track section. + */ +module startingTrackTile() { + translateZ(trackGroundThickness / 2) { + color(colorTile) { + straightTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 1 + ); + } + translateZ(layerHeight / 2) { + color(colorDecoration) { + startingGroundTileDecoration( + length = trackSectionLength, + width = trackSectionWidth, + thickness = layerHeight, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + startPositions = startPositions, + startLines = startLines, + shiftPositions = shiftStartPositions + ); + } + } + } +} + +/** + * A full tile of a curved track section. + * @param Number [ratio] - The size factor. + */ +module curvedTrackTile(ratio=1) { + translateZ(trackGroundThickness / 2) { + color(colorTile) { + curvedTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = ratio + ); + } + } +} + +/** + * A full tile of a curved track section with extra space. + * @param Number [ratio] - The size factor. + */ +module enlargedCurveTrackTile(ratio=1) { + translateZ(trackGroundThickness / 2) { + color(colorTile) { + enlargedCurveTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = ratio + ); + } + } +} diff --git a/scale-64/shapes/tiles/fragments.scad b/scale-64/shapes/tiles/fragments.scad new file mode 100644 index 0000000..90bae99 --- /dev/null +++ b/scale-64/shapes/tiles/fragments.scad @@ -0,0 +1,74 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the fragments for the full tiles. + * + * @author jsconan + */ + +/** + * Draws the shape of a tile link. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the track ground. + * @param Number [distance] - An additional distance added to the outline of the shape. + * @param Number [neckDistance] - An additional distance added to the neck of the link. + */ +module tileLink(width, height, thickness, distance=0, neckDistance=0) { + translateZ(-thickness) { + linear_extrude(height=height + thickness, center=false, convexity=10) { + barrierLinkProfile( + width = width, + height = height, + distance = distance, + neckDistance = neckDistance + ); + } + } +} + +/** + * Draws the shape of a tile fastening hole. + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the track ground. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [distance] - An additional distance added to the outline of the shape. + */ +module tileHole(width, height, thickness, diameter, headDiameter, headHeight, distance=0) { + rotate_extrude(angle=DEGREES, convexity=10) { + tileHoleProfile( + width = width, + height = height, + thickness = thickness, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = distance + ); + } +} diff --git a/scale-64/shapes/tiles/profiles.scad b/scale-64/shapes/tiles/profiles.scad new file mode 100644 index 0000000..27e8ee1 --- /dev/null +++ b/scale-64/shapes/tiles/profiles.scad @@ -0,0 +1,75 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the profiles for the full tiles. + * + * @author jsconan + */ + +/** + * Draws the profile of a tile fastening hole. + * + * To get the final shape, rotate_extrude(angle=360, convexity=10) must be applied. + * + * @param Number width - The width of the barrier. + * @param Number height - The height of the barrier. + * @param Number thickness - The thickness of the track ground. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [distance] - An additional distance added to the outline of the shape. + */ +module tileHoleProfile(width, height, thickness, diameter, headDiameter, headHeight, distance=0) { + // Prepare the parameters for the polygon + fullHeight = height + thickness + ALIGN2; + alignedHeight = height + ALIGN; + alignedThickness = thickness + ALIGN; + headRadius = max(headDiameter, diameter) / 2 + distance; + radius = diameter / 2 + distance; + pegRadius = getBarrierPegDiameter(width, height) / 2 + distance; + pegHeight = getBarrierPegInnerHeight(width, height) + layerHeight + ALIGN; + pegFootRadius = pegRadius + alignedThickness; + remainingRadius = pegRadius - radius; + remainingPegHeight = pegHeight - remainingRadius; + remainingHeight = alignedHeight - headHeight - pegHeight; + remainingWidth = headRadius - radius; + + // Uncomment to debug: + // %translateY(height / 2) rectangle([headRadius * 2, height]); + // %translateY(-thickness / 2) rectangle([pegFootRadius * 2, thickness]); + + // Draw the profile + polygon(path([ + ["P", 0, alignedHeight], + ["V", -fullHeight], + ["H", pegFootRadius], + ["L", -alignedThickness, alignedThickness], + ["V", remainingPegHeight], + ["L", -remainingRadius, remainingRadius], + ["V", remainingHeight], + ["H", remainingWidth], + ["V", headHeight], + ]), convexity = 10); +} diff --git a/scale-64/shapes/tiles/straight.scad b/scale-64/shapes/tiles/straight.scad new file mode 100644 index 0000000..0355b0c --- /dev/null +++ b/scale-64/shapes/tiles/straight.scad @@ -0,0 +1,107 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Defines the shapes for the straight full tiles. + * + * @author jsconan + */ + +/** + * Draws the shape of a straight full tile. + * @param Number length - The length of a track section. + * @param Number width - The width of a track section. + * @param Number thickness - The thickness of the track ground. + * @param Number barrierWidth - The width of the barrier. + * @param Number barrierHeight - The height of the barrier. + * @param Number barrierChunks - The number of barrier chunks per section. + * @param Number diameter - The diameter of the fasteners. + * @param Number headDiameter - The diameter of the fasteners head. + * @param Number headHeight - The height of the fasteners head. + * @param Number [ratio] - The size factor. + */ +module straightTile(length, width, thickness, barrierWidth, barrierHeight, barrierChunks, diameter, headDiameter, headHeight, ratio=1) { + overallLength = getStraightLength(length, ratio); + overallChunks = getStraightBarrierChunks(barrierChunks, ratio); + linkHeight = getBarrierLinkHeight(barrierWidth, barrierHeight); + barrierPosition = (width - barrierWidth) / 2; + barrierLength = length / barrierChunks; + + difference() { + union() { + // Tile body + translateZ(-thickness) { + box([overallLength, width, thickness], center=false); + } + // Barriers body + translate([0, barrierWidth - width, barrierHeight] / 2) { + repeat(count=2, intervalY=width - barrierWidth) { + straightBarrierBody( + length = overallLength, + width = barrierWidth, + height = barrierHeight + ); + } + } + } + repeatRotate(count=2) { + translateY(barrierPosition) { + // Fastener holes + repeat(intervalX=barrierLength, count=barrierChunks, center=true) { + tileHole( + width = barrierWidth, + height = barrierHeight, + thickness = thickness, + diameter = diameter, + headDiameter = headDiameter, + headHeight = headHeight, + distance = printTolerance + ); + } + // Link holes + translateX(overallLength / 2) { + tileLink( + width = barrierWidth, + height = linkHeight + layerHeight, + thickness = thickness + ALIGN, + distance = printTolerance, + neckDistance = 0 + ); + } + } + } + } + // Links + repeatRotate(count=2) { + translate(-[overallLength, barrierWidth - width, 0] / 2) { + tileLink( + width = barrierWidth, + height = linkHeight - layerHeight, + thickness = thickness, + distance = -printTolerance, + neckDistance = printTolerance + ); + } + } +} diff --git a/scale-64/slice.sh b/scale-64/slice.sh new file mode 100755 index 0000000..b7c3942 --- /dev/null +++ b/scale-64/slice.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# GPLv3 License +# +# Copyright (c) 2022 Jean-Sebastien CONAN +# +# This file is part of jsconan/rc-tracks. +# +# jsconan/rc-tracks is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# jsconan/rc-tracks is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with jsconan/rc-tracks. If not, see . +# + +# +# A race track system for 1/64 to 1/76 scale RC cars. +# +# Slices the STL files for the project. +# +# @author jsconan +# + +# script config +scriptpath="$(dirname $0)" +configpath="config/config.ini" + +# include libs +source "${scriptpath}/../lib/camelSCAD/scripts/utils.sh" + +# defines the config path +distfile "${configpath}" + +# redirect to the lib utils +"$(dirname $0)/../lib/camelSCAD/scripts/slice.sh" \ + --input "dist/stl" \ + --output "dist/gcode" \ + --config "${configpath}" \ + --prusaslicer \ + --recurse \ + "$@" + +# run a post-slice script +if [ -x "${scriptpath}/post-slice.sh" ]; then + printmessage "${C_CTX}Calling the post-slice script" + "${scriptpath}/post-slice.sh" +fi diff --git a/scale-64/test/barriers/curved.scad b/scale-64/test/barriers/curved.scad new file mode 100644 index 0000000..7e60530 --- /dev/null +++ b/scale-64/test/barriers/curved.scad @@ -0,0 +1,76 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the curved barriers. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + ratio = 1; + outerRadius = getCurveOuterRadius(trackSectionLength, trackSectionWidth, ratio) - barrierWidth / 2; + outerAngle = getCurveAngle(ratio) / getCurveOuterBarrierChunks(barrierChunks, ratio); + innerRadius = getCurveInnerRadius(trackSectionLength, trackSectionWidth, ratio) + barrierWidth / 2; + innerAngle = getCurveAngle(ratio) / getCurveInnerBarrierChunks(barrierChunks, ratio); + + distributeGrid( + intervalX = xAxis3D(getPrintInterval(getCurvedBarrierLength(outerRadius, outerAngle, barrierWidth, barrierHeight))), + intervalY = yAxis3D(getPrintInterval(getCurvedBarrierWidth(outerRadius, outerAngle, barrierWidth, barrierHeight))), + line = 1, + center = true + ) { + + // test the shape of a curved barrier for the outer radius of a track section + curvedBarrier( + radius = outerRadius, + angle = outerAngle, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + right = false + ); + + + // test the shape of a curved barrier for the inner radius of a track section + curvedBarrier( + radius = innerRadius, + angle = innerAngle, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + right = true + ); + + } +} diff --git a/scale-64/test/barriers/fragments.scad b/scale-64/test/barriers/fragments.scad new file mode 100644 index 0000000..ec57b74 --- /dev/null +++ b/scale-64/test/barriers/fragments.scad @@ -0,0 +1,68 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the fragments for the barriers. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=1, center=true) { + + // test the barrier link shape + barrierLink( + width = barrierWidth, + height = barrierHeight, + distance = printTolerance, + neckDistance = printTolerance, + center = true + ); + + // test the barrier peg shape + barrierPeg( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + thickness = trackGroundThickness, + distance = printTolerance + ); + + // test the barrier fastening hole shape + barrierFastenerHole( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + distance = printTolerance + ); + + } +} diff --git a/scale-64/test/barriers/profiles.scad b/scale-64/test/barriers/profiles.scad new file mode 100644 index 0000000..f5c5436 --- /dev/null +++ b/scale-64/test/barriers/profiles.scad @@ -0,0 +1,74 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the profiles for the barriers. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=2, center=true) { + + // test the barrier profile + barrierProfile( + width = barrierWidth, + height = barrierHeight, + distance = printTolerance + ); + + // test the barrier fastening hole profile + barrierFastenerHoleProfile( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + distance = printTolerance + ); + + // test the barrier link profile + barrierLinkProfile( + width = barrierWidth, + height = barrierHeight, + distance = printTolerance, + neckDistance = printTolerance + ); + + // test the barrier peg profile + barrierPegProfile( + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + thickness = trackGroundThickness, + distance = printTolerance + ); + + } +} diff --git a/scale-64/test/barriers/straight.scad b/scale-64/test/barriers/straight.scad new file mode 100644 index 0000000..c6418bc --- /dev/null +++ b/scale-64/test/barriers/straight.scad @@ -0,0 +1,55 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the straight barriers. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid( + intervalX = xAxis3D(getPrintInterval(getStraightBarrierLength(barrierLength, barrierWidth, barrierHeight))), + intervalY = yAxis3D(getPrintInterval(getStraightBarrierWidth(barrierLength, barrierWidth, barrierHeight))), + line = 1, + center = true + ) { + + // test the shape of a straight barrier + straightBarrier( + length = barrierLength, + width = barrierWidth, + height = barrierHeight, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight + ); + + } +} diff --git a/scale-64/test/grounds/curved.scad b/scale-64/test/grounds/curved.scad new file mode 100644 index 0000000..db8246e --- /dev/null +++ b/scale-64/test/grounds/curved.scad @@ -0,0 +1,95 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the curved ground tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(trackSectionLength), 0, 0], intervalY=[0, getPrintInterval(trackSectionLength), 0], line=2, center=true) { + + // test the shape of a curved ground tile: half of a tight curve + curvedGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = .5 + ); + + // test the shape of a curved ground tile: tight curve + curvedGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 1 + ); + + // test the shape of a curved ground tile: large curve + curvedGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 2 + ); + + // test the shape of a curved ground tile: very large curve + curvedGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 4 + ); + + // test the shape of a curved ground tile with extra space + enlargedCurveGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 1 + ); + + } +} diff --git a/scale-64/test/grounds/fragments.scad b/scale-64/test/grounds/fragments.scad new file mode 100644 index 0000000..76b5de7 --- /dev/null +++ b/scale-64/test/grounds/fragments.scad @@ -0,0 +1,68 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the fragments for the ground tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=1, center=true) { + + // test the barrier peg hole shape + barrierPegHole( + width = barrierWidth, + height = barrierHeight, + thickness = trackGroundThickness, + distance = printTolerance + ); + + // test the starting block shape + startingBlock( + length = max(barrierWidth, barrierHeight), + width = min(barrierWidth, barrierHeight) / 2, + height = trackGroundThickness, + thickness = getBarrierBaseUnit(barrierWidth, barrierHeight) / 2, + distance = printTolerance, + center = true + ); + + // test the finish line shape + finishLine( + length = max(barrierWidth, barrierHeight), + width = min(barrierWidth, barrierHeight) / 2, + height = trackGroundThickness, + lines = 4, + distance = printTolerance, + center = true + ); + + } +} diff --git a/scale-64/test/grounds/profiles.scad b/scale-64/test/grounds/profiles.scad new file mode 100644 index 0000000..21457e1 --- /dev/null +++ b/scale-64/test/grounds/profiles.scad @@ -0,0 +1,87 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the profiles for the ground tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=2, center=true) { + + // test the barrier peg hole profile + barrierPegHoleProfile( + width = barrierWidth, + height = barrierHeight, + thickness = trackGroundThickness, + distance = printTolerance + ); + + // test the curved track ground profile with a size ratio of 2 + curvedGroundProfile( + length = max(barrierWidth, barrierHeight) / 2, + width = min(barrierWidth, barrierHeight) / 2, + angle = CURVE_ANGLE, + ratio = 2 + ); + + // test the curved track ground profile with a size ratio of 1 + curvedGroundProfile( + length = max(barrierWidth, barrierHeight) / 2, + width = min(barrierWidth, barrierHeight) / 2, + angle = CURVE_ANGLE, + ratio = 1 + ); + + // test the enlarged curve track ground profile + enlargedCurveGroundProfile( + length = max(barrierWidth, barrierHeight) / 2, + width = min(barrierWidth, barrierHeight) / 2, + ratio = 1 + ); + + // test the starting block profile + startingBlockProfile( + length = max(barrierWidth, barrierHeight), + width = min(barrierWidth, barrierHeight) / 2, + thickness = getBarrierBaseUnit(barrierWidth, barrierHeight) / 2, + distance = printTolerance + ); + + // test the finish line profile + finishLineProfile( + length = max(barrierWidth, barrierHeight), + width = min(barrierWidth, barrierHeight) / 2, + lines = 4, + distance = printTolerance + ); + + } +} diff --git a/scale-64/test/grounds/straight.scad b/scale-64/test/grounds/straight.scad new file mode 100644 index 0000000..a63e453 --- /dev/null +++ b/scale-64/test/grounds/straight.scad @@ -0,0 +1,74 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the straight ground tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(trackSectionLength), 0, 0], intervalY=[0, getPrintInterval(trackSectionLength), 0], line=2, center=true) { + + // test the shape of a straight ground tile + straightGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = 1 + ); + + // test the shape of a straight ground tile: half the length + straightGroundTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + ratio = .5 + ); + + // test the shape of the decoration for a starting ground tile + startingGroundTileDecoration( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + startPositions = startPositions, + startLines = startLines, + shiftPositions = shiftStartPositions + ); + + } +} diff --git a/scale-64/test/tiles/curved.scad b/scale-64/test/tiles/curved.scad new file mode 100644 index 0000000..8399965 --- /dev/null +++ b/scale-64/test/tiles/curved.scad @@ -0,0 +1,110 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the curved full tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(trackSectionLength), 0, 0], intervalY=[0, getPrintInterval(trackSectionLength), 0], line=2, center=true) { + + // test the shape of a curved full tile: half of a tight curve + curvedTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = .5 + ); + + // test the shape of a curved full tile: tight curve + curvedTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 1 + ); + + // test the shape of a curved full tile: large curve + curvedTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 2 + ); + + // test the shape of a curved full tile: very large curve + curvedTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 4 + ); + + // test the shape of a curved full tile with extra space + enlargedCurveTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 1 + ); + + } +} diff --git a/scale-64/test/tiles/fragments.scad b/scale-64/test/tiles/fragments.scad new file mode 100644 index 0000000..3318dae --- /dev/null +++ b/scale-64/test/tiles/fragments.scad @@ -0,0 +1,60 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the fragments for the full tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=1, center=true) { + + // test the tile link shape + tileLink( + width = barrierWidth, + height = barrierHeight, + thickness = trackGroundThickness, + distance = printTolerance, + neckDistance = printTolerance + ); + + // test the tile fastening hole shape + tileHole( + width = barrierWidth, + height = barrierHeight, + thickness = trackGroundThickness, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + distance = printTolerance + ); + + } +} diff --git a/scale-64/test/tiles/profiles.scad b/scale-64/test/tiles/profiles.scad new file mode 100644 index 0000000..a47d881 --- /dev/null +++ b/scale-64/test/tiles/profiles.scad @@ -0,0 +1,51 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the profiles for the full tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(barrierWidth), 0, 0], intervalY=[0, getPrintInterval(barrierHeight), 0], line=2, center=true) { + + // test the tile fastening hole profile + tileHoleProfile( + width = barrierWidth, + height = barrierHeight, + thickness = trackGroundThickness, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + distance = printTolerance + ); + + } +} diff --git a/scale-64/test/tiles/straight.scad b/scale-64/test/tiles/straight.scad new file mode 100644 index 0000000..71b310a --- /dev/null +++ b/scale-64/test/tiles/straight.scad @@ -0,0 +1,68 @@ +/** + * @license + * GPLv3 License + * + * Copyright (c) 2022 Jean-Sebastien CONAN + * + * This file is part of jsconan/rc-tracks. + * + * jsconan/rc-tracks is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jsconan/rc-tracks is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jsconan/rc-tracks. If not, see . + */ + +/** + * A race track system for 1/64 to 1/76 scale RC cars. + * + * Test the shapes for the straight full tiles. + * + * @author jsconan + */ + +// Import the project's setup. +include <../../config/setup.scad> + +// Sets the minimum facet angle and size using the defined render mode. +applyMode(mode=renderMode) { + + distributeGrid(intervalX=[getPrintInterval(trackSectionLength), 0, 0], intervalY=[0, getPrintInterval(trackSectionLength), 0], line=2, center=true) { + + // test the shape of a straight full tile + straightTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = 1 + ); + + // test the shape of a straight full tile: half the length + straightTile( + length = trackSectionLength, + width = trackSectionWidth, + thickness = trackGroundThickness, + barrierWidth = barrierWidth, + barrierHeight = barrierHeight, + barrierChunks = barrierChunks, + diameter = fastenerDiameter, + headDiameter = fastenerHeadDiameter, + headHeight = fastenerHeadHeight, + ratio = .5 + ); + + } +}