✍ diale.org

Webpage of Tiago Charters de Azevedo

Início/Start Arquivo/Archive AdNauseum Notas/Notes Contact me RSS


Isto é parte da dificuldade, apenas o início.

Senso comum e a sua sua falta dele

2017/09/20-12:06:51

Etiquetas/Tags: filosofia, física, senso comum

DVD Plotter

Uma construção transversal

2017/09/20-11:28:30

A construção de uma plotter reciclando os motores passa-a-passo de umas drives de CDROM não é um projecto original mas coloca alguns desafios de montagem, calibração e programação.

A minha abordagem não difere de muitas outras que se podem encontrar pela net fora, apenas difere no objectivo. Desenhar numa folha de papel, nem que seja de dimensões reduzidas (4cm por 4cm), soluções de equações diferenciais ordinárias.

Assim para além de ter de controlar os motores passo-a-passo é necessário construir a rotina de integração numérica. Implementei um Runge-Kutta de ordem 4 (há quantos exemplos na net) apenas tive de o ajustar às minhas necessidades.

A construção ficou assim:

Está disponível um vídeo.

As funções que implementam a resolução numérica são duas.

// Runge-Kutta

float rk(float t, float dt, float x[]){
  float xaux[]={0,0,0};
  int i=0,j=0;

    f(t,x,k1);
    for(i=0;i<m;i++){
        xaux[i]=x[i]+dt/2*k1[i];}

    f(t+dt/2,xaux,k2);
    for(i=0;i<m;i++){
      xaux[i]=x[i]+dt/2*k2[i];}

    f(t+dt/2,xaux,k3);
    for(i=0;i<m;i++){
      xaux[i]=x[i]+dt/2*k3[i];}
    
    f(t+dt,xaux,k4);

    for(i=0;i<m;i++){
      x[i]=x[i]+dt/6.0*(k1[i]+2.0*k2[i]+2*k3[i]+k4[i]);}

    t=t+dt;}

void f(float t, float x[],float aux[]){
  aux[0]=c1*(x[1]-x[0]);
  aux[1]=x[0]*(c2-x[2]);
  aux[2]=x[0]*x[1]-c3*x[2];}

E o código completo é este

#include <Servo.h>
#include "AFMotor.h"
#define LINE_BUFFER_LENGTH 512

/* -------------------------------------------------- */
// Plotter parameters
// SINGLE, DOUBLE. INTERLEAVE or MICROSTEP.
char STEP=MICROSTEP;
const int stepsPerRevolution=20; 
AF_Stepper PStepperY(stepsPerRevolution,1);            
AF_Stepper PStepperX(stepsPerRevolution,2);  

float StepsPerMillimeterX=100.0;
float StepsPerMillimeterY=100.0;
const float pi=3.14159265358979;

const int penZUp=80;
const int penZDown=66;
const int penServoPin =10; 
Servo penServo;  
/* -------------------------------------------------- */

/* -------------------------------------------------- */
// Drawing robot limits, in mm
float Xmin=0;
float Xmax=40;
float Ymin=0;
float Ymax=40;
float Zmin=0;
float Zmax=1;

float Xpos=Xmin;
float Ypos=Ymin;
float Zpos=Zmax; 

float StepInc=1;
int StepDelay=0;
int LineDelay=0;
int penDelay=5;
/* -------------------------------------------------- */

/* -------------------------------------------------- */
// begin ode parameters
const float c1=10.0; 
const float c2=28.0;
const float c3=8.0/3.0;
const int m=3; // ode order
const float dt=0.01; //integration step
  
float x[m]={1, 1, 1};    // init conditions
float xaux[m]={0, 0, 0};    // aux
float k1[m], k2[m], k3[m], k4[m]; // arrays for the Runge-Kutta intermediate points
/* -------------------------------------------------- */

void setup() {
  //  Serial.begin(9600);

  PStepperX.setSpeed(5);
  PStepperY.setSpeed(5);
  
  penServo.attach(penServoPin);
  penServo.write(penZUp);
  delay(100);}

void loop(){
  int i=0;
  int n=10000;
  float t=0;

  penUp();
  delay(1000);

  /* -------------------------------------------------- */
  // Do some jogging...
  /* -------------------------------------------------- */
  move(Xmax,0);
  move(Xmax,Ymax);
  move(0,Ymax);
  move(0,0);
  /* -------------------------------------------------- */

  
  /* -------------------------------------------------- */
  // Draw the square limits
  /* -------------------------------------------------- */
  drawLine(Xmax,0);
  drawLine(Xmax,Ymax);
  drawLine(0,Ymax);
  drawLine(0,0);
  /* -------------------------------------------------- */
  
  penUp();
  delay(2000);

  /* -------------------------------------------------- */
  // Move to initial position
  /* -------------------------------------------------- */
  move(x[1],x[2]);

  
  // use random initials conditions
  // or close to the one given {1,1,1}
  for(i=0;i<=n;i++){
    rk(t,dt, x);
    drawLine(Xmax/2+x[1]*2.0/3.0,x[2]*4.0/5.0);
  }

  
    penUp();
    move(Xmax,Ymax);
    delay(100000);}

