dimarts, 31 de maig del 2022

Matriu de m x n a una matriu de dues columnes on la primera és recursiva (resultat a partir de la columna 36 o AJ)

Sub taula()

Dim CantFila As Long
Dim CantCol As Long
Dim c As Single, f As Single, M As Single
M = 1

CantFila = Cells(Rows.Count, 1).End(xlUp).Row
CantCol = Cells(1, Columns.Count).End(xlToLeft).Column

    
For c = 2 To CantCol Step 1
    For f = 2 To CantFila Step 1

        Cells(M, 31).Value = Cells(f, 1).Value
        Cells(M, 32).Value = Cells(1, c).Value
        Cells(M, 33).Value = Cells(f, c).Value
        M = M + 1

    Next f
Next c

End Sub


diumenge, 1 de maig del 2022

Shape detection (square, equilateral triangle and circle)

Three shapes are going to be recognised through a formula that manages the square, the triangle or the circle itself over a relative area to its circumscribed circle.

Then, 

  • if the result of substraction is 36%, the original area is a square
  • if the area resulting is a 58% then the shape is an equilateral triangle
  • Finally, if all the area is substracted and results 0%, the shape is the circle itself.  
See below the details on formulae: 





In addition to this, it is required to define the center from three points at least. Thus, we determine the center. This point is called centroid. The algorith to get
 is https://stackoverflow.com/questions/4103405/what-is-the-algorithm-for-finding-the-center-of-a-circle-from-three-points

From an image, where blue color has been scanned, we can get min and max from x scan and just min from y scan. 
Although we already know which the area should be, we need determining three points at least.

Let's make a revision on PVector in Processing. Once more, Schiffman teaches us how to do it.



dimarts, 19 d’abril del 2022

Processing envia RGB (123) a Arduino

Per part de processing

import processing.video.*;
Capture video;
import processing.serial.*; 
Serial myPort; 

float TotalPixelsBlaus=0;
float TotalPixelsVermells=0; 
float TotalPixelsVerds=0; 
int comptadorReset=0;
int EstatAra=0;
int EstatAnt=0;
String EstatAraStr;

void setup() {
  size(640, 480);
  String[] cameras = Capture.list();
  printArray(cameras);
  video = new Capture(this, cameras[1]);
  video.start();
  
  printArray(Serial.list()); 
  //myPort = new Serial(this, Serial.list()[0], 9600); 
    myPort = new Serial(this, "COM6", 9600); //determinem el port pel qual envia informació a l'Arduino
}

void draw() {
      if (video.available() == true) {
        video.read();  
      }
image(video, 0, 0);

float pB=TotalPixelsBlaus/(TotalPixelsBlaus+TotalPixelsVermells+TotalPixelsVerds)*100;
float pR=TotalPixelsVermells/(TotalPixelsBlaus+TotalPixelsVermells+TotalPixelsVerds)*20;//el Vermell predomina, millor que 100
float pG=TotalPixelsVerds/(TotalPixelsBlaus+TotalPixelsVermells+TotalPixelsVerds)*100;
String pRstr = nf(pR, 0, 2); // convertim a dos decimals
String pGstr = nf(pG, 0, 2);
String pBstr = nf(pB, 0, 2);
println(pRstr,pGstr,pBstr);  // imprimim dos decimals

if      (pR>pB && pR>pG){EstatAra=1; println("envio Vermell");}
else if (pG>pR && pG>pB){EstatAra=2; println("envio Verd");}
else {                   EstatAra=3; println("envio Blau");}


if (comptadorReset>100){
  TotalPixelsBlaus=0; TotalPixelsVermells=0; TotalPixelsVerds=0; comptadorReset=0;}
else {comptadorReset+=1;}

for (int x = 0; x < video.width; x++ ) {
    for (int y = 0; y < video.height; y++ ) {
      int loc = x + y * video.width;
      color currentColor = video.pixels[loc];
      float r = red(currentColor); float g = green(currentColor);float b = blue(currentColor);
      if      (r>b && r>g) {TotalPixelsVermells+=1;}
      else if (g>r && g>b) {TotalPixelsVerds+=1;}
      else                 {TotalPixelsBlaus+=1;}
    }
}
  
if (EstatAra!=EstatAnt && comptadorReset>80){
  String EstatAraStr=str(EstatAra);
      myPort.write(EstatAraStr);
            println("he enviat pel serie",EstatAraStr);
     delay(2000); //temps per poder llegir el missatge per la consola
      EstatAnt=EstatAra;
}  
}

