#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# [LEAP motion used] Elipse react to hand position (and the physics add on of punktierd)

edited March 2017

The theremin we build using Leap Motion and processing is pretty far, now we are trying to make a visual enhancement accompany the build.

I made the visual part based on a punktierd example called behavior attractor. I basically reversed the process and made it a behavior DEtractor.

Now i'd like to combine the two together. First by adapting the mousx, mousy to righthandx and righthandy. But for some reason it's not working correctly yet using this approach. It might the fault of the code being in the wrong order. Any ideas or suggestions?

Here's the code we are working with (note that both the mouse and hands in leap motion are enabled) (for some reason the forum is not showing the code correctly using the coding raster, so i used the quoting tool but it's still a bit of a mess... excuse me).

import de.voidplus.leapmotion.*; import processing.sound.*; import punktiert.math.Vec; import punktiert.physics.*;

LeapMotion leap; SinOsc sine; Hand leftHand; Hand rightHand;

float freq; float amp; float pos; PVector hL; PVector hR;

int teller = 0; int amount = 100;

// world object VPhysics physics;

// attractor BAttraction attr;

void setup() { size(displayWidth, 700);

leap = new LeapMotion(this); sine = new SinOsc(this);

//Start the Sine Oscillator. sine.play(); sine.amp(amp);

noStroke(); background (#57385c); frameRate (30); smooth();

//set up physics physics = new VPhysics(); physics.setfriction(.4f);

// new AttractionForce: (Vec pos, radius, strength) attr = new BAttraction(new Vec(width * .5f, height * .5f), 400, .01f); physics.addBehavior(attr);

//

void draw() { background(255); smooth();

for (Hand hand : leap.getHands()) { boolean handIsLeft = hand.isLeft(); boolean handIsRight = hand.isRight();

leftHand = leap.getLeftHand(); hL = leftHand.getPosition(); rightHand = leap.getRightHand(); hR = rightHand.getPosition(); //----------------------- LEFT HAND ----------------------------------

``````if (handIsLeft) {
text("leftHand-X=" +hL.x, 10, 15); //shows hL.x in sketch
text("leftHand-Y=" +hL.y, 10, 30); //shows hL.y in sketch
text("leftHand-Z=" +hL.z, 10, 45); //shows hL.z in sketch
text("volume(in %)= " +nf(amp*100, 1, -3), 10, 60);

leftHand.draw();
// Map leftHandY van 0.0 to 1.0 voor amplitude (volume)
amp=map(hL.y, 0, height, 1.0, 0.0);
}

sine.amp(amp);

//----------------------- RIGHT HAND ----------------------------------
if (handIsRight) {
text("rightHand-X= " +hR.x, width-160, 15); //shows hL.x in sketch
text("rightHand-Y= " +hR.y, width-160, 30); //shows hL.y in sketch
text("rightHand-Z= " +hR.z, width-160, 45); //shows hL.z in sketch
text("freq(in Hz)= " +nf(freq, 3, -3), width-160, 60);

rightHand.draw();
// Map rightHandX van 100Hz to 800Hz voor frequency
freq=map(hR.x, 0, width, 100.0, 800.0);
}
if (!handIsLeft && handIsRight) {
amp = 0;
}
sine.freq(freq);
``````

} physics.update();

noFill(); stroke(200, 0, 0); // set pos to mousePosition attr.setAttractor(new Vec(hR.x, hR.y)); //ellipse(attr.getAttractor().x, attr.getAttractor().y, attr.getRadius(), attr.getRadius());

noStroke(); fill(0, 125);

teller = 0; for (VParticle p : physics.particles) { println(teller);

``````if (teller == 0) {
p.set(mouseX, mouseY);
ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
teller++;
}
if (teller == 1);
{
ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
}
``````

} }

• I have been playing with the Leap Motion for the last couple of days ever since I discovered the "Leap Motion for Processing" library.

The biggest problem that you have is that sometimes the Leap Motion library does not immediately provide data. To demonstrate this I modified example sketch "LM_1_Basics". It can take up to 99 msecs for the Leap Motion to connect, that's a really long time from the sketches point of view.

In your original code you were assuming the the right-hand's position data was available from the very first iteration of the draw(). Unfortunately, initially it isn't, I modified your code to illustrate this problem:

``````import de.voidplus.leapmotion.*;
import processing.sound.*;
import punktiert.math.Vec;
import punktiert.physics.*;

LeapMotion leap;
SinOsc sine;
Hand leftHand;
Hand rightHand;

float freq;
float amp;
float pos;
PVector hL;
PVector hR;

int teller = 0;
int amount = 100;

// world object
VPhysics physics;

// attractor
BAttraction attr;

void setup() {
//size(displayWidth, 700);
size(1280, 720); // HD 720P

leap = new LeapMotion(this);
sine = new SinOsc(this);

//Start the Sine Oscillator.
sine.play();
sine.amp(amp);

noStroke();
background(#57385c);
//frameRate(30);
smooth();

//set up physics
physics = new VPhysics();
physics.setfriction(0.4f);

// new AttractionForce: (Vec pos, radius, strength)
attr = new BAttraction(new Vec(width * .5f, height * .5f), 400, .01f);
//
// val for arbitrary radius
// vector for position
// create particle (Vec pos, mass, radius)
VParticle particle = new VParticle(pos, 9, rad);
// add Collision Behavior
// add particle to world

for (int i = 1; i < amount; i++) {
// val for arbitrary radius
float rad2 = random(2, 20);
// vector for position
// create particle (Vec pos, mass, radius)
VParticle particle2 = new VParticle(pos2, 8, rad2);
// add Collision Behavior
// add particle to world
}
}

void draw() {
background(255);
smooth();

for (Hand hand : leap.getHands()) {
boolean handIsLeft = hand.isLeft();
boolean handIsRight = hand.isRight();

leftHand = leap.getLeftHand();
hL = leftHand.getPosition();
if (hL == null) println("No LH data!");

rightHand = leap.getRightHand();
hR = rightHand.getPosition();
if (hR == null) println("No RH data!");

//----------------------- LEFT HAND ----------------------------------
if (handIsLeft) {
text("leftHand-X=" + hL.x, 10, 15); //shows hL.x in sketch
text("leftHand-Y=" + hL.y, 10, 30); //shows hL.y in sketch
text("leftHand-Z=" + hL.z, 10, 45); //shows hL.z in sketch
text("volume(in %)= " + nf(amp*100, 1, -3), 10, 60);

leftHand.draw();
// Map leftHandY van 0.0 to 1.0 voor amplitude (volume)
amp = map(hL.y, 0, height, 1.0, 0.0);
}

sine.amp(amp);

//----------------------- RIGHT HAND ----------------------------------
if (handIsRight) {
text("rightHand-X= " + hR.x, width-160, 15); // shows hL.x in sketch
text("rightHand-Y= " + hR.y, width-160, 30); // shows hL.y in sketch
text("rightHand-Z= " + hR.z, width-160, 45); // shows hL.z in sketch
text("freq(in Hz)= " + nf(freq, 3, -3), width-160, 60);

rightHand.draw();
// Map rightHandX van 100Hz to 800Hz voor frequency
freq = map(hR.x, 0, width, 100.0, 800.0);
}

if (!handIsLeft && handIsRight) {
amp = 0;
}

sine.freq(freq);
} // end for - hand

physics.update();

noFill();
stroke(200, 0, 0);

// set pos to mousePosition
Vec mousePos;

// Deal with right-hand position not yet ready?
// Note: The Leap Motion can take a fraction of a second to start providing data and
//       this code is outside the "for (Hand hand : leap.getHands())" for-loop ;-)
if (hR == null) {
println("hR is null!");
mousePos = new Vec(mouseX, mouseY); // Added by Niels
} else {
println("hand x,y = " + hR.x + "," + hR.y);
mousePos = new Vec(hR.x, hR.y); // Added by Niels
}

attr.setAttractor(mousePos);

noStroke();
fill(0, 125);

teller = 0;
for (VParticle p : physics.particles) {
//println("teller= " + teller);

if (teller == 0) {
p.set(mouseX, mouseY);
ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
teller++;
}

if (teller == 1); {
ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
}
} // end for - p
}
``````

With no call to frameRate() specified Processing will call draw() as quickly as it can. When I run the modified sketch I see the following in the console window:

```# Leap Motion Library v2.3.1.6 - Leap Motion SDK v2.3.1+31549 - https://github.com/nok/leap-motion-processing hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! translate(), or this particular variation of it, is not available with this renderer. hand x,y = 647.9134,592.4121 hand x,y = 786.3234,530.3577 hand x,y = 767.5345,525.84015 hand x,y = 745.8991,519.5922```

So you see you need to handle the situation where you don't immediately get data from the Leap Motion.