void penUp(){ 
   penServo.write(penZUp); 
   delay(penDelay);}
 
 void penDown(){ 
   penServo.write(penZDown); 
   delay(penDelay);}
 
void drawLine(float x1, float y1){
  if (x1 >= Xmax){x1=Xmax;}
  if (x1 <= Xmin){x1=Xmin;}
  if (y1 >= Ymax){y1=Ymax;}
  if (y1 <= Ymin){y1=Ymin;}
  
  x1=(int)(x1*StepsPerMillimeterX);     //  Convert coordinates to steps
  y1=(int)(y1*StepsPerMillimeterY);
  float x0=Xpos;
  float y0=Ypos;
  
  long dx=abs(x1-x0);     //  Let's find out the change for the coordinates
  long dy=abs(y1-y0);
  int sx=x0<x1 ? StepInc : -StepInc;
  int sy=y0<y1 ? StepInc : -StepInc;
  
  long i;
  long over=0;
  penDown();
  
  if (dx>dy){
    for (i=0; i<dx; ++i) {
      PStepperX.onestep(sx,STEP);
      over+=dy;
      if (over>=dx) {
        over-=dx;
        PStepperY.onestep(sy,STEP);}
      delay(StepDelay);}}
  else{
    for (i=0; i<dy; ++i){
      PStepperY.onestep(sy,STEP);
      over+=dx;
      if (over>=dy){
        over-=dy;
        PStepperX.onestep(sx,STEP);}
      delay(StepDelay);}}
  
  Xpos=x1;
  Ypos=y1;}


void move(float x1, float y1){
  penUp();
  
  if (x1 >= Xmax){
    x1=Xmax;}
  if (x1 <= Xmin){
    x1=Xmin;}
  if (y1 >= Ymax){
    y1=Ymax;}
  if (y1 <= Ymin){
    y1=Ymin;}
  
  x1=(int)(x1*StepsPerMillimeterX);     //  Convert coordinates to steps
  y1=(int)(y1*StepsPerMillimeterY);
  float x0=Xpos;
  float y0=Ypos;
  
  long dx=abs(x1-x0);     //  Let's find out the change for the coordinates
  long dy=abs(y1-y0);
  int sx=x0<x1 ? StepInc : -StepInc;
  int sy=y0<y1 ? StepInc : -StepInc;
  
  long i;
  long over=0;
  
  if (dx>dy){
    for (i=0; i<dx; ++i) {
      PStepperX.onestep(sx,STEP);
      over+=dy;
      if (over>=dx) {
        over-=dx;
        PStepperY.onestep(sy,STEP);}
      delay(StepDelay);}}
  else{
    for (i=0; i<dy; ++i){
      PStepperY.onestep(sy,STEP);
      over+=dx;
      if (over>=dy){
        over-=dy;
        PStepperX.onestep(sx,STEP);}
      delay(StepDelay);}}
  
  Xpos=x1;
  Ypos=y1;}


// Runge-Kutta

float rk(float t, float dt, float x[]){
  float xaux[]={0,0,0};
  
  int i=0,j=0;
  
    
    f(t,x,k1);
    for(i=0;i<m;i++){
        xaux[i]=x[i]+dt/2*k1[i];}

    f(t+dt/2,xaux,k2);
    for(i=0;i<m;i++){
      xaux[i]=x[i]+dt/2*k2[i];}

    f(t+dt/2,xaux,k3);
    for(i=0;i<m;i++){
      xaux[i]=x[i]+dt/2*k3[i];}
    
    f(t+dt,xaux,k4);

    for(i=0;i<m;i++){
      x[i]=x[i]+dt/6.0*(k1[i]+2.0*k2[i]+2*k3[i]+k4[i]);}

    t=t+dt;

  }

void f(float t, float x[],float aux[]){
  aux[0]=c1*(x[1]-x[0]);
  aux[1]=x[0]*(c2-x[2]);
  aux[2]=x[0]*x[1]-c3*x[2];}

Parte das peças usadas foram impressas e modeladas usando o OpenScad:

include <../utils/polyholes.scad>
$fn=64;
h=15;


module pin(r=2.8){
    difference(){
        union(){
            cylinder(h=h,r=5,center=true);
            translate([0,0,1]){
                cylinder(h,r=r,center=true);}}
        poly_cylinder(h=2*h,r=2,center=true);}}

module print(){
    n=3;
    translate([0,0,h/2]){
        for(i=[0:n]){
            translate([0,12*i,0]){
                pin(2.8);}
            translate([12,12*i,0]){
                pin(7.1/2);}}}

    translate([20,0,0]){
        rotate([0,0,90])
        fixing();}

        translate([20,11*2.5,0]){
        rotate([0,0,90])
        fixing();}}



