processing判断一个点是否在三角形、圆、椭圆、矩形内(超详细鼠标交互)

前言

刚好最近在学processing,然后有不少同学遇到一个问题哈,就是如何用processing判断一个点是否在三角形、圆、椭圆、矩形内,并且联合arduino一起,通过串口通信实现用户在processing发生点击事件,然后通过arduino开发板反馈(亮灯等等),这一期我就先出如何解决利用processing判断一个点是否在三角形、圆、椭圆、矩形内的问题,下一期再联合arduino开发板出一期实现两个联合,点个赞支持一下呗!

这一期主要讲如何判断在圆和三角形内

下一期主要讲如何判断是在椭圆矩形

椭圆和矩形看这里

最新一期:直接上processing+Arduino代码,实现软硬件结合

如何判断点击事件在圆内:

其实不用想这么复杂,我们在高中就学过圆的表达式:(x-a)²+ (y-b)²=r²,在processing中我们用于画圆的函数是

ellipse(a,b,r,r);

根据这个函数,我们画的时候就已经可以知道了圆心(a,b)、半径r,我们又知道计算两点之间距离的公式:gif.latex?s%3D%5Csqrt%7B%28x1-x2%29%5E2+%28y1-y2%29%5E2%7D,由这公式我们就知道如果点击点p与圆心距离大于半径,那么点p一定在圆外,如果是等于或者小于,就一定是在圆上或圆内,那么我就可以直接做了

另外在processing中鼠标点击产生的事件会返回给程序一个坐标即:(mouseX,mouseY),每一次点击都会有返回,甚至如果(mouseX,mouseY)在draw()函数内调用的话还可以实现一直返回,从而实现一些跟着鼠标不断画图形、移动图形等根据这些我们就可以编写以下代码啦:

上processing代码:

void setup(){
  size(150,50);
}
void draw() {
  fill(0,0,255);
  ellipse(125,25,50,50);
}
void mouseClicked(){
if(sqrt(sq(mouseX-125)+sq(mouseY-25)) <= 25){
    println("yuan");
  }
}

运行效果:

0ec01540f26f44cfa6651c943d28083d.png

 上述函数说明:

sq(a)//a的平方
sqrt(b)//开b的平方根
/*int a=4;
sq(a)就等于16
sqrt(a)==2
*/

如何判断点击事件在三角形内:(重点、难点)

先简单说一下,其实办法很多如用向量相交求交点、算面积等等,后面再考虑出一篇数学专题说这个,这里为了方便大家理解我就用最容易理解的算三角形面积来做,显然底乘高不太现实比较复杂,那么还有其他方法吗?大家应该还记得高中学过的海伦公式,表达式为:S=gif.latex?%5Csqrt%7Bp%28p-a%29%28p-b%29%28p-c%29%7D,其中gif.latex?p%3D%5Cfrac%7Ba&plus;b&plus;c%7D%7B2%7D,再结合两点之间的距离公式就可以计算了,那么我们都知道processing画一个三角形的函数是:

triangle(a1,a2,b1,b2,c1,c2);

其中三个顶点坐标a(a1,a2),b(b1,b2),c(c1,c2),那么如何实现?请看下图

当正好点击在圆内:

图一:

336f5c79a8874bd9b65cb148538cf795.png

图二:

5f24492d92da4ad5b315d3827196007b.png

当鼠标点击点在三角形内:

图一: S=s1+s2+s3,

注意:如果点在三角形的边上也是可以的,只是其中一个面积变为0,和不变如图二:

S=s1+s2,s3等于0

当点击不在圆内:

图三:

03c29d866f9347bdbfcd797de096dbfd.png

040335b2db42448d803bfbfec9b78e15.png

 由图三:S肯定小于s1+s2+s3,其中由图:(s1+s2+s3)-S=2*s3

图示

由这两图我们可以直观知道,如果一个点在这个三角形内,那么它与其他三个顶点相连分别构成的三个三角形的面积之和一定等于大三角形的面积,如果这个点不在此三角形中,那么其面积之和一定大于原三角形的面积