dilluns, 18 d’abril del 2022

Blob Tracking in Processing by Daniel Shiffman (link to the video included)

// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/1scFcY-xMrI

import processing.video.*;

Capture video;

color trackColor; 
float threshold = 25;
float distThreshold = 50;

ArrayList<Blob> blobs = new ArrayList<Blob>();

void setup() {
  size(640, 480);
  String[] cameras = Capture.list();
  printArray(cameras);
  video = new Capture(this, cameras[1]);
  video.start();

  trackColor = color(152, 48, 56);
}

void captureEvent(Capture video) {
  video.read();
}


void keyPressed() {
  if (key == 'a') {
    distThreshold+=5;
  } else if (key == 'z') {
    distThreshold-=5;
  }
  if (key == 'w') {
      trackColor = color(255, 0, 0);
  }
  
  if (key == 's') {
    threshold+=5;
  } else if (key == 'x') {
    threshold-=5;
  }

  println(distThreshold);
}

void draw() {
  video.loadPixels();
  image(video, 0, 0);


  blobs.clear();


  // Begin loop to walk through every pixel
  for (int x = 0; x < video.width; x++ ) {
    for (int y = 0; y < video.height; y++ ) {
      int loc = x + y * video.width;
      // What is current color
      color currentColor = video.pixels[loc];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
      float r2 = red(trackColor);
      float g2 = green(trackColor);
      float b2 = blue(trackColor);

      float d = distSq(r1, g1, b1, r2, g2, b2); 

      if (d < threshold*threshold) {

        boolean found = false;
        for (Blob b : blobs) {
          if (b.isNear(x, y)) {
            b.add(x, y);
            found = true;
            break;
          }
        }

        if (!found) {
          Blob b = new Blob(x, y);
          blobs.add(b);
        }
      }
    }
  }

  for (Blob b : blobs) {
    if (b.size() > 500) {
      b.show();
    }
  }

  textAlign(RIGHT);
  fill(0);
  text("distance threshold: " + distThreshold, width-10, 25);
  text("color threshold: " + threshold, width-10, 50);
}


// Custom distance functions w/ no square root for optimization
float distSq(float x1, float y1, float x2, float y2) {
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
  return d;
}


float distSq(float x1, float y1, float z1, float x2, float y2, float z2) {
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) +(z2-z1)*(z2-z1);
  return d;
}

void mousePressed() {
  // Save color where the mouse is clicked in trackColor variable
  int loc = mouseX + mouseY*video.width;
  trackColor = video.pixels[loc];
}


In an separate tab called Blob (the Blob object)...

// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/1scFcY-xMrI

class Blob {
  float minx;
  float miny;
  float maxx;
  float maxy;

  ArrayList<PVector> points;

  Blob(float x, float y) {
    minx = x;
    miny = y;
    maxx = x;
    maxy = y;
    points = new ArrayList<PVector>();
    points.add(new PVector(x, y));
  }

  void show() {
    stroke(0);
    fill(255);
    strokeWeight(2);
    rectMode(CORNERS);
    rect(minx, miny, maxx, maxy);

    for (PVector v : points) {
      stroke(0, 0, 255);
      point(v.x, v.y);
    }
  }

  void add(float x, float y) {
    points.add(new PVector(x, y));
    minx = min(minx, x);
    miny = min(miny, y);
    maxx = max(maxx, x);
    maxy = max(maxy, y);
  }

  float size() {
    return (maxx-minx)*(maxy-miny);
  }

  boolean isNear(float x, float y) {
    float d = 10000000;
    for (PVector v : points) {
      float tempD = distSq(x, y, v.x, v.y);
      if (tempD < d) {
        d = tempD;
      }
    }

    if (d < distThreshold*distThreshold) {
      return true;
    } else {
      return false;
    }
  }
}

dijous, 24 de març del 2022

dimecres, 23 de març del 2022

Cam lever simulator

 Cam lever simulator

https://www.stonybrook.edu/commcms/motiongen/how-to-use.php

http://cadcam.eng.sunysb.edu/

Wow!