module fixing(l=25,rc=.1*22){
    difference(){
        minkowski(){
            cube([l-rc,l-rc,l-rc],center=true);
            sphere(rc);}
        
        translate([0,0,-l/2+.01]){
            cube([2*l,2*l,l],center=true);}
        
        translate([0,l/2,l]){
            cube([2*l,l,2*l],center=true);}
        
        translate([0,-l/1.4,l/1.4]){
            rotate([45,0,0])
            cube([1.5*l,l,l],center=true);}
        
        translate([0,-l/4,l-4.5]){
            cylinder(l,r=4,center=true,$fn=6);
            poly_cylinder(2*l,r=2,center=true);}
        
        translate([l/3,0,l/4]){
            rotate([90,0,0]){
                translate([0,0,l-4.5]){
                    cylinder(l,r=4,center=true,$fn=6);
                    poly_cylinder(2*l,r=2,center=true);}}}

        translate([-l/3,0,l/4]){
            rotate([90,0,0]){
                translate([0,0,l-4.5]){
                    cylinder(l,r=4,center=true,$fn=6);
                    poly_cylinder(2*l,r=2,center=true);}}}}}    


module otherfixing(l=25,rc=.1*22){
    difference(){
        minkowski(){
            cube([l-rc,l-rc,l-rc],center=true);
            sphere(rc);}
        
        translate([0,0,-l/2+.01]){
            cube([2*l,2*l,l],center=true);}
        
        translate([0,l/2,l]){
            cube([2*l,l,2*l],center=true);}
        
        translate([0,-l/1.4,l/1.4]){
            rotate([45,0,0])
            cube([1.5*l,l,l],center=true);}
        
        translate([0,-l/4,l-4.5]){
            cylinder(l,r=4.5,center=true,$fn=64);
            poly_cylinder(2*l,r=2,center=true);}
        
        translate([l/3,0,l/4]){
            rotate([90,0,0]){
                translate([0,0,l-4.5]){
                    cylinder(l,r=4.5,center=true,$fn=66);
                    poly_cylinder(2*l,r=2,center=true);}}}

        translate([-l/3,0,l/4]){
            rotate([90,0,0]){
                translate([0,0,l-4.5]){
                    cylinder(l,r=4.5,center=true,$fn=64);
                    poly_cylinder(2*l,r=2,center=true);}}}}}    



a=25.4*4/3;
b=25.4*2;

module penbase(){
    
    difference(){
        cube([a,b,2.5],center=true);
        translate([0,12,10/2]){
            rotate([0,0,90]){
                poly_cylinder(h=b,r=2.1,center=true);}}}


    //Servo holder
    difference(){
        translate([a/2-5/2,-b/2+2.5,15/2-2.5/2]){
            cube([5,5,15],center=true);}
        
        translate([a/2-1.25/2,-b/2+5-2,2+5]){
            rotate([0,90,0]){
                cylinder(10,r=.8,center=true);}}}

    //Servo holder
    difference(){
        translate([a/2-5/2,-b/2+5+2.5+23.5,15/2-2.5/2]){
            cube([5,5,15],center=true);}
        
        translate([a/2-1.25/2,-b/2+21+7+2.5,2+5]){
            rotate([0,90,0]){
                cylinder(h=10,r=.8,center=true);}}}
    
    difference(){
        union(){
            translate([-a/2+6,b/2-2.5,10/2-2.5/2]){
                cube([12,5,10],center=true);}
            
            translate([-a/2+6,-b/2+2.5,10/2-2.5/2]){
                cube([12,5,10],center=true);}}
        
        
        translate([-a/2+6-3,2.5,10/2]){
            rotate([0,90,90]){
                poly_cylinder(h=b,r=3.1/2,center=true);}}
        
        translate([-a/2+6+3,2.5,10/2]){
            rotate([0,90,90]){
                poly_cylinder(h=b,r=3.1/2,center=true);}}


    }}

module penholder(){
    difference(){
        translate([-a/2+6,0,22/2+2.5/2+1]){
            cube([13,12,22],center=true);}

        translate([-a/2+6-3,2.5,10/2]){
            rotate([0,90,90]){
                poly_cylinder(h=b,r=3.3/2,center=true);}}

        translate([-a/2+6+3,2.5,10/2]){
            rotate([0,90,90]){
                poly_cylinder(h=b,r=3.3/2,center=true);}}
        
        translate([-a/2+6,2.5,13]){
            rotate([0,90,90]){
                poly_cylinder(h=b,r=4.25,center=true);}}
        
        translate([-a/2+6,2.5,25]){
            rotate([0,0,90]){
                cube([20,2,20],center=true);}}
        
        translate([-a/2+6,0,21]){
            rotate([0,90,0]){
                poly_cylinder(h=b,r=2,center=true);}}
        
        
    }}

module otherpin(h=7,r=2){
    difference(){

            cylinder(h=h,r=5,center=true);      
        poly_cylinder(h=2*h,r=2,center=true);}}


