Multi-touch gear for navigation

Hello to everyone,

I’m a student and not very expert in coding but I’m trying to experiment with touchscreens using the smartphone’s screen as prototype, using conductive objects as interactive gears.

I’d like to put on the screen a three-point of contact object, where each point is positioned as if they where on each of an isosceles triangle’s vertices.
When I rotate the tool, something should happen, like scrolling a page or something.

Now, as a first step I think I should define an orientation, that’s why I thought of an isosceles triangle (acute), so I need to find the apex.

I think I should calculate the sides to find the longer, so I thought about calculating point distances.
Should I calculate the major sides, confronting each distances?
Am I in the right direction?

The next problem is to keep the apex tracked when rotating the object, to have the orientation and tracking the angle of rotation.
What could I use to track the angle of rotation?

Do you have some clues on the algorithm?

thank you in advance,

Al

Hi.
Maybe this link could be a starting point.
Edit: I forgot to link the reference.
https://android.processing.org/reference/multitouch/touches.html

Thanks I’ve been looking to your example but I don’t know how to fit it to my needs.

Here is the code I’ve written.

import controlP5.*;


double dist1, dist2, dist3;

float XG, YG;

float centreX;
float centreY;
float angle;
float rotation0 = 0;
int lineLength = 1000;
float degree;

int apix;

ControlP5 cp5;
int slider = 100;

void setup() {
  fullScreen();
  orientation(LANDSCAPE);
  textFont(createFont("SansSerif", 24 * displayDensity));
  textAlign(CENTER, CENTER);

  cp5 = new ControlP5(this);
  rotate(PI/2);
  cp5.addSlider("slider").setPosition(100, 400).setRange(0, 360).setSize(1000, 100);
}    

void draw() {
  background(255);

  for (int i = 0; i < touches.length; i++) {
    //diameter
    float d = (70 + 70 * touches[i].area) * displayDensity;

    fill(0, 255 * touches[i].pressure);
    ellipse(touches[i].x, touches[i].y, d, d);

    //ellipse text - touches ID
    fill(255, 0, 0);
    text(touches[i].id, touches[i].x + d/2, touches[i].y - d/2);    

    text("T"+ i + ": " + touches[i].x + ", " + touches[i].y, 500, (100+i*100));

    stroke(0);
    strokeWeight(4);


    if (touches.length == 2) {
      line(touches[0].x, touches[0].y, touches[1].x, touches[1].y);
    }    

    if (touches.length == 3) {
      line(touches[0].x, touches[0].y, touches[1].x, touches[1].y);
      line(touches[0].x, touches[0].y, touches[2].x, touches[2].y);
      line(touches[1].x, touches[1].y, touches[2].x, touches[2].y);

      // distance from points
      dist1 = Math.sqrt(Math.pow((touches[0].x - touches[1].x), 2) + Math.pow((touches[0].y - touches[1].y), 2));
      dist2 = Math.sqrt(Math.pow((touches[0].x - touches[2].x), 2) + Math.pow((touches[0].y - touches[2].y), 2));
      dist3 = Math.sqrt(Math.pow((touches[1].x - touches[2].x), 2) + Math.pow((touches[1].y - touches[2].y), 2));

      // center of mass
      XG = (touches[0].x + touches[1].x + touches[2].x)/3;
      YG = (touches[0].y + touches[1].y + touches[2].y)/3;

      centreX = XG;
      centreY = YG;

      float dx = touches[0].x - centreX;
      float dy = touches[0].y - centreY;
      angle = atan2(dy, dx);
      // calculate the end point
      float newX = centreX + cos(angle) * lineLength;
      float newY = centreY + sin(angle) * lineLength;

      // map to the 0-360 range
      degree = degrees(floorMod(angle + HALF_PI, TWO_PI));

      noFill();
      strokeWeight(6);
      stroke(0);
      line(centreX, centreY, newX, newY);
    }
  }


  fill(255);
  stroke(0);
  strokeWeight(6);
  pushMatrix();
  translate(400, 800);
  rotate(rotation0 + angle);
  triangle(0, -100, 100, 100, -100, 100);
  popMatrix();

  cp5.getController("slider").setValue(degree);
}

static float floorMod(float a, float b) {
  return a - b * floor(a / b);
}

As you can see the problem I need to solve is that this shows the real angle, and of course it changes if you first touch the screen with a different foot of the tripoid.
I instead want a relative difference in degrees, so I want that any time you touch with the tripoid, no matter the foot, the 0 is set at that angle, and then to visualize the angle of which it has been rotated.

Another problem is to “map” the numbers to find the angle especially when the range is exceeded, like when the 0 is set to 300° and I move the tripoid of 200°, so the effective 200° movement will be at the original 140° angle, if you follow me.
What formula can I use to calculate this difference in angle?

thank you for anyone’s help!

Maybe I’m not understanding your question, but if your goal is to always point your “center to top line” to the angle where the longest lines crosses, why dont you pick the midle of the triangle base and calculate from there the angle to the top.
The part of your code below will always take the first toutch in consideration.

float dx = touches[0].x - centreX;
      float dy = touches[0].y - centreY;
      angle = atan2(dy, dx);
      // calculate the end point
      float newX = centreX + cos(angle) * lineLength;
      float newY = centreY + sin(angle) * lineLength;