光线跟踪钛合金猫眼-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 16329|回复: 27

光线跟踪钛合金猫眼

[复制链接]
发表于 2019-9-14 18:28 | 显示全部楼层 |阅读模式
本帖最后由 createskyblue 于 2020-3-3 11:56 编辑

你说啥子作业.jpg
+视频
https://www.bilibili.com/video/av67732712/

+原理

---光线跟踪


光敏阵列.png
建立极坐标系
3个等距的光敏电阻,相隔120°获取的原始光照数据范围在0-1023,三个传感器度数分别为ABC并映射在极坐标系对于3个向量中
接着把极坐标系的3个点转化为直角坐标系,把3个传感器的向量累加,得到光源位置
极坐标与平面坐标互换.png

Cache_-5db6b77c4b94dfa..jpg

上图是串口输出
L(-149,46) 是最后算出光源的直角坐标系位置,也就是说在左上角
下面3行分别是3,枚光敏电阻的参数和数据 譬如 这一条

   [ 1 ]-    (219.00     ,     1.57      ,       0.00 ,        216.00 )
传感器B     光强          原件弧度            x                 y

[mw_shl_code=arduino,true]int ray_tracing_x = 0;
int ray_tracing_y = 0;
void ray_tracing() {
  float xy[3][4];
  xy[0][0] = analogRead(A3);
  xy[1][0] = analogRead(A1);
  xy[2][0] = analogRead(A2);
  xy[0][1] = pi / 2;
  xy[1][1] = (7 * pi) / 6;
  xy[2][1] = (11 * pi) / 6;
  ray_tracing_x = 0;
  ray_tracing_y = 0;
  for (int wi = 0; wi < 3; wi++) {
    //Serial.println(String("[") + wi + String("]- (") + xy[wi][0] + String(" , ") + xy[wi][1] + String(" , ") + xy[wi][2] + String(" , ") + xy[wi][3] + String(" )"));
    xy[wi][2] = xy[wi][0] * cos(xy[wi][1]);
    xy[wi][3] = xy[wi][0] * sin(xy[wi][1]);
    ray_tracing_x += xy[wi][2];
    ray_tracing_y += xy[wi][3];
  }
  //Serial.println("\n\n");
}[/mw_shl_code]



---绘制椭圆和画出眼白
椭圆.png
Ellipse(25, 4, 40 , 28);
在x=25  y=4 画出一个a=40  b=28的椭圆

[mw_shl_code=arduino,true]
Ellipse(25, 4, 40 , 28);
  
void Ellipse(int ex, int ey, int a, int b) {
  int c = (a ^ 2) - (b ^ 2);
  float x, y;
  for (y = 32 + map(IrisSide, 0, 1023, -32, 15); y < 2 * b; y++)
  {
    for (x = 0; x < 2 * a; x++)
    {
      if ((x - a) * (x - a) / (a * a) + (y - b) * (y - b) / (b * b) < 1) {
        u8g2.setDrawColor(1);
        u8g2.drawPixel(x + ex, y + ey);
      } else {
        u8g2.setDrawColor(0);
        u8g2.drawPixel(x + ex, y + ey);
      }
    }
  }
}
[/mw_shl_code]

---虹膜缩放把前面光线追踪时获得的光强值映射到一个圆钝钝合理范围传入椭圆函数,最后加上光线跟踪坐标位移

*感谢网友"虚空黄瓜皇"关于这部分提出的数据处理问题,已修复平滑处理误差


[mw_shl_code=arduino,true]void iris(int x, int y) {
  u8g2.setDrawColor(0);
  //u8g2.drawFilledEllipse(64, 32, map(analogRead(A0), 0, 1023, 1, 64), 25);
  /*
     平滑光线变化
  */

  IrisSide = 0;
  for (byte i = 0; i < 7; i++) {
    //丢弃列表最后一个数据并写入新的环境光线强度采样
    IrisSideList = IrisSideList[i + 1];
    if (i!=6)  IrisSide += IrisSideList;
    //Serial.println(String("[") + i + String("]") + String(" : ") + IrisSideList + String("   "));
  }
  IrisSideList[7] = (analogRead(A1) + analogRead(A2)) / 2;
  // Serial.println(IrisSide);
  IrisSide = IrisSide / 6;
  //Serial.println(IrisSide);
  u8g2.drawFilledEllipse(64 + x, 32 + y, map(IrisSide, 0, 1023, 21, 9), map(IrisSide, 0, 1023, 24, 21));
}[/mw_shl_code]


第一点是这样的IrisSideList = IrisSideList[i + 1];
0 1 2 3 4 5 6
a b c d e f  g  处理前
b c d e f g g  处理后
<--注意有两个g

是丢弃最后一个数字
IrisSide += IrisSideList;
IrisSide=b+c+d+e+f+g+g <--注意有两个g
并让数列向前移位

. . .
if (i!=6) IrisSide += IrisSideList;
. . .
IrisSide = IrisSide / 6;因为g重复两遍
所以只累加前6个数字并取其平均数!



+
下载
游客,如果您要查看本帖隐藏内容请回复















发表于 2020-2-16 16:44 | 显示全部楼层
你好,我有两个问题
1.IrisSideList = IrisSideList[i + 1];
    IrisSide += IrisSideList;
为何不直接写成一行  IrisSide += IrisSideList[i + 1]; ?
2.IrisSide = IrisSide / 6;
你循环累加了7次,要求平均值的话为什么这里要除6?
发表于 2019-9-14 19:06 | 显示全部楼层
让我想起肉总喜欢的那个猫头鹰摄像头
发表于 2019-9-14 23:24 | 显示全部楼层
这创意着实不错!
发表于 2019-9-15 21:12 | 显示全部楼层
谢谢
         
发表于 2019-9-16 14:01 | 显示全部楼层
“3个等距的光敏电阻,每个之间相隔60°获取的原始光照“这个间隔是120度吧?
还有“L=64”是怎么来的?
计算光源位置的原理没看懂,下载程序看下。
这个有意思,谢谢楼主分享
 楼主| 发表于 2019-9-21 10:50 | 显示全部楼层
MACE 发表于 2019-9-16 14:01
“3个等距的光敏电阻,每个之间相隔60°获取的原始光照“这个间隔是120度吧?
还有“L=64”是怎么来的?
计 ...

我的表述可能有点不当,我修改一下ovo
发表于 2019-11-20 10:31 | 显示全部楼层
guozhendashen
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:47 , Processed in 0.133238 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表