module foot(h=12,r=2){
    difference(){
        cylinder(h=h,r1=5,r2=5,center=true);
        translate([0,0,-h+5]){
            poly_cylinder(h,r=6.25/2,center=true,$fn=6);}
        poly_cylinder(h=1.1*h,r=2.1,center=true);}}

module penpin(h=7,r=2){
    difference(){
        hull(){
            cylinder(h=h,r=5,center=true);
            translate([0,5,0])
            cylinder(h=h,r=5,center=true);}

        
        poly_cylinder(h=2*h,r=r,center=true);}}

 penbase();

Etiquetas/Tags: dvd, plotter, maker, diy, arduino

Yet another Platonic solid set

... circumscribed in a 25mm radius sphere

2017/05/25-12:35:21

Get it here: https://www.youmagine.com/designs/yet-another-platonic-solid-set

Print it, share and learn!

Etiquetas/Tags: 3dprint, 3dprinting, Platonic, regular, solid, solids, polyhedron

So you want to print a Truncated Icosahedron ?

Buckyball

2017/05/25-12:29:36

Get it here: https://www.youmagine.com/designs/truncated-icosahedron-buckyball

Print it, share and learn!

Etiquetas/Tags: buckyball, Truncated Icosahedron, Truncated, Icosahedron, 3dprint, 3dprinting

Paradroid: how I did it

Steps to build a 2.5D Paradroid for 3D printing

2017/05/03-14:11:33

It all started when I found some drawings of the character of the infamous computer game from the 80's.

The next step was obvious to me, just build a raster graphics of the beast using GNU/Octave. As is the original image needed some modification on order to be 3d-printed.

A=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1;
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1;    
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1;
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1;
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;    
1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1;
1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0;
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0;
0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 1 1 0 0 0;
0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 1 1 0 0 0;
0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 1 1 0 0 0;
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0;
1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0;    
1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1;
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1;    
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1];
imshow(A)

print -deps -color paradroid.eps
print -dpng -color paradroid.png

So added some extra squares to get the job done.

Then used the Inkscape-to-OpenSCAD plugin and got the final 3d model, after some editing on the output code.

And it prints nicely with a resolution of 0.2mm and a 20% infill.

You can get it here: https://www.youmagine.com/designs/paradroid-ornament-key-chain

Share and enjoy!

Etiquetas/Tags: paradroid, 3d, 3dprinting, 3dprint, game, math

Números pseudo-aleatórios em LISP

Implementação em LISP de um gerador de números pseudo-aleatórios

2017/04/19-17:34:32

Uma das formas de gerar números com uma distribuição uniforme num intervalo é usando o método de congruências lineares1. Vejamos então como implementar um gerador de números pseudo-aleatórios que gera números inteiros entre 0 e m com uma distribuição uniforme latex2png equation.

A ideia é gerar uma sucessão de números com a forma latex2png equation onde2

latex2png equation

Ao valor de latex2png equation dá-se o nome de semente porque é o primeiro termo da sucessão e é usado como input para o termo seguinte. Note-se que para um mesmo latex2png equation obtém-se sempre o mesmo latex2png equation.

A sucessão de números assim obtida tem período latex2png equation e o intervalo de variação dos valores da sucessão pode ser ajustado ao intervalo latex2png equation através de

latex2png equation

A maneira mais directa é escrever

(defun rand (a c m x)
  (mod (+ (* a x) c) m))
e obtém-se
> (rand 24298 99991 199017 0)

99991

Esta não é a maneira preferível de obter um número aleatório. Queremos obter um número simplesmente fazendo (rand), mas para isso, temos de ter uma maneira de guardar os sucessivos termos da sucessão de modo a que sirvam de sementes para os termos seguintes. Assim vamos definir a variável

(defvar *r-seed* 0)
que inicializa a sucessão de sementes (ou dos próprios números pseudo-aleatórios). Esta é uma variável global e por isso está enquadrada por *. Definimos um substituto para a função anterior como
(defun rand1 ()
  (let ((a 24298)
        (c 99991)
        (m 199017))
    (cond ((<= *r-seed*  199017)
           (setf *r-seed* (mod (+ (* a *r-seed*) c) m)))
          (t
           (setf *r-seed* 0)))))
onde agora os parâmetros a, c e m são locais e estão definidos dentro da função. Assim
> (rand1)

99991

A função rand1 é simples de perceber. Depois de inicializar as quantidades a, c e m verifica se *r-seed* é menor ou igual a 199017, se sim altera o valor de *r-seed* para o novo termo da sucessão através de

(setf *r-seed* (mod (+ (* a *r-seed*) c) m))
se não
(setf *r-seed* 0)

De modo a gerar números aleatórios entre latex2png equation define-se a função

(defun rand (&optional alpha beta)
  (let ((m 199017))
    (cond ((not (and alpha beta))
           (float (/ (rand1) m)))
          (t
           (+ (* (float (/ (rand1) m)) (- beta alpha)) alpha)))))
com dois argumentos opcionais alpha e beta; se não forem dados (rand) gera números com uma distribuição uniforme no intervalo latex2png equation:
> (rand)

0.55237997

