Find y coordinate of point on line (given x)

Hi, I have this code which compiles but does not work as expected. I’ve translated it from some javascript I’ve found around and I’m trying to figure out where the issue is.
Basically it should be fairly simple.
There’s a list of straight lines. Given a x value (hardcoded) I want to find the corresponding Y value on one of the existing line. Assumin lines are consecutives and there is only 1 line going across 1 x point.
In the example I’m trying to do the calculation and to draw 2 lines (red/blu) which should cross on the white line at the right (x,y) coordinates. But it does not seem to work.
Can anyone take a look and help me spot the issue? Thanks!

Here’s the full code

void setup(){
  size(400,400);
  background(5);
  smooth();
}
void draw(){

  LineCollection lines = new LineCollection();

  lines.addLine(new StraightLineSegment(0,50, 100,80)); //start X, start Y, end X, endY
  lines.addLine(new StraightLineSegment(100,80, 200,120));
  lines.display();
  
  // our give x. change to test
  float x = 153;
  
  //lines.normalise(10);
  
  fill(255,0,0);
  stroke(255,0,0);
  strokeWeight(1);
  line(x, 0, x, height); //red
  stroke(0,0,255);
  line(0, lines.getYAtX(x), width, lines.getYAtX(x)); //blue
  stroke(0,255,0);
  //line(0, lines.getYAtX(9.1), width, lines.getYAtX(9.1)); //green (static line only for test)
  println(lines.getYAtX(x));
  println("m: " + mouseX + " - " + mouseY);

}
class LineCollection {
  
  private ArrayList <StraightLineSegment> lines;
  private float totalWidth;
  
  LineCollection() {
    this.lines = new ArrayList <StraightLineSegment>();
    this.totalWidth = 0;
  }
  
  public void display(){
  stroke(255);
  strokeWeight(1);
  for(StraightLineSegment l : this.lines)
    line(l.startX, l.startY, l.endX, l.endY);
  }

  /**
   * It is expected that this line's x starts where the previous line's x ends
  **/
  public void addLine(StraightLineSegment line) {
    StraightLineSegment lastLine;
    if(this.lines.size() != 0) {
      lastLine = this.lines.get(this.lines.size() - 1);

      // Note comparing doubles with == isn't the best idea
      // It may break when the same doubles are derived differently
      if(lastLine.endX != line.startX) {
        throw new Error("Line does not begin where last line ends");
      }
    }

    this.lines.add(line);
    this.totalWidth += line.getWidth(); //??
  }

  public float getStartX() {
    if(this.lines.size() == 0) return -1111;
    else return this.lines.get(0).startX;
  }

  public float getStartY() {
    if(this.lines.size() == 0) return -2222;
    else return this.lines.get(0).startY;
  }

  public float getEndX() {
    if(this.lines.size() == 0) return -3333;
    else return this.lines.get(this.lines.size() - 1).endX;
  }

  public float getEndY() {
    if(this.lines.size() == 0) return -4444;
    else return this.lines.get(this.lines.size() - 1).endY;
  }

  // Assumes only one value of y for each value of x
  public float getYAtX(float x) {
    //println("END: " + this.getEndX());
    if(x < this.getStartX() || x > this.getEndX()) return -5555;

    // Find the right line and return it.getYAtX(x)
    float sumX = this.getStartX();

    for(StraightLineSegment line : this.lines) {
      sumX += line.getWidth();

      if(sumX >= x) {
        return line.getYAtX(x);
      }
    }

    throw new Error("How did we get here?");
  }

  public void normalise(float newTotalWidth) {
    if(newTotalWidth == 0.0) newTotalWidth = 1;
    float scale = newTotalWidth / this.totalWidth;

    for(StraightLineSegment line : this.lines) {
      line.reScale(scale, 1);
    }

    this.totalWidth = newTotalWidth;
  }
}
class StraightLineSegment {

  private float startX;
  private float startY;
  private float endX;
  private float endY;
  
  public StraightLineSegment(float startX, float startY, float endX, float endY) {
    this.startX = startX;
    this.startY = startY;
    this.endX = endX;
    this.endY = endY;
  }

  public float getYAtX(float x) {
    if(x < this.startX || x > this.endX) return -1000;
    return this.startY + (this.endY - this.startY) * (this.endX - x) / width;
  }

  public void reScale(float x, float y) {
    this.startX *= x;
    this.endX *= x;
    this.startY *= y;
    this.endY *= y;
  }

  public float getWidth() {
    return this.endX - this.startX;
  }
}
1 Like

any math-guy out there? :smiley:

http://mathworld.wolfram.com/Two-PointForm.html

void setup() {
  size(400, 400);
}

float find_y(float x, float x1, float y1, float x2, float y2) {
  return( (((y2-y1)/(x2-x1))*(x-x1))+y1 );
}

void draw() {
  background(0);
  float x1 = random(0, 200);
  float y1 = random(0, 200);
  float x2 = random(200, 400);
  float y2 = random(200, 400);

  float x = 200;
  float y = find_y( x, x1, y1, x2, y2 );

  translate(0, height);
  scale(1, -1);
  stroke(200, 0, 0);
  line(x1, y1, x2, y2);
  stroke(200);
  line(x, 0, x, height);
  noFill();
  stroke(0, 200, 0);
  ellipse(x, y, 5, 5);
  noLoop();
}

void mousePressed(){
  loop();
}
1 Like