Faz qualquer coisa...

Este é um blog de geral de matemática, física, electrónica, áudio, LISP, Arduino, impressão 3D, etc, ... Já tem uns anitos :)

As entrada antigas estão arquivadas de uma forma não linear.

Happy hacking!

RSS

[Valid RSS]


How to add a delay control to a pen plotter running grbl
A simple hack to add a delay after a servo move...

2022/04/13-21:41:13

grbl is a wonderful piece of software. One of the issues that lacks solution is the delay control when, instead of using the typical CNC spindle, one uses a servo to control a pen plotter. Here's a simple hack: download grbl, look for the gcode.c file and locate the following part:

// [4. Set spindle speed ]:
  if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) {
    if (gc_state.modal.spindle != SPINDLE_DISABLE) { 
      #ifdef VARIABLE_SPINDLE
        if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_ISMOTION)) {
          if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) {
             spindle_sync(gc_state.modal.spindle, 0.0);
          } else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); }
        }
      #else
        spindle_sync(gc_state.modal.spindle, 0.0);
      #endif
    }
    gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state.
  }

add the following line mc_dwell(0.2); (see below).

// [4. Set spindle speed ]:
  if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) {
    if (gc_state.modal.spindle != SPINDLE_DISABLE) { 
      #ifdef VARIABLE_SPINDLE
        if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_ISMOTION)) {
          if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) {
             spindle_sync(gc_state.modal.spindle, 0.0);
          } else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); }
        }
      #else
        spindle_sync(gc_state.modal.spindle, 0.0);
      #endif
    }
    gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state.

    mc_dwell(0.2); // add this line to set delay for servo motion (in mseconds !?)
  }

Compile the code and upload it. That's it.

Happy hacking!

P.S.

I'm using this spindle_control.c. Servo is controlled by M3 Sx where x takes the values 0-255.

Etiquetas/Tags: grbl, plotter, servo, delay, arduino


Planner and look-ahead code from different firmware
Controlling speed is an important factor which determines the quality of computer generated motion profiles.

2022/02/09-14:22:38

3 examples.

From Teacup

 /**
   * What we want is (for each axis):
   *
   *   delta velocity = dv = |v1 - v2| < max_jerk
   *
   * In case this isn't satisfied, we can slow down by some factor x until
   * the equitation is satisfied:
   *
   *   x * |v1 - v2| < max_jerk
   *
   * Now computation is pretty straightforward:
   *
   *        max_jerk
   *   x = -----------
   *        |v1 - v2|
   *
   *   if x > 1: continue full speed
   *   if x < 1: v = v_max * x
   *
   * See also: https://github.com/Traumflug/Teacup_Firmware/issues/45
   */

From Marlin

/**
 * planner.cpp
 *
 * Buffer movement commands and manage the acceleration profile plan
 *
 * Derived from Grbl
 * Copyright (c) 2009-2011 Simen Svale Skogsrud
 *
 * The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis.
 *
 *
 * Reasoning behind the mathematics in this module (in the key of 'Mathematica'):
 *
 * s == speed, a == acceleration, t == time, d == distance
 *
 * Basic definitions:
 *   Speed[s_, a_, t_] := s + (a*t)
 *   Travel[s_, a_, t_] := Integrate[Speed[s, a, t], t]
 *
 * Distance to reach a specific speed with a constant acceleration:
 *   Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t]
 *   d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance()
 *
 * Speed after a given distance of travel with constant acceleration:
 *   Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t]
 *   m -> Sqrt[2 a d + s^2]
 *
 * DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2]
 *
 * When to start braking (di) to reach a specified destination speed (s2) after accelerating
 * from initial speed s1 without ever stopping at a plateau:
 *   Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di]
 *   di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance()
 *
 * IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a)
 *
 * --
 *
 * The fast inverse function needed for Bézier interpolation for AVR
 * was designed, written and tested by Eduardo José Tagle on April/2018
 */

From grbl