> (rand 0 2)

1.1378727

Ref:

1. D. Knuth, TAOCP

2. Master Library da TI Programable 58/59

Etiquetas/Tags: LISP, números pseudo-aleatórios

Dwarf guitar amplifier

... pics

2017/04/18-15:37:35

Found these pics of a guitar amplifier from the 70's, lovely!

Etiquetas/Tags: guitar, amp, amplifier, dwarf, DIY

OpenSCAD mode for emacs

... my hack.

2017/03/01-12:44:47

;;scad.el --- Major mode for editing SCAD files
;;; scad.el --- Major mode for editing SCAD files

;; Original author: Len Trigg <lenbok@gmail.com>
;; Maintainer: This hack is maintained by tca  <tca@diale.org>
;; Created:    20141107
;; Modified:   20141107
;; Keywords:   OpenSCAD, emacs, mode
;; URL:        http://diale.org/scad.el.html
;; Version:    0.1
;; Comments: Added a bunch of skeletons and keymaps.
;;
;; This program 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 2 of the License, or
;; (at your option) any later version.
;; 
;; This program 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 this program; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;
;;; Commentary:
;;
;; This is a major-mode to implement the SCAD constructs and
;; font-locking for openscad
;;; Code:

;;;###autoload

(add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode))

(defcustom scad-command
  '"~/Downloads/openscad-2014.03/local_inst/bin/openscad"
  "Path to openscad executable"
  :type 'string)

(defcustom scad-keywords
  '("return" "true" "false")
  "SCAD keywords."
  :type 'list
  :group 'scad-font-lock)

(defcustom scad-functions
  '("cos" "acos" "sin" "asin" "tan" "atan" "atan2"  
    "abs" "sign" "rands" "min" "max" 
    "round" "ceil" "floor" 
    "pow" "sqrt" "exp" "log" "ln"
    "str" 
    "lookup" "version" "version_num" "len" "search"
    "dxf_dim" "dxf_cross")
    "SCAD functions."
  :type 'list
  :group 'scad-font-lock)

(defcustom scad-modules
  '("child" "children" "echo" "assign" "for" "intersection_for" "if" 
    "else" "cube" "sphere" "cylinder" "polyhedron" "square" "circle" 
    "polygon" "scale" "rotate" "translate" "mirror" "multmatrix" "union"
    "difference" "intersection" "render" "color" "surface" 
    "dxf_linear_extrude" "linear_extrude" "dxf_rotate_extrude" 
    "rotate_extrude" "import_stl" 
    "import_off" "import_dxf" "import" "group" 
    "projection""minkowski" "glide" "subdiv" "hull" "resize")
    "SCAD modules."
  :type 'list
  :group 'scad-font-lock)

(defcustom scad-operators
  '("+" "-" "*" "/" "%" 
    "&&" "||" "!" 
    "<" "<=" "==" "!=" ">" ">="
    "?" ":" "=")
  "SCAD operators."
  :type 'list
  :group 'scad-font-lock)

;; "C-c letter"  are reserved for users

(defvar scad-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\t" 'scad-indent-line)
    (define-key map (kbd "C-c C-v") 'scad-open-current-buffer)
    (define-key map (kbd "C-c C-c") 'scad-output-stl)

    ;; s for solid
    (define-key map (kbd "C-c C-s c") 'scad-cylinder)
    (define-key map (kbd "C-c C-s u") 'scad-cube)
    (define-key map (kbd "C-c C-s y") 'scad-cylinder)
    (define-key map (kbd "C-c C-s p") 'scad-polyhedron)

    ;; b for Boolean
    (define-key map (kbd "C-c C-b u") 'scad-union)
    (define-key map (kbd "C-c C-b d") 'scad-difference)
    (define-key map (kbd "C-c C-b i") 'scad-intersection)

    ;; t for transformations
    (define-key map (kbd "C-c C-t t") 'scad-translate)
    (define-key map (kbd "C-c C-t r") 'scad-rotate)
    (define-key map (kbd "C-c C-t s") 'scad-scale)
    (define-key map (kbd "C-c C-t z") 'scad-resize)
    (define-key map (kbd "C-c C-t m") 'scad-mirror)
    (define-key map (kbd "C-c C-t x") 'scad-multmatrix)
    (define-key map (kbd "C-c C-t c") 'scad-color)
    (define-key map (kbd "C-c C-t h") 'scad-hull)
    (define-key map (kbd "C-c C-t k") 'scad-minkowski)

    ;; s for syntax
    (define-key map (kbd "C-c C-s m") 'scad-module)
    (define-key map (kbd "C-c C-s f") 'scad-function)
    (define-key map (kbd "C-c C-s i") 'scad-include)
    (define-key map (kbd "C-c C-s u") 'scad-use)

    ;; m for math
    ;; Is this really needed;)

    ;; f for functions
    (define-key map (kbd "C-c C-f l") 'scad-lookup)
    (define-key map (kbd "C-c C-f r") 'scad-str)
    (define-key map (kbd "C-c C-f c") 'scad-chr)
    (define-key map (kbd "C-c C-f s") 'scad-search)
    (define-key map (kbd "C-c C-f n") 'scad-version-num)
    (define-key map (kbd "C-c C-f n") 'scad-norm )
    (define-key map (kbd "C-c C-f c") 'scad-cross)
    (define-key map (kbd "C-c C-f m") 'scad-parent-module)

    ;; o for others
    (define-key map (kbd "C-c C-o r") 'scad-render)
    (define-key map (kbd "C-c C-o f") 'scad-for)
    (define-key map (kbd "C-c C-o t") 'scad-intersection-for)
    (define-key map (kbd "C-c C-o i") 'scad-if)
    (define-key map (kbd "C-c C-o a") 'scad-assign)
    (define-key map (kbd "C-c C-o m") 'scad-import)
    (define-key map (kbd "C-c C-o x") 'scad-linear-extrude)
    (define-key map (kbd "C-c C-o o") 'scad-rotate-extrude)
    (define-key map (kbd "C-c C-o s") 'scad-surface)
    (define-key map (kbd "C-c C-o p") 'scad-projection)
    (define-key map (kbd "C-c C-o c") 'scad-children)

    ;; p for on the plane
    (define-key map (kbd "C-c C-p c") 'scad-circle)
    (define-key map (kbd "C-c C-p s") 'scad-square)
    (define-key map (kbd "C-c C-p p") 'scad-polygon)

    (define-key map [return] 'newline-and-indent)
    map)
  "Keymap for `scad-mode'.")

(defvar scad-mode-syntax-table
  (let ((st (make-syntax-table)))
    ;; support comment style: “// ...” 
    ;; support comment style: “/* ... */” 
    (modify-syntax-entry ?\/ ". 124b" st)
    (modify-syntax-entry ?\n "> b" st)
    (modify-syntax-entry ?* ". 23" st)

    ;; Extra punctuation
    (modify-syntax-entry ?+  "." st)
    (modify-syntax-entry ?-  "." st)
    (modify-syntax-entry ?%  "." st)
    (modify-syntax-entry ?<  "." st)
    (modify-syntax-entry ?>  "." st)
    (modify-syntax-entry ?&  "." st)
    (modify-syntax-entry ?:  "." st)
    (modify-syntax-entry ?|  "." st)
    (modify-syntax-entry ?=  "." st)
    (modify-syntax-entry ?\;  "." st)

    ;; _ allowed in word (alternatively "_" as symbol constituent?)
    (modify-syntax-entry ?_  "w" st) st)
  "Syntax table for `scad-mode'.")

(defvar scad-keywords-regexp (regexp-opt scad-keywords 'words))
(defvar scad-modules-regexp (regexp-opt scad-modules 'words))
(defvar scad-functions-regexp (regexp-opt scad-functions 'words))
(defvar scad-operators-regexp (regexp-opt scad-operators))

(defvar scad-font-lock-keywords
  `(
    ("\\(module\\|function\\)[ \t]+\\(\\sw+\\)" (1 'font-lock-keyword-face nil) (2 'font-lock-function-name-face nil t))
    ("\\(use\\|include\\)[ \t]*<\\([^>]+\\)>" (1 'font-lock-preprocessor-face nil) (2 'font-lock-type-face nil t))
    ("<\\(\\sw+\\)>" (1 'font-lock-builtin-face nil))
    ("$\\(\\sw+\\)" (1 'font-lock-builtin-face nil))
    (,scad-keywords-regexp . font-lock-keyword-face)
    (,scad-modules-regexp .  font-lock-builtin-face)
    (,scad-functions-regexp .  font-lock-function-name-face)
    ;(,scad-operators-regexp .  font-lock-operator-face) ;; This actually looks pretty ugly
    ;("\\(\\<\\S +\\>\\)\\s *(" 1 font-lock-function-name-face t) ;; Seems to override other stuff (e.g. in comments and builtins)
    )
  "Keyword highlighting specification for `scad-mode'.")

;(defvar scad-imenu-generic-expression ...)
;(defvar scad-outline-regexp ...)

;;;###autoload
(define-derived-mode scad-mode fundamental-mode "SCAD"
  "A major mode for editing SCAD files."
  :syntax-table scad-mode-syntax-table
  (set (make-local-variable 'font-lock-defaults) '(scad-font-lock-keywords))
  (set (make-local-variable 'indent-line-function) 'scad-indent-line)
                                        ;(set (make-local-variable 'imenu-generic-expression) scad-imenu-generic-expression)
                                        ;(set (make-local-variable 'outline-regexp) scad-outline-regexp)
  ;; set comment styles for scad mode
  (set (make-local-variable 'comment-start) "//")
  (set (make-local-variable 'comment-end) "")
  (set (make-local-variable 'block-comment-start) "/*")
  (set (make-local-variable 'block-comment-end) "*/"))


;; From: http://stackoverflow.com/questions/14520073/add-words-for-dynamic-expansion-to-emacs-mode
(defun scad-prime-dabbrev ()
  "Makes a hidden scad-mode buffer containing all the scad keywords, so dabbrev expansion just works."
  (unless (get-buffer " *scad words*")
    (with-current-buffer (get-buffer-create " *scad words*")
      (scad-mode)
      (insert "module function use include")  ; Explicitly add these -- they're not in the below vars
      (insert (mapconcat 'identity (append scad-keywords scad-functions scad-modules) " ")))))

(add-hook 'scad-mode-hook 'scad-prime-dabbrev)

;;; Indentation, based on http://www.emacswiki.org/emacs/download/actionscript-mode-haas-7.0.el

(defun scad-indent-line ()
  "Indent current line of SCAD code."
  (interactive)
  (let ((savep (> (current-column) (current-indentation)))
        (indent (max (scad-calculate-indentation) 0)))
    (if savep
        (save-excursion (indent-line-to indent))
      (indent-line-to indent))))

(defun scad-calculate-indentation ()
  "Return the column to which the current line should be indented."
  (save-excursion
    (scad-maybe-skip-leading-close-delim)
    (let ((pos (point)))
      (beginning-of-line)
      (if (not (search-backward-regexp "[^\n\t\r ]" 1 0))
          0
        (progn
          (scad-maybe-skip-leading-close-delim)
          (+ (current-indentation) (* standard-indent (scad-count-scope-depth (point) pos))))))))

(defun scad-maybe-skip-leading-close-delim ()
  (beginning-of-line)
  (forward-to-indentation 0)
  (if (looking-at "\\s)")
      (forward-char)
    (beginning-of-line)))

(defun scad-face-at-point (pos)
  "Return face descriptor for char at point."
  (plist-get (text-properties-at pos) 'face))

(defun scad-count-scope-depth (rstart rend)
  "Return difference between open and close scope delimeters."
  (save-excursion
    (goto-char rstart)
    (let ((open-count 0)
          (close-count 0)
          opoint)
      (while (and (< (point) rend)
                  (progn (setq opoint (point))
                         (re-search-forward "\\s)\\|\\s(" rend t)))
        (if (= opoint (point))
            (forward-char 1)
          (cond
           ;; Don't count if in string or comment.
           ((scad-face-at-point (- (point) 1)))
           ((looking-back "\\s)")
            (setq close-count (+ close-count 1)))
           ((looking-back "\\s(")
            (setq open-count (+ open-count 1)))
           )))
      (- open-count close-count))))

(defun scad-open-current-buffer ()
  (interactive)
  (call-process scad-command nil 0 nil (buffer-file-name)))

(defun scad-output-stl ()
  (interactive)
  (async-shell-command (concat  scad-command " -o " (buffer-file-name) ".stl "
                              (buffer-file-name))))

;; Skeleton for easy editing
;; 3D
(define-skeleton scad-sphere
  "Insert sphere."
  "Sphere:"
  "sphere:(" str ");")

(define-skeleton scad-cube
  "Insert cube."
  "Cube:"
  "cube:(" str ");")

(define-skeleton scad-cylinder
  "Insert cylinder."
  "Cylinder:"
  "cylinder(" str ");")

(define-skeleton scad-polyhedron
  "Insert polyhedron."
  "Polyhedron:"
  "polyhedron(" str ");")

;; 2D

(define-skeleton scad-circle
  "Insert square."
  "Square:"
  "square(" str ");")

(define-skeleton scad-square
  "Insert square ."
  "Square:"
  "square(" str ");")

(define-skeleton scad-polygon
  "Insert polygon."
  "Polygon:"
  "Polygon(" str ");")

;; Transformations

(define-skeleton scad-translate
  "Insert translate."
  "translate:"
  "translate(" str "){"_"}")

(define-skeleton scad-rotate
  "Insert rotate."
  "rotate:"
  "rotate(" str "){"_"}")

(define-skeleton scad-scale
  "Insert scale."
  "Scale:"
  "scale(" str "){"_"}")

(define-skeleton scad-resize
  "Insert resize."
  "Resize:"
  "resize(" str "){"_"}")

(define-skeleton scad-mirror
  "Insert mirror."
  "Mirror:"
  "mirror(" str "){"_"}")

(define-skeleton scad-multmatrix
  "Insert multmatrix."
  "Multmatrix:"
  "multmatrix:(" str "){"_"}")

(define-skeleton scad-color
  "Insert color."
  "Color:"
  "color(" str "){"_"}")

(define-skeleton scad-hull
  "Insert hull."
  "Hull:"
  "hull(" str "){"_"}")

(define-skeleton scad-minkowski
  "Insert minkowski."
  "Minkowski:"
  "minkowski(){"_"}")

;; Boolean

(define-skeleton scad-union
  "Insert union."
  "Union:"
  "union(){}")

(define-skeleton scad-difference
  "Insert difference."
  "Difference:"
  "difference(){"_"}")

(define-skeleton scad-intersection
  "Insert intersection."
  "Intersection:"
  "intersection(){"_"}")

;; Syntax

(define-skeleton scad-module
  "Insert module."
  "Module:"
  "module " str "("_"){}")

(define-skeleton scad-function
  "Insert function."
  "Function:"
  "function " str "("_"){}")

(define-skeleton scad-include
  "Insert include."
  "Include:"
  "include <" str ".scad>")

(define-skeleton scad-use
  "Insert use."
  "Use:"
  "use <" str ".scad>")

;; Other

(define-skeleton scad-render
  "Insert render."
  "Render:"
  "render(){"_"}")


(define-skeleton scad-translate
  "Insert translate."
  "translate:"
  "translate(" str "){"_"}")

(define-skeleton scad-rotate
  "Insert rotate."
  "rotate:"
  "rotate(" str "){"_"}")

(define-skeleton scad-scale
  "Insert scale."
  "Scale:"
  "scale(" str "){"_"}")

(define-skeleton scad-resize
  "Insert resize."
  "Resize:"
  "resize(" str "){"_"}")

(define-skeleton scad-mirror
  "Insert mirror."
  "Mirror:"
  "mirror(" str "){"_"}")

(define-skeleton scad-multmatrix
  "Insert multmatrix."
  "Multmatrix:"
  "multmatrix:(" str "){"_"}")

(define-skeleton scad-color
  "Insert color."
  "Color:"
  "color(" str "){"_"}")

(define-skeleton scad-hull
  "Insert hull."
  "Hull:"
  "hull(" str "){"_"}")

(define-skeleton scad-minkowski
  "Insert minkowski."
  "Minkowski:"
  "minkowski(){"_"}")

;; Boolean

(define-skeleton scad-union
  "Insert union."
  "Union:"
  "union(){}")

(define-skeleton scad-difference
  "Insert difference."
  "Difference:"
  "difference(){"_"}")

(define-skeleton scad-intersection
  "Insert intersection."
  "Intersection:"
  "intersection(){"_"}")

;; Syntax

(define-skeleton scad-module
  "Insert module."
  "Module:"
  "module " str "("_"){}")

(define-skeleton scad-function
  "Insert function."
  "Function:"
  "function " str "("_"){}")

(define-skeleton scad-include
  "Insert include."
  "Include:"
  "include <" str ".scad>")

(define-skeleton scad-use
  "Insert use."
  "Use:"
  "use <" str ".scad>")

;; Other

(define-skeleton scad-render
  "Insert render."
  "Render:"
  "render(){"_"}")

(define-skeleton scad-for
  "Insert for."
  "For:"
  "for  (i=" str ")" "{" _ "}")
  

;; (define-skeleton scad-
;;   "Insert ."
;;   ":"
;;   "(" str ");")


(provide 'scad)
;;; scad-mode.el ends here

Enjoy.

Etiquetas/Tags: emacs, openscad

Guitar fuzzbox under 3$

Craig Anderton, Popular Electronics, January 1967

2017/02/10-14:03:34

Etiquetas/Tags: fuzz, guitar, audio

Uma aproximação ou conveniência

... dizer que a ciência é uma aproximação da realidade.

2017/01/23-12:52:54

Dizer que as afirmações da ciência não são a verdade mas a uma aproximação à verdade corresponde a atribuir o mesmo estatuto da ciência a outras actividades intelectuais não científicas tais como religiões, crenças, ideologias etc.

Uma afirmação é verdadeira se está de acordo com os factos que descreve, caso contrário é falsa, não há aproximações.

O facto de o mundo poder ser descrito, bem descrito, por uma certa teoria científica nada diz acerca do mundo ou como ele é realmente, mas diz-nos no entanto alguma coisa sobre ele, i.e., que pode ser bem descrito por essa teoria científica e não outra.

Atribuir à ciência o mero estatuto de uma actividade de produção de afirmações aproximadas à verdade legitima outro tipo de afirmações que, com semelhantes argumentos interiores a elas, podem ser tomadas como afirmações verdadeiras, aproximadas ou não, ou mesmo considerar-se possuir-se a totalidade da verdade num sistema formal imaginado.

Na base da toda a visão moderna do mundo reside a ilusão de que as chamadas de leis da natureza são explicações dos fenómenos naturais. Assim ficamos com a ideia de que as leis da natureza são como coisas inatacáveis, da mesma forma o faziam os antigos com Deus e o Destino. E ambos estão certos e errados. Mas os antigos eram mais claros, reconheciam um fim claro, enquanto o sistema moderno torna-a como se tudo estivesse explicado.

Etiquetas/Tags: ciência, verdade, Wittgenstein

Palavras chave/keywords: página pessoal, blog

Criado/Created: NaN

Última actualização/Last updated: 20-09-2017 [12:06]


GNU/Emacs

1999-2017 (ç) Tiago Charters de Azevedo

São permitidas cópias textuais parciais/integrais em qualquer meio com/sem alterações desde que se mantenha este aviso.

Verbatim copying and redistribution of this entire page are permitted provided this notice is preserved.