Problem with 3D Code (LeapMotion / Arduino / Mesh)

edited May 2016 in Arduino

Hi, I´m making a project in my University using a LEapMotion and Arduino to make 3D models with the movement of my hand, like a pipe or a tube guide by my hand. The problem is that for some reason (I still not finding the problem) the code always draw mesh from the current point of my hand to the first point of the model. I´m adding some photos to show how it looks and I´m also adding the code for the review.

I´ll ve more than happy if someone can spot the error and help me with that.

140808_131656 140808_162530

This is the mainClass

/* 
Folkwang Universität der Künste
Dramaturgie des Zwischenraums
Prof. Claudius Lazzeroni

Student. Jose Chavarría
*/

//-----------------------------------------------------------//
// Librarys
import processing.serial.*;
import cc.arduino.*;

import processing.opengl.*;
import java.util.Calendar;

import com.onformative.leap.*;
import com.leapmotion.leap.*;
import nervoussystem.obj.*;

import toxi.geom.*;

//-----------------------------------------------------------//
// Global Variables

Arduino arduino;

LeapMotionP5 leap;

Mesh myMesh;

int sensorA = 0;
int sensorB = 1;
int resolution = 125;
int cantPoints = 0;
ArrayList<Point> pointList;
boolean record = false;
boolean mySwitch = true;
int rotX, rotY;

ArrayList<CirclePoints> circlesList;

boolean rotation = false;


void setup() {
  size(displayWidth,displayHeight,OPENGL);

  // setup drawing style 
  background(255);
  noStroke();
  fill(0);

  circlesList = new ArrayList<CirclePoints>();
  arduino = new Arduino(this, Arduino.list()[0], 57600);

  frameRate(25);
  leap = new LeapMotionP5(this);
  pointList = new ArrayList<Point>();
  rotateZ(radians(90));
}

void draw(){

  background(255);
  lightSpecular(230, 230, 230); 
  directionalLight(200, 200, 200, -0.0, -0.0, 1); 
  directionalLight(200, 200, 200, 0.0, 0.0, -1); 
  specular(color(150)); 
  shininess(5.0);
  lights();  

  rotX = int(map(arduino.analogRead(sensorA),0,1023,-20,20));
  rotY = int(map(arduino.analogRead(sensorB),0,1023,-90,90));

  scale(0.5,0.5,0.5);
  translate(width/2,height/5);
  rotateX(radians(rotX));
  rotateY(radians(rotY));


  if (record) {    
    beginRecord("nervoussystem.obj.OBJExport", timestamp()+".obj"); 
  }  

  for (Hand hand : leap.getHandList()) {
    PVector handPosition = leap.getPosition(hand);
    Vec3D nHandPosition = new Vec3D(handPosition.x, handPosition.y, handPosition.z);
    float handSize = leap.getSphereRadius(hand);
    setSpline(nHandPosition, handSize/5);
  }
  myMesh = new Mesh(circlesList);
  myMesh.draw();
  if (record) {
    endRecord();
    record = false;
    saveFrame(timestamp()+".png");
  }
}


void setSpline(Vec3D position, float radious){
  Point newPoint = new Point(position, radious);
  pointList.add(newPoint);
  int numPoints = pointList.size();
  if (numPoints > 1){
    for (int index = 1; index <= numPoints-1; index ++){
      Point actPoint = pointList.get(index);
      Vec3D actPosition = actPoint.pos;
      float actRad = actPoint.rad;
      Point prevPoint = pointList.get(index - 1);
      Vec3D prevPosition = prevPoint.pos;
      CirclePoints circle = new CirclePoints(prevPosition, actPosition, actRad, mySwitch);

      circlesList.add(circle);

      mySwitch = circle.mySwitch;
    }
  }
}


void mousePressed() {
  if (mouseButton == LEFT) {
    record = true;
  } 
}

String timestamp() {
  return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", Calendar.getInstance());
}

And in there he make for every point detected by the LeapMotion a circle with this class:

class CirclePoints{
  //-----------------------------------------------------------//
  // Global Variables

  Vec3D[] circle;
  float frac = 0.2;
  int sides = 10;
  boolean mySwitch;

  //-----------------------------------------------------------//
  // Constructor

  CirclePoints(Vec3D refPoint, Vec3D point, float rad, boolean nSwitch){
    Vec3D direction = point.sub(refPoint);
    direction.normalize();
    Vec3D delta = point.sub(refPoint).scale(frac);
    Vec3D perp = perpendicular(direction).scale(rad);
    mySwitch = nSwitch;

    float deltaAng = TWO_PI/float(sides);

    circle = new Vec3D[sides + 1];

    for(int index = 0; index < sides+1; index++){
      if (mySwitch){
        circle[index] = new Vec3D(point.x + delta.x + perp.x, point.y + delta.y + perp.y, point.z + delta.z + perp.z);
      }
      else{
        circle[index] = new Vec3D(point.x - delta.x + perp.x, point.y - delta.y + perp.y, point.z - delta.z + perp.z);
      }
      perp.rotateAroundAxis(direction, deltaAng);
    }
    if (mySwitch){
      mySwitch = false;
    }
    else{
      mySwitch = true;
    }
  }