/*                            PLANNER SPEED DEFINITION
                                     +--------+   <- current->nominal_speed
                                    /          \
         current->entry_speed ->   +            \
                                   |             + <- next->entry_speed (aka exit speed)
                                   +-------------+
                                       time -->
  Recalculates the motion plan according to the following basic guidelines:
    1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
        (i.e. current->entry_speed) such that:
      a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
         neighboring blocks.
      b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
         with a maximum allowable deceleration over the block travel distance.
      c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
    2. Go over every block in chronological (forward) order and dial down junction speed values if
      a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
         acceleration over the block travel distance.
  When these stages are complete, the planner will have maximized the velocity profiles throughout the all
  of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
  other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
  are possible. If a new block is added to the buffer, the plan is recomputed according to the said
  guidelines for a new optimal plan.
  To increase computational efficiency of these guidelines, a set of planner block pointers have been
  created to indicate stop-compute points for when the planner guidelines cannot logically make any further
  changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
  planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
  bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
  added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
  them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
  point) are all accelerating, they are all optimal and can not be altered by a new block added to the
  planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
  junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
  used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
  recomputed as stated in the general guidelines.
  Planner buffer index mapping:
  - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
  - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
      the buffer is full or empty. As described for standard ring buffers, this block is always empty.
  - next_buffer_head: Points to next planner buffer block after the buffer head block. When equal to the
      buffer tail, this indicates the buffer is full.
  - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
      streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
      planner buffer that don't change with the addition of a new block, as describe above. In addition,
      this block can never be less than block_buffer_tail and will always be pushed forward and maintain
      this requirement when encountered by the plan_discard_current_block() routine during a cycle.
  NOTE: Since the planner only computes on what's in the planner buffer, some motions with lots of short
  line segments, like G2/3 arcs or complex curves, may seem to move slow. This is because there simply isn't
  enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and then
  decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this happens and
  becomes an annoyance, there are a few simple solutions: (1) Maximize the machine acceleration. The planner
  will be able to compute higher velocity profiles within the same combined distance. (2) Maximize line
  motion(s) distance per block to a desired tolerance. The more combined distance the planner has to use,
  the faster it can go. (3) Maximize the planner buffer size. This also will increase the combined distance
  for the planner to compute over. It also increases the number of computations the planner has to perform
  to compute an optimal plan, so select carefully. The Arduino 328p memory is already maxed out, but future
  ARM versions should have enough memory and speed for look-ahead blocks numbering up to a hundred or more.
*/

Etiquetas/Tags: CNC, Marlin, grbl, Teacup, 3d print, 3D, 3D printing


Ball vertical strip vase
... with a vertical line patter do trick your brain and hide the layer lines.

2021/12/06-10:10:02

Inspired by Bubble pencil holder here's an OpenSCAD version. Enjoy!

// Author: Tiago Charters de Azevedo 
// Maintainer: Tiago Charters de Azevedo 

// Copyright (c) - 2021 Tiago Charters de Azevedo

// 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 3, 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; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301, USA.

//Notes:
// Based on: https://www.prusaprinters.org/prints/86837-bubble-pencil-holder

$fn= $preview ? 16 : 32;

n=10;
m=5;
h=1.2;
eps=1;

rball=10;
rvase=30;

spacing=.75*rball;
lvase=m*rball+(m-1)*spacing;

echo("Height:");
echo(lvase);
echo("Radius:");
echo(rvase);

module balls(l=30,r=rball,theta=.25*360/(n-1),spacing=spacing){
    for(j=[0:m-2]){
        for(i=[0:n-2]){
            rotate([0,0,i*360/(n-1)+pow(-1,j)*theta])
            translate([rvase-.1*rball,0,(r+spacing)*j+r+spacing/2])
            sphere(r=r);}}}

module verts(r=rvase,l=lvase,hh=1.2){
    N=1.25*PI*rvase/hh;
    for(i=[0:N]){
        rotate([0,0,i*360/N])
        translate([rvase-h,0,lvase/2])
        cube([3*rball,hh,lvase+eps],center=true);}}


module cylinder1(r=rvase,l=lvase,h=h){
    translate([0,0,l/2])
    difference(){
        cylinder(h=l,r=r,center=true);
        translate([0,0,h])
        cylinder(h=l+eps,r=r-h,center=true);}}

module vase1(hollow=false){
    if (hollow==true){
        //balls
        difference(){
            balls(r=rball);
            cylinder(h=lvase,r=rvase-h);}
        // cylinder
        difference(){
            cylinder1(r=rvase,l=lvase,h=h);
            balls(r=rball);
        }}
    else{
        balls(r=rball);
        cylinder(r=rvase,h=lvase);}}

module vasesolid(){
        vasescale=(rvase-h)/rvase;
        union(){
            scale(vasescale*[1,1,1/vasescale])
            vase1(hollow=false);
            intersection(){
                vase1(hollow=false);
                verts();}}}

