2

I have very little experience with coding and for my University Project Prototype, I need to code an image (a PImage in Processing) to move using my hands (Leap Motion Controller Input).

At the moment I am stuck on how to get my image to move using the position of my hand, but the error pops up saying that the image can only use floats as inputs since the position of the hand is calculated using the PVector class. I tried to use float[] (name) = handpos.array(); to make it a float value but then I can't get the x and y value from the position needed for the image.

Here is the code I have done so far, in the for loop, was where I was planning on adding the image to appear.

import de.voidplus.leapmotion.*;

LeapMotion leap;

//Assets
PImage hand;
//Colours
color ocean = color(50,113,250);

void setup(){
  size(700, 700);
  background(255);
  leap = new LeapMotion(this);
  hand = loadImage("images/hand.png");
  imageMode(CENTER);
}

void draw() {
background (ocean);
int fps = leap.getFrameRate();
  for (Hand hand : leap.getHands ()) {
    Finger index = hand.getIndexFinger();
    PVector hpos = hand.getPosition(); 
    PVector ipos = index.getPosition(); 
}
 
}
codeogeek
  • 652
  • 1
  • 8
  • 22
Sophie
  • 21
  • 1

2 Answers2

2

Dietrich's answer is correct (+1).

There are a couple of caveats. The error you're getting (expects parameters like: "image(PImage, float, float)") is due to variable shadowing

You're probably trying to render the hand image inside the for loop, however, the loop uses a local variable with the same name (hand) which in this case is a LeapMotion Hand instance, not a PImage.

The for loop variable (Hand instance) is shadowing the global variable(PImage variable).

The error happens because it attempts to render a LeapMotion Hand instead of your PImage.

You could simply rename the local variable:

import de.voidplus.leapmotion.*;

LeapMotion leap;

//Assets
PImage hand;
//Colours
color ocean = color(50, 113, 250);

void setup() {
  size(700, 700);
  background(255);
  leap = new LeapMotion(this);
  hand = loadImage("images/hand.png");
  imageMode(CENTER);
}

void draw() {
  background (ocean);
  int fps = leap.getFrameRate();
  for (Hand leapHand : leap.getHands ()) {
    Finger index = leapHand.getIndexFinger();
    PVector hpos = leapHand.getPosition(); 
    PVector ipos = index.getPosition();
    image(hand, hpos.x, hpos.y);
  }
}

This would render multiple images per hand.

If you want to render a single image for a single hand you could do multiple things.

You could extract the position out of the loop which means the most recent hand will control the image position:

import de.voidplus.leapmotion.*;

LeapMotion leap;

//Assets
PImage hand;
//Colours
color ocean = color(50, 113, 250);

PVector handPosition = new PVector();

void setup() {
  size(700, 700);
  background(255);
  leap = new LeapMotion(this);
  hand = loadImage("images/hand.png");
  imageMode(CENTER);
}

void draw() {
  background (ocean);
  int fps = leap.getFrameRate();
  // hand inside is the loop is a Leap Hand instance, shadowing the PImage
  for (Hand hand : leap.getHands ()) {
    Finger index = hand.getIndexFinger();
    PVector hpos = hand.getPosition(); 
    PVector ipos = index.getPosition();
    handPosition.set(hand.getPosition());
  }
  // hand here is your PImage
  image(hand, handPosition.x, handPosition.y);
  
}

or you could use the first hand for example:

import de.voidplus.leapmotion.*;

LeapMotion leap;

//Assets
PImage hand;
//Colours
color ocean = color(50, 113, 250);

PVector handPosition = new PVector();

void setup() {
  size(700, 700);
  background(255);
  leap = new LeapMotion(this);
  hand = loadImage("images/hand.png");
  imageMode(CENTER);
}

void draw() {
  background (ocean);
  int fps = leap.getFrameRate();
  // try to read first hand data
  Hand firstHand = leap.getHand(0);
  // check if there is actual data (at least one hand is present)
  if(firstHand != null){
    // read hand's position
    PVector handPosition = hand.getPosition();
    // render image to hand's position
    image(hand, handPosition.x, handPosition.y);
  }
  
}

There are many ways of doing this, it depends on what makes sense for your project's user experience.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
1

If I understand your problem correctly, you can do it like this:

image(hand, hpos.x, hpos.y)
Dietrich
  • 681
  • 5
  • 18
  • I tried that first, but the error: The function "image()" expects parameters like: "image(PImage, float, float)" appears. – Sophie Oct 07 '20 at 07:46