如何更改 mousePress() 上单行的颜色

How to change the color of a single line on mousePress()

我有一小段原型代码。

我试图让它在 mousePressed() 或 mouseClicked() 上被点击的行的颜色会改变。

我这辈子都想不通!

如有任何帮助,我们将不胜感激!

我到目前为止设法编写的代码如下,它应该可以正常工作。

int value = 0;
ArrayList<Line> l = new ArrayList<Line>();

void setup() {
   size(500,500);
   background(57, 76, 222);
   //noLoop();
   stroke(255);
   strokeWeight(3);
}

void draw() {
    for (int i = 1; i< 20; i++) {
        l.add(new Line());   
        for (int a=0; a< l.size(); a++){
            l.get(a).display();
            noLoop();
        }
    }
    int total = l.size();
    println("The total number of lines is: " + total);
}


class Line {
    int ranX1, ranX2, ranY1, ranY2;

    Line() {
        ranX1 = int(random(50,450));
        ranX2 = int(random(50,450));
        ranY1 = int(random(50,450));
        ranY2 = int(random(50,450));
    }

    void update() {
        //
    }

    void display() {
        line(ranX1,ranX2,ranY1,ranY2);
    }
}

如果你有一条线,由一个点 (O) 和一个方向 (D) 给出,那么这条线上最近的点,到点 p 可以计算如下

X = O + D * dot(P-O, D);

2 个向量的点积等于 2 个向量之间夹角的余弦乘以两个向量的大小(长度)。

dot( A, B ) == | A | * | B | * cos( alpha ) 

VD的点积等于直线(O,D)和向量[=24=之间夹角的余弦值],乘以V的数量(长度),因为D是一个unit vectorD的长度是1.0)。

使用PVector to get the direction from (ranX1, ranY1) to (ranX2, ranY2) and make the direction vector to an unit vector by .normalize(). The length of the vector is verified by .mag():

PVector D = new PVector(ranX2 - ranX1, ranY2 - ranY1);
if ( D.mag() > 0.0 )
    D.normalize();

用上面的算法计算到一条无限直线的法线距离,其中0点(ranX1,ranY1)和(ranX2,ranY2)是在。为此,使用方法 .mult(), .add(), .dist() and .dot()

PVector X = new PVector(ranX1, ranY1);
X.add( D.mult( D.dot( vP1 ) ) );
boolean hit = X.dist(new PVector(x, y)) < hit_dist;

用点积验证通过an点(x,y)的直线与法线的交点(X)是否在( ranX1ranY1) 和 (ranX2ranY2)。如果两个亚麻布之间的角度大于 90 度或小于 -90 度,则点积小于 0.0:

PVector vP1 = new PVector(x - ranX1, y - ranY1);
if ( D.dot( vP1 ) < 0.0 )
    hit = false;

PVector vP2 = new PVector(x - ranX2, y - ranY2);
if ( D.dot( vP2 ) > 0.0 )
    hit = false;

在classLine中添加方法isHit,检查输入位置(xy)是否在线。可以通过 hit_dist 设置识别线上点击的可接受准确度。如果必须准确命中该行,请减小此值。增加它以允许在旁边但靠近线的地方击中。添加一个颜色属性col和一个可以改变颜色的方法:

class Line {

    // [...]

    color col;

    // [...]

    void setColor(color c) {
        col = c;
    }

    boolean isHit(int x, int y) {

        final int hit_dist = 5;

        // [...]

        return hit;
    }
}

使用鼠标按下事件mousePressed()循环遍历所有行。鼠标按下时改变每条线的颜色为2hit":

void mousePressed() {

    for (int i = 0; i < l.size(); ++i) {

        if (l.get(i).isHit(mouseX, mouseY)) {
            l.get(i).setColor(color(255, 0, 0) );
        }
    } 
}

查看示例,它实现了算法并对您的代码做了一些进一步的改进和错误修复:

int value = 0;
ArrayList<Line> l = new ArrayList<Line>();

void setup() {
    size(500,500);

   for (int i = 0; i < 20; ++i) {
       l.add(new Line());  
   }
}

void draw() {

    background(57, 76, 222);

    strokeWeight(3);
    for (int i = 0; i < l.size(); ++i) {
       l.get(i).display();
    }
}

void mousePressed() {

    for (int i = 0; i < l.size(); ++i) {

        if (l.get(i).isHit(mouseX, mouseY)) {
            l.get(i).setColor(color(255, 0, 0) );
        }
    } 
}

class Line {
    int ranX1, ranX2, ranY1, ranY2;
    color col;

    Line() {
        col = color(255);
        ranX1 = int(random(50,450));
        ranX2 = int(random(50,450));
        ranY1 = int(random(50,450));
        ranY2 = int(random(50,450));
    }

    void setColor(color c) {
        col = c;
    }

    boolean isHit(int x, int y) {

        final int hit_dist = 5;

        PVector D = new PVector(ranX2 - ranX1, ranY2 - ranY1);
        if ( D.mag() > 0.0 )
            D.normalize();

        PVector vP1 = new PVector(x - ranX1, y - ranY1);
        if ( D.dot( vP1 ) < 0.0 )
            return false;

        PVector vP2 = new PVector(x - ranX2, y - ranY2);
        if ( D.dot( vP2 ) > 0.0 )
            return false;

        PVector X = new PVector(ranX1, ranY1);
        X.add( D.mult( D.dot( vP1 ) ) );
        boolean hit = X.dist(new PVector(x, y)) < hit_dist; 

        return hit;
    }

    void display() {
        stroke(col);
        line(ranX1, ranY1, ranX2, ranY2);
    }
}