module vase(hollow=false){
    vasescale=(rvase-h)/rvase;
    if (hollow==false){
        vasesolid();}
    else{
        difference(){
            vasesolid();
            translate([0,0,lvase/2+h])
            cylinder(h=lvase+eps,r=rvase-2*h,center=true);
             for(j=[0:m-2])
            {
                for(i=[0:n-2])
                {
                    rotate([0,0,i*360/(n-1)+pow(-1,j)*.25*360/(n-1)])
                    translate([rvase-.1*rball,0,(rball+spacing)*j+rball+spacing/2])
                    sphere(r=rball-2*h);}}
            translate([0,0,2*h])
            cylinder(h=lvase,r=rvase-2*h);
            }
    }}




//show
vase(hollow=false);

Etiquetas/Tags: 3dprint, vase, openscad, opensource


Trippy vase
... in OpenSCAD

2021/11/29-16:15:08

Spiral it!

step=$preview ? 1 : 1;    

phi=(1+sqrt(5))/2;

function surf(theta,z,height,R)=R*(1+sin(phi*90*z/height))*(1+.25*(cos(1*360*z/height)+.5*sin(10*theta+sqrt(2)*360*z/height)+.5*sin(5*theta-sqrt(3)*360*z/height)));

eps=.1;
h=1.2;
module vase(height=100,sides=360,R=30,top=true,bottom=true){
    points=[
        for(z=[0:step:height])
        for(theta=[0:sides-1])
        let(r=surf(theta,z,height,R),
            x=r*cos(theta),
            y=r*sin(theta))    
        [x,y,z]];
    
    faces=concat(
        [
            // Triangle #1
            for(z=[0:(height-1)/step])
            for(s=[0:sides-1])
            let(// clockwise from left-down corner
                f1=s+sides*z,
                f2=s+sides*(z+1),
                f3=((s+1)%sides)+sides*(z+1),
                f4=((s+1)%sides)+sides*z)
            [f1,f2,f3]],
        [
            // Triangle #2
            for(z=[0:(height-1) / step])
            for(s=[0:sides-1])
            let(// clockwise from left-down corner
                f1=s+sides*z,
                f2=s+sides*(z+1),
                f3=((s+1)%sides)+sides*(z+1),
                f4=((s+1)%sides)+sides*z)
            [f3,f4,f1]],

        [if (bottom==true) [for(s=[0:sides-1]) s]],  //bottom;          

        [if (top==true) [for(s=[sides-1:-1:0]) (height/step)*(sides)+s]] //top        
    );   
    
    polyhedron(points=points, faces=faces);
}

vase(height=180,sides=360,R=30,top=true,bottom=true);

Etiquetas/Tags: 3dprint, openscad, stl, math, Fourier


Vaso 3D
... obtido por rotação em torno de um eixo

2021/11/15-17:58:02

A visualização tridimensional é um ingrediente importante na comunicação e estudo da matemática. Figuras e modelos expressam ideias e antecipam o estabelecimento de um formalismo matemático mais rigoroso. Embora a imaginação visual não substitua o conceito de demonstração dá-nos uma prova visual convincente e permite construir uma intuição sobre os resultados a perseguir e ideias a aprofundar.

A figura seguinte mostra a modelação 3D de uma "jarra" construída através da rotação em torno de um eixo.

Ao contrário do que acontece com outros tipos de software, os softwares usados em matemática permitem de uma forma muito económica a modelação e construção de estruturas não triviais, especificando simplesmente a expressão que as definem.

phi=(1+sqrt(5))/2;

n=100;

r=40;
l=152;
mu=3;
mv=2;
a=.25;
b=a/phi;
lambda=1.5;

nu=.2;
[u,v]=meshgrid([linspace(0,2*pi,n) 2*pi/n],linspace(0,l,n));
 
x=r*cos(u).*abs(cos(u)).^nu.*(1+a*cos(mu*u+mv*pi*v/l).^5+b*cos(mv*2*pi*v/l));
y=r*sin(u).*abs(sin(u)).^nu.*(1+a*cos(mu*u+mv*phi*pi*v/l).^5+b*cos(mv*2*pi*v/l));
z=v;

simplef2stl("vase.stl",x,y,z)

Depois de impresso o resultado é muito apelativo!

... e não é uma curva.

Função para gerar STL em GNU/Octave

## Author: Tiago Charters de Azevedo 
## Maintainer: Tiago Charters de Azevedo 

## Copyright (c) - 2016 Tiago Charters de Azevedo

## 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 3, 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; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor,
## Boston, MA 02110-1301, USA.

