add vsketch and nixos
parent
2ebe20e601
commit
d5e772c831
Binary file not shown.
After Width: | Height: | Size: 199 KiB |
Binary file not shown.
After Width: | Height: | Size: 210 KiB |
Binary file not shown.
After Width: | Height: | Size: 193 KiB |
|
@ -0,0 +1,169 @@
|
|||
---
|
||||
title: "vsketch and NixOS"
|
||||
date: 2023-07-09T15:26:24+02:00
|
||||
tags:
|
||||
- NixOS
|
||||
- Plotting
|
||||
- vsketch
|
||||
summary: >
|
||||
Adventures with vsketch, axidraw and NixOS.
|
||||
---
|
||||
|
||||
|
||||
# vsketch and NixOS
|
||||
I like to plotter. I like to draw pictures with my [axidraw](https://axidraw.com/) and ogle with the [terrapen](https://terrapen.xyz/products/terrapen-a2-pen-plotter) .
|
||||
|
||||
I had a few runs on using [vsketch](https://vsketch.readthedocs.io/en/latest/) in [NixOS](https://nixos.org) but because I don't know much about Python, I had never found enough time to make [vsketch](https://vsketch.readthedocs.io/en/latest/) work under NixOS. Same holds for the [axidraw cli](https://axidraw.com/doc/cli_api/#introduction).
|
||||
|
||||
But lately I got introduced to [pipenv](https://pipenv.pypa.io/en/latest/) which made everything possible and very easy.
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
I simple use a combination of `direnv` `shell.nix` , `steam-run` and `pipenv` to make everything work.
|
||||
|
||||
### shell.nix
|
||||
|
||||
The shell nix is called by `direnv` simply by putting
|
||||
|
||||
```text-plain
|
||||
use nix
|
||||
```
|
||||
|
||||
in the repositories `.envrc` file.
|
||||
|
||||
In the `shell.nix` I simple define a all packages I need and override the `steam-run` binary to add some package. Getting to this point, was a bit fiddly, but once it works, it works :D This is my `shell.nix`
|
||||
|
||||
```text-plain
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
pkgs.mkShell {
|
||||
buildInputs =
|
||||
let
|
||||
steamrun = (pkgs.steam.override {
|
||||
extraPkgs = pkgs: [
|
||||
(pkgs.python3.withPackages (ps: with ps; [
|
||||
matplotlib
|
||||
pyside6
|
||||
setuptools
|
||||
scikitlearn
|
||||
toml
|
||||
]))
|
||||
pkgs.qt6.qtbase
|
||||
];
|
||||
extraLibraries = pkgs: [ pkgs.libkrb5 ];
|
||||
}).run;
|
||||
in
|
||||
[
|
||||
(pkgs.writers.writeDashBin "vsk" ''
|
||||
${steamrun}/bin/steam-run pipenv run vsk "$@"
|
||||
'')
|
||||
(pkgs.writers.writeDashBin "axicli" ''
|
||||
${steamrun}/bin/steam-run pipenv run axicli "$@"
|
||||
'')
|
||||
(pkgs.writers.writeDashBin "pipenv-shell" ''
|
||||
${steamrun}/bin/steam-run pipenv shell
|
||||
'')
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Pipenv
|
||||
|
||||
Now `pipenv` has all needed dependencies for it's thing to do. But we need to set up `pipenv` itself as well, of course. Here is my `Pipfile`:
|
||||
|
||||
```text-plain
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
vsketch = {editable = true, git = "https://github.com/abey79/vsketch"}
|
||||
axicli = {file = "https://cdn.evilmadscientist.com/dl/ad/public/AxiDraw_API.zip" }
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
||||
python_full_version = "3.10.11"
|
||||
```
|
||||
|
||||
Now I can run
|
||||
|
||||
```text-plain
|
||||
pipenv install
|
||||
```
|
||||
|
||||
and magically the shell command `vsk` (which is defined in the `shell.nix`) works like charm.
|
||||
|
||||
My first sketch
|
||||
---------------
|
||||
|
||||
After running
|
||||
|
||||
```text-plain
|
||||
vsk init SimpleRings
|
||||
```
|
||||
|
||||
I could instantly start fiddling around with the code.
|
||||
|
||||
I'm amazed how fast my development cycle was. I could instantly see results, and play around with seed and parameters. And once I liked something. I can just hit **Like** and it will be saved as svg.
|
||||
|
||||
Here is my first script + some screenshots and photos of the results:
|
||||
|
||||
```text-plain
|
||||
import vsketch
|
||||
|
||||
class SimpleRingsSketch(vsketch.SketchClass):
|
||||
amount = vsketch.Param(3)
|
||||
space = vsketch.Param(30, min_value=10)
|
||||
min_radius = vsketch.Param(30, min_value=1)
|
||||
base_rotation = vsketch.Param(1)
|
||||
show_rings = vsketch.Param(True)
|
||||
show_rings_randomly = vsketch.Param(True)
|
||||
show_lines = vsketch.Param(True)
|
||||
|
||||
def draw(self, vsk: vsketch.Vsketch) -> None:
|
||||
vsk.size("a4", landscape=False)
|
||||
|
||||
# vsk.scale("mm")
|
||||
# height and width are in pixels (not mm)
|
||||
max_radius = min(vsk.height / 2, vsk.width / 2) - self.space
|
||||
|
||||
for i in range(self.amount):
|
||||
radius = vsk.random(self.min_radius, max_radius)
|
||||
amount_of_lines = int(vsk.random(1, radius))
|
||||
line_length = vsk.random(1, 20)
|
||||
circle_line_height = vsk.random(1, line_length)
|
||||
|
||||
# vsk.random() consumes the seed, so we have to consume it in every step, other changing the
|
||||
# options would result in different results in the other routines.
|
||||
if vsk.random(0, 1) > 0.5 or not self.show_rings_randomly:
|
||||
if self.show_rings:
|
||||
vsk.circle(0, 0, radius - circle_line_height, mode="radius")
|
||||
|
||||
if not self.show_lines:
|
||||
continue
|
||||
vsk.rotate(self.base_rotation, degrees=True)
|
||||
with vsk.pushMatrix():
|
||||
angle = 360.0 / amount_of_lines
|
||||
for j in range(0, amount_of_lines):
|
||||
vsk.rotate(angle, degrees=True)
|
||||
vsk.line(0, radius, 0, radius - line_length)
|
||||
|
||||
def finalize(self, vsk: vsketch.Vsketch) -> None:
|
||||
vsk.vpype("linemerge linesimplify reloop linesort")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
SimpleRingsSketch.display()
|
||||
```
|
||||
|
||||
{{< card >}}
|
||||
{{<figure src="./images/screenshot.png" width=100% >}}
|
||||
{{< /card >}}
|
||||
|
||||
{{< card >}}
|
||||
{{<figure src="./images/plot01.jpg" width=100% >}}
|
||||
{{<figure src="./images/plot02.jpg" width=100% >}}
|
||||
{{< /card >}}
|
Loading…
Reference in New Issue