java - 如何在 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 )
V
和的点积D
等于线 ( O
, D
) 与向量之间的夹角的余弦V = P - O
乘以 的量(长度)V
,因为D
是单位向量(的长度D
为 1.0)。
用于PVector
获取从 ( ranX1
, ranY1
) 到 ( ranX2
, ranY2
) 的方向,并将方向向量通过 转化为单位向量.normalize()
。向量的长度由 验证.mag()
:
PVector D = new PVector(ranX2 - ranX1, ranY2 - ranY1);
if ( D.mag() > 0.0 )
D.normalize();
使用上述算法计算到一条无限线的法线距离,其中点 ( ranX1
, ranY1
) 和 ( ranX2
, ranY2
) 位于其中。为此,使用方法.mult()
、和:.add()
.dist()
.dot()
PVector X = new PVector(ranX1, ranY1);
X.add( D.mult( D.dot( vP1 ) ) );
boolean hit = X.dist(new PVector(x, y)) < hit_dist;
使用点积验证X
直线与法线的交点 ( x
)y
是否在 ( ranX1
, ranY1
) 和 ( ranX2
, ranY2
) 之间。如果两条亚麻布之间的角度大于 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;
isHit
向类添加一个方法,该方法Line
检查输入位置 ( x
, y
) 是否在线。可以通过 设置识别线上点击的可接受准确度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);
}
}
推荐阅读
- ssl - Issue connecting to SSL secured Kafka
- django - Django] Saving multiple images by formset doesn't work
- ios - iOS 应用程序的 Citrix MDX 工具包包装失败并出现“Mach Header contains Invalid Flag bits ...”错误
- javascript - JavaScript 二叉搜索树按顺序遍历返回未定义作为答案的一部分
- python - 在 Pandas 中使用字符值创建新行
- c# - Access GSuite user mailboxes using admin credentials
- javascript - 如何使用 highcharts 指向数据中第二个索引的范围(dataClasses)?
- vba - Workbook_Open 下标超出范围
- c# - 如何使用 XUnit 在 ASP.NET Core 中使用依赖注入测试控制器?
- php - 当用户点击“搜索”按钮时,在表格中显示搜索结果