function simplef2stl(filename,x,y,z)
  fid=fopen(filename,'w');
  title_str=sprintf('%s',datestr(now));
  fprintf(fid,'solid %s\r\n',title_str);

  zmin=min(min(z));
  z=z-zmin;
  nfacets=0;
  nx=size(z,1);
  ny=size(z,2);
  for i=1:nx-1;
    for j=1:ny-1
      p1=[x(i,j) y(i,j) z(i,j)];
      p2=[x(i,j+1) y(i,j+1) z(i,j+1)];
      p3=[x(i+1,j+1) y(i+1,j+1) z(i+1,j+1)];
      writefacet(fid,p1,p2,p3);

      p1=[x(i+1,j+1) y(i+1,j+1) z(i+1,j+1)];
      p2=[x(i+1,j) y(i+1,j) z(i+1,j)];
      p3=[x(i,j) y(i,j) z(i,j)];        
      writefacet(fid,p1,p2,p3);
    end
  end
  fprintf(fid,'endsolid');
  fclose(fid);
end  
  
function num=writefacet(fid,p1,p2,p3)
    n=normal(p1,p2,p3);
    fprintf(fid,'facet normal %.7E %.7E %.7E\r\n',n(1),n(2),n(3));
    fprintf(fid,'outer loop\r\n');        
    fprintf(fid,'vertex %.7E %.7E %.7E\r\n',p1);
    fprintf(fid,'vertex %.7E %.7E %.7E\r\n',p2);
    fprintf(fid,'vertex %.7E %.7E %.7E\r\n',p3);
    fprintf(fid,'endloop\r\n');
    fprintf(fid,'endfacet\r\n');
end

function n=normal(p1,p2,p3)
  v1=p2-p1;
  v2=p3-p1;
  v3=cross(v1,v2);
  n=v3./sumsq(v3);
end

Etiquetas/Tags: 3d, print, reprap, GNU/Octave, STL


Proposta para o Laboratório de Cidadãos
para a Rede de Bibliotecas de Lisboa

2021/10/28-11:47:08

Proposta para o Laboratório de Cidadãos "Peças de Jardim"

Título do seu projeto

Mesa de musgo para leitura

Motivação

A construção de uma mesa de musgo com um candeeiro LED alimentado com baterias BPV (Biological Photo Voltaic cells) concretiza numa mesma ideia a reutilização de madeira ou mobiliário, geração renovável de energia elétrica através de um processo natural de crescimento das plantas, a fotossíntese, a geração local de energia de fontes renováveis e a sua utilização num local de atividade humana. Permitirá criar um local de leitura onde a iluminação é gerada por um processo natural e que pode ser implementada no interior da biblioteca ou no exterior do edifício. Permite também a replicação da mesma estrutura em locais diferentes para o qual foi projetado e.g. em nossas casas ou escolas.

Engloba competências de fabrico artesanal com madeira, o design colaborativo e partilhado, trabalho em equipa na construção e recolha de materiais, e disciplinas científicas como a biologia, a química e a física. Permite enquadrar o fabrico e conhecimento teórico-prático em todos os níveis de ensino e para todas as idades. No fundo uma forma válida de divulgação científica e participação em ciência feita por cidadãos.

Toda a documentação produzida será libertada segundo uma licença Creative Commons cc-by-sa de modo catalisar a produção e réplicas em outros locais.

Breve descrição do projeto

