|
本帖最后由 createskyblue 于 2020-3-3 11:56 编辑
+视频
https://www.bilibili.com/video/av67732712/
+原理
---光线跟踪
建立极坐标系
3个等距的光敏电阻,相隔120°获取的原始光照数据范围在0-1023,三个传感器度数分别为ABC并映射在极坐标系对于3个向量中
接着把极坐标系的3个点转化为直角坐标系,把3个传感器的向量累加,得到光源位置
上图是串口输出
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]
---绘制椭圆和画出眼白
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个数字并取其平均数!
+下载
|
|