  Vec3D perpendicular(Vec3D point){
    Vec3D perp = new Vec3D();
    if(point.x != 0 && point.y != 0 && point.z != 0){
      perp.set(1, -point.x / point.y, 0);
      perp.normalize();
    }
    else if(point.x == 0){
      perp.set(1, 0, 0);
    }
    else if(point.y == 0){
      perp.set(0, 1, 0);
    }
    else if(point.z == 0){
      perp.set(0, 0, 1);
    }
    return perp;
  }
}

And finally he draw all the mesh by connecting the points with this class:

class Mesh{  
  //-----------------------------------------------------------//
  // Global Variables

  ArrayList<CirclePoints> circlesList;

  //-----------------------------------------------------------//
  // Constructor

  Mesh(ArrayList<CirclePoints> nCirclesList) {
    circlesList = nCirclesList;     
  }

  void draw(){
    noStroke();
    fill(#831010);
    for(int pos = 0; pos < (circlesList.size() - 1); pos++){
      CirclePoints circle = circlesList.get(pos);
      CirclePoints nextCircle = circlesList.get(pos+1);
      Vec3D[] circle1 = circle.circle;
      Vec3D[] circle2 = nextCircle.circle;      
      for(int index = 0; index < (circle1.length-1); index++){
        beginShape(QUADS);
        vertex(circle1[index].x, circle1[index].y, circle1[index].z); 
        vertex(circle1[index+1].x, circle1[index+1].y, circle1[index+1].z);
        vertex(circle2[index+1].x, circle2[index+1].y, circle2[index+1].z);
        vertex(circle2[index].x, circle2[index].y, circle2[index].z);
        endShape();
      }                
    }
  }
}

I´ll really apreciate any help.

Thanks

Tagged:

Answers

  • Answer ✓

    What a mess... can you repost with md or code view?

  • Answer ✓

    repost

    /* Folkwang Universität der Künste Dramaturgie des Zwischenraums Prof. Claudius Lazzeroni
    
     Student. Jose Chavarría */
    
    //-----------------------------------------------------------// // Librarys import processing.serial.*; import cc.arduino.*;
    
    import processing.opengl.*; 
    import java.util.Calendar;
    
    import com.onformative.leap.*; 
    import com.leapmotion.leap.*; 
    import nervoussystem.obj.*;
    
    import toxi.geom.*;
    
    //-----------------------------------------------------------// // Global Variables
    
    Arduino arduino;
    
    LeapMotionP5 leap;
    
    Mesh myMesh;
    
    int sensorA = 0; 
    int sensorB = 1; 
    int resolution = 125; 
    int cantPoints = 0; 
    ArrayList pointList; 
    boolean record = false; 
    boolean mySwitch = true; 
    int rotX, rotY;
    
    ArrayList circlesList;
    
    boolean rotation = false;
    
    void setup() { 
      size(displayWidth, displayHeight, OPENGL);
    
      // setup drawing style 
      background(255); 
      noStroke(); 
      fill(0);
    
      circlesList = new ArrayList(); 
      arduino = new Arduino(this, Arduino.list()[0], 57600);
    
      frameRate(25); 
      leap = new LeapMotionP5(this); 
      pointList = new ArrayList(); 
      rotateZ(radians(90));
    }
    
    void draw() {
    
      background(255); 
      lightSpecular(230, 230, 230); 
      directionalLight(200, 200, 200, -0.0, -0.0, 1); 
      directionalLight(200, 200, 200, 0.0, 0.0, -1); 
      specular(color(150)); 
      shininess(5.0); 
      lights();
    
      rotX = int(map(arduino.analogRead(sensorA), 0, 1023, -20, 20)); 
      rotY = int(map(arduino.analogRead(sensorB), 0, 1023, -90, 90));
    
      scale(0.5, 0.5, 0.5); 
      translate(width/2, height/5); 
      rotateX(radians(rotX)); 
      rotateY(radians(rotY));
    
      if (record) {
        beginRecord("nervoussystem.obj.OBJExport", 
        timestamp()
          +".obj");
      }
    
      for (Hand hand : leap.getHandList()) { 
        PVector handPosition = leap.getPosition(hand); 
        Vec3D nHandPosition = new Vec3D(handPosition.x, handPosition.y, handPosition.z); 
        float handSize = leap.getSphereRadius(hand); 
        setSpline(nHandPosition, handSize/5);
      } 
      myMesh = new Mesh(circlesList); 
      myMesh.draw(); 
      if (record) { 
        endRecord(); 
        record = false; 
        saveFrame(timestamp()+".png");
      }
    }
    