Pretende-se reaproveitar e reutilizar uma mesa, ou fabricá-la com madeira reciclada, de modo a que contenha um conjunto significativo de baterias BPV (Biological Photo voltaic cells) de modo a acender um candeeiro de mesa providenciando uma fonte de luz a quem sobre ela trabalha ou lê. Estas baterias, que estão no início do seu desenvolvimento mas têm o potencial de produzir eletricidade para alimentar pequenos aparelhos elétricos tais como relógios ou LEDs, podem ser construídas localmente com materiais facilmente acessíveis . As BPV podem ter uma vantagem competitiva numa pequena escala relativamente às renováveis usuais (https://www.cam.ac.uk/research/news/the-hidden-power-of-moss).

A vantagem das BPV está na sua capacidade de armazenar energia através de um processo natural que ocorre à nossa volta: a fotossíntese. Para além de usar a energia do sol para converter o dióxido de carbono em compostos orgânicos, que as plantas usam para crescer, a fotossíntese que ocorre nos musgos liberta compostos orgânicos no solo que são por sua vez digeridos por bactérias libertando nesse processo eletrões que podem ser capturados e armazenados para alimentar pequeno eletrodomésticos (https://royalsocietypublishing.org/doi/full/10.1098/rsos.160249).

Estas baterias, que na realidade são, ao olho não treinado, apenas plantas num vaso, serão acomodadas na estrutura das mesas integrando-as como parte funcional da estrutura e podem ser usadas no interior ou exterior dos edifícios.

Espera-se que a utilização desta estrutura tenha impacto na perceção nas diferentes possibilidade na utilização das plantas na geração limpa de energia elétrica, na manutenção e equilíbrio necessário entre a utilização dos ecossistemas onde as pessoas são parte integrante.

Porque todo o conhecimento necessário para a construção da mesa de musgo é aberto e está acessível online é fácil reproduzir a sua construção em outros locais através de projetos na escola, em casa ou juntas de freguesia. Este projeto tem também o objetivo de produzir um manual de construção, sob uma licença de direitos de autor aberta Creative Commons cc-by-sa, que ficará disponível para consulta e distribuição junto da mesa.

Recursos necessários para o desenvolvimento do projeto

Para este projeto serão necessárias ferramentas usuais que podem ser encontradas em qualquer oficina de reparação de móveis ou nas ferramentas de um qualquer entusiasta de DIY; mesas, ou madeira para reaproveitamento que as permita fabricar.

Para as baterias BPV serão necessários: musgo que poderá ser apanhado localmente e.g. no próprio jardim; folha de alumínio usada em culinária; feltro de carbono; e pó de zeolite (usado em cosméticos), ver método de construção (https://www.instructables.com/Indoor-Moss-Microbial-Fuel-Cell/). O candeeiro será construido com LED.

Um conjunto de 3 a 4 pessoas serão necessárias para construção de cada uma das mesas de musgo.

Os detalhes específicos de design serão decididos durante a construção pelos elementos que a fabricarão adaptado ao espaço e local, à função e aos possíveis utilizadores da estrutura.

Outras informações relevantes

Etiquetas/Tags: musgo, diy, cidadãos, mesa, energia, BPV


Comprei um Filastruder
Para reciclar plástico e produzir filamento para impressão 3D

2021/10/10-16:20:46

Comprei-o em segunda mão, um filastruder, versão 1.6.

Dizem-me que não será fácil usá-lo para produzir filamento para impressão 3D usando plástico reciclado, que o plástico triturado é irregular, pouco homogéneo e que se já é difícil usar pellets para produzir filamento então pedacinhos de plástico ainda pior!

A ver vamos!

As primeiras experiências correram bem. Se não vejamos: com pellets ABS temos 1.62mm

Os dois rolos ABS (branco) e PLA (preto) não têm tolerâncias muito longe disto.

Mas podemos melhorar!

Etiquetas/Tags: impressão 3D, filamento, filastruder


Interpolação fractal
Alguns exemplos de interpolação fractal e códigos em Octave

2021/10/10-15:48:09

A interpolação fractal consiste em construir uma função contínua que passa por um conjunto de pontos e cujo o gráfico é uma curva fractal. A construção desta curva fractal é feita recorrendo a um sistema de funções iteradas (SFI) que de seguida se define como um conjunto de funções afins.

Chama-se sistema de funções iteradas a um conjunto de aplicações afins latex2png equation , , onde latex2png equation é uma matriz latex2png equation com entradas reais e latex2png equation um vector coluna com entradas reais, com factor de contracção latex2png equation , latex2png equation. A contracção máxima deste conjunto de aplicações é dado pelo número latex2png equation.

Em geral para se construir o SFI que interpola o conjunto de pontos latex2png equation cujo conjunto invariante latex2png equation é gráfico de uma função contínua interpoladora, considere-se o SFI latex2png equation onde as aplicações latex2png equation são definidas por

De modo a construir as aplicações que definem a função interpoladora é necessário impor-se as condições latex2png equation

Como cada aplicação é determinada pelos valores de latex2png equation e latex2png equation latex2png equation que é um sistema linear sobre-determinado nos coeficientes da aplicação. Escolhe-se latex2png equation como parâmetro livre. A escolha desta quantidade com parâmetro permite pondo latex2png equation recuperar a forma da interpolação linear por troços. Assim tomando latex2png equation como parâmetro livre pode escrever-se cada uma das quantidades latex2png equation e latex2png equation em termos dos dados e de latex2png equation

latex2png equation

Ao parâmetro latex2png equation dá-se o nome de factor de escala.

A figura seguinte mostra exemplos de várias funções interpoladoras para alguns pontos sobre o gráfico da função seno para vários valores do factor contracção máxima (ver topo de cada gráfico, o vector d tem todas as componentes iguais a esse valor de contracção máximo em cada gráfico)

O código em GNU/Octave que permite gerar os pontos da função interpoladora fractal é

function [px py]=interpfrac(x,y,d,npoints)
  n=length(x);
  b=x(n)-x(1);

  for i=2:n
    aw(i-1)=(x(i)-x(i-1))/b;
    ew(i-1)=(x(n)*x(i-1)-x(1)*x(i))/b;
    cw(i-1)=(y(i)-y(i-1)-d(i)*(y(n)-y(1)))/b;
    fw(i-1)=(x(n)*y(i-1)-x(1)*y(i)-d(i)*(x(n)*y(1)-x(1)*y(n)))/b;
  endfor

  oldx=0;
  oldy=0;
  px=oldx;
  py=oldy;
  for j=1:npoints
    k=floor((n-1)*rand)+1;
    newx=aw(k)*oldx+ew(k);
    newy=cw(k)*oldx+d(k)*oldy+fw(k);
    oldx=newx;
    oldy=newy;
    px=[px; newx];
    py=[py; newy];
  endfor
endfunction
e para se obter os gráficos usa-se
x=[0:.5:2*pi];
y=sin(x);
t=[0:.01:2*pi];

clf
hold on

s=[.1:.1:.9];
for i=1:9
  d=s(i)*ones(1,length(x));
  subplot(3,3,i)
  hold on

  [xx, yy]=interpfrac(x,y,d,10000);
  plot(xx,yy,'.')
  plot(x,y,'ok')
  plot(t,sin(t),'r--')
  xlabel('x')
  ylabel('y')
  title(sprintf('s=%f',s(i)));
endfor;

Os gráficos seguintes mostram que variações se obtêm variando as diferentes entradas do vector d de uma forma aleatória num intervalo latex2png equation.

As instruções para os obter são

x=[0:.5:2*pi];
y=sin(x);
t=[0:.01:2*pi];

clf
hold on

for i=1:9
  d=.7*rand(1,length(x));
  subplot(3,3,i)
  hold on

  [xx, yy]=interpfrac(x,y,d,10000);
  plot(xx,yy,'.')
  plot(x,y,'ok')
  plot(t,sin(t),'r--')
  xlabel('x')
  ylabel('y')
endfor;

Etiquetas/Tags: fractal, interpolação, matemática, octave


2021/08/22-17:28:29

Etiquetas/Tags:


Raytracing
... with povray

2021/03/03-11:16:08

Some examples in povray and further reading.

global_settings{ 
   ambient_light rgb<1,1,1>
   
   photons{ count 100000
     media 10
     autostop 0
     jitter .4
   }
}
light_source {<0,10,5>,1}

camera{location <30,30,5> 
  right x*image_width/image_height look_at 0}


cylinder{<0,0,0>,<0,10,0>,2
  pigment{ color rgbf <1,1,1,1> } 
  finish{
    reflection .1
    ior 1.2
    phong 0}
 photons { target reflection on } 
  photons {
    target
    refraction on
    reflection on
    collect off
  }
}
 
plane{y,0
  pigment{
    color rgb <.3,.3,.3>
     }
  finish{ 
    diffuse .7
    reflection 0}
 }

global_settings{ 
   ambient_light rgb<1,1,1>
   photons{ count 100000
     media 10
     autostop 0
     jitter .4
   }
 }

light_source {<0,7,5>,.5
}

camera{location <30,30,5> 
  right x*image_width/image_height look_at 0}

sphere{<-1,3,1>,5
  pigment{ color rgbf <1,1,1,1> } 
  finish{
    reflection .1
    ior 1.2
    phong 0}
 photons { target reflection on } 
  photons {
    target
    refraction on
    reflection on
    collect off
  }
}

plane{y,-2.5
  pigment{
    color rgb <.3,.3,.3>
     }
  finish{ 
    diffuse .7
    reflection 0}
 }

Etiquetas/Tags: povray, raytracing


Palavras chave/keywords: página pessoal, blog

Criado/Created: NaN

Última actualização/Last updated: 13-04-2022 [21:41]


Voltar à página inicial.


GNU/Emacs Creative Commons License

(c) Tiago Charters de Azevedo