为了方便这里我们直接用等腰三角形做,其他三角形也是一样的喔,只是计算三角形面积稍微改一下就好,直接上代码processing:

void setup(){
  size(150,50);
}
void draw() {
  fill(0,255,0);//(R,G,B)绿色
  triangle(75,0,50,50,100,50);
}
void mouseClicked(){
  if((mouseX>=50)&(mouseX<=100)&(mouseY>=0)&(mouseY<=50)){
    float a = sqrt(sq(mouseX-50)+sq(mouseY-50));
    float b = sqrt(sq(mouseX-75)+sq(mouseY-0));
    float c = sqrt(sq(mouseX-100)+sq(mouseY-50));
    float d = sqrt(sq(75-50)+sq(0-50));
    float p1 = (a+b+d)/2;
    float p2 = (a+c+50)/2;
    float p3 = (c+b+d)/2;
    float s = sqrt(p1*(p1-a)*(p1-b)*(p1-d))+sqrt(p2*(p2-a)*(p2-c)*(p2-50))+sqrt(p3*(p3-c)*(p3-b)*(p3-d));
    if (s>=50*50/2-10 & s<=50*50/2+10){//+10和-10是为了减小误差,因为计算过程有较多小数
    println("sanjiaoxing");
    }
  }
}

代码函数说明:

a,b,c;分别是鼠标到三个顶点的距离

d;是等腰三角形的腰长

p1,p2,p3;分别是三个顶点如鼠标点击点构成三角形的p(海伦公式里的p)

s;就是三个三个顶点如鼠标点击点构成三角形的面积和,可以看出是由三部分加起来的,其中每一部分都是海伦公式计算出来的;

运行效果:

984651d726ac47308898789902022ff2.png

如何判断点击事件在椭圆内:(重点)​​​​​​​

废话不多说,我们都知道椭圆表达式:b%5E2%3D1%2C%28a%3Eb%3E0%29%3B(焦点在x轴)

今天有写代码有画图还打这么多字实在是花了好久,点个赞支持一下吧,剩下的会在下一篇尽快更噢,请留意,可以进我的博客主页的processing-arduino专栏查看噢!!!感谢各位的理解与支持!!!

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
以下是一个示例代码,展示如何让5个随着鼠标移动,离鼠标越远移动越快,你可以根据自己的需求进行修改: ```python class Circle: def __init__(self, x, y, r): self.x = x self.y = y self.r = r self.speed = 0.1 def move_away(self, target_x, target_y): # 计算心到目标点的距离 d = dist(self.x, self.y, target_x, target_y) # 计算需要移动的距离 move_dist = self.r + 10 - d # 计算移动的方向向量 dx = (self.x - target_x) / d dy = (self.y - target_y) / d # 根据速度和方向移动 self.x += dx * move_dist * self.speed self.y += dy * move_dist * self.speed # 限制速度的最大值 self.speed = min(0.5, self.speed * 1.1) def draw(self): ellipse(self.x, self.y, self.r * 2, self.r * 2) circles = [] num_circles = 5 for i in range(num_circles): x = random(width) y = random(height) r = random(20, 50) circles.append(Circle(x, y, r)) def setup(): size(400, 400) def draw(): background(255) for circle in circles: # 让远离鼠标 circle.move_away(mouseX, mouseY) # 绘制 circle.draw() ``` 在这个示例中,我们创建了5个对象,并将它们存储在一个列表中。在 `draw()` 函数中,我们遍历这个列表,对于每个,调用 `move_away()` 方法来让它远离鼠标,然后调用 `draw()` 方法来绘制。在 `move_away()` 方法中,我们使用 `dist()` 函数计算心和鼠标之间的距离,并根据距离计算需要移动的距离和移动的方向向量。然后根据速度和方向移动,并限制速度的最大值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你好呀zws

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值