    void setSpline(Vec3D position, float radious) { 
      Point newPoint = new Point(position, radious); 
      pointList.add(newPoint); 
      int numPoints = pointList.size(); 
      if (numPoints > 1) { 
        for (int index = 1; index <= numPoints-1; index ++) { 
          Point actPoint = pointList.get(index); 
          Vec3D actPosition = actPoint.pos; 
          float actRad = actPoint.rad; 
          Point prevPoint = pointList.get(index - 1); 
          Vec3D prevPosition = prevPoint.pos; 
          CirclePoints circle = new CirclePoints(prevPosition, actPosition, actRad, mySwitch);
    
          circlesList.add(circle);
    
          mySwitch = circle.mySwitch;
        }
      }
    }
    
    void mousePressed() { 
      if (mouseButton == LEFT) { 
        record = true;
      }
    }
    
    String timestamp() { 
      return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", Calendar.getInstance());
    }
    
    // And in there he make for every point detected by the LeapMotion a circle with this class:
    
    class CirclePoints { 
      //-----------------------------------------------------------// // Global Variables
    
        Vec3D[] circle; 
      float frac = 0.2; 
      int sides = 10; 
      boolean mySwitch;
    
      //-----------------------------------------------------------// // Constructor
    
      CirclePoints(Vec3D refPoint, Vec3D point, float rad, boolean nSwitch) { 
        Vec3D direction = point.sub(refPoint); 
        direction.normalize(); 
        Vec3D delta = point.sub(refPoint).scale(frac); 
        Vec3D perp = perpendicular(direction).scale(rad); 
        mySwitch = nSwitch;
    
    
        float deltaAng = TWO_PI/float(sides);
    
        circle = new Vec3D[sides + 1];
    
        for (int index = 0; index < sides+1; index++) {
          if (mySwitch) {
            circle[index] = new Vec3D(point.x + delta.x + perp.x, point.y + delta.y + perp.y, point.z + delta.z + perp.z);
          }
          else {
            circle[index] = new Vec3D(point.x - delta.x + perp.x, point.y - delta.y + perp.y, point.z - delta.z + perp.z);
          }
          perp.rotateAroundAxis(direction, deltaAng);
        }
        if (mySwitch) {
          mySwitch = false;
        }
        else {
          mySwitch = true;
        }
      }
    
      Vec3D perpendicular(Vec3D point) { 
        Vec3D perp = new Vec3D(); 
        if (point.x != 0 && point.y != 0 && point.z != 0) { 
          perp.set(1, -point.x / point.y, 0); 
          perp.normalize();
        } 
        else if (point.x == 0) { 
          perp.set(1, 0, 0);
        } 
        else if (point.y == 0) { 
          perp.set(0, 1, 0);
        } 
        else if (point.z == 0) { 
          perp.set(0, 0, 1);
        } 
        return perp;
      }
    }
    
    // And finally he draw all the mesh by connecting the points with this class:
    
    class Mesh {
      //-----------------------------------------------------------// // Global Variables
    
      ArrayList circlesList;
    
      //-----------------------------------------------------------// // Constructor
    
      Mesh(ArrayList nCirclesList) { 
        circlesList = nCirclesList;
      }
    
      void draw() { 
        noStroke(); 
        fill(#831010); 
        for (int pos = 0; pos < (circlesList.size() - 1); pos++) { 
          CirclePoints circle = circlesList.get(pos); 
          CirclePoints nextCircle = circlesList.get(pos+1); 
          Vec3D[] circle1 = circle.circle; 
          Vec3D[] circle2 = nextCircle.circle;
          for (int index = 0; index < (circle1.length-1); index++) { 
            beginShape(QUADS); 
            vertex(circle1[index].x, circle1[index].y, circle1[index].z); 
            vertex(circle1[index+1].x, circle1[index+1].y, circle1[index+1].z); 
            vertex(circle2[index+1].x, circle2[index+1].y, circle2[index+1].z); 
            vertex(circle2[index].x, circle2[index].y, circle2[index].z); 
            endShape();
          }
        }
      }
    }
    
  • Answer ✓

    See To newcomers in this forum: read attentively these instructions for hints about choosing a category and formatting code. I did that for you this time.

  • yes sorry, i´m new and i didn´t knew how to do it, thanks Chrisir

  • don't click Accept when the problem isn't solved....

  • The problem is that for some reason (I still not finding the problem) the code always draw mesh from the current point of my hand to the first point of the model.

    ok, so now we know what it's doing wrong, but you haven't told us what you want it to do. which makes it hard.

    also, the use of arduino and leapmotion makes it difficult for us without those to help. we can't run your code to see what it does, we have to go on your description. see point 1.

    can you explain what you want, maybe with a modified picture?

    it might be as simple a fix as drawing the mesh (lines 84-90?) BEFORE adding the current hand position to it (lines 78-83?). would also help if you commented your blocks with a line saying what they do.

Sign In or Register to comment.