前言
- 本博文算是一個簡單的算法類的博客。
- 硬件材料是: 0.96OLED(IIC接口)中景園SSD1306;
STM32L496開發板(IIC-1); - 關於OLED這裏就不說了,主要闡述軟件這塊兒對功能的實現;
要實現的功能描述和效果
如下圖:圖片中有一對同心固定的大小圓和一個帶圓心的移動圓。
要求: 大小圓在整個屏幕內的位置不會變。移動圓隨着給定的參數的改變,實際座標位置可能在屏幕內任意位置。但是爲了完成電子氣泡的效果,這裏要求:移動圓圓心不能出大圓,也就是移動圓的實際座標位置無論有沒有在大圓外,其顯示座標位置都不能在大圓外。當移動圓座標沒有落在大圓內(包含邊)時,就要求移動圓圓心落在移動圓圓心實際座標和大圓圓心座標之間的連線與大圓的交點上(繞口)。(以上步驟,下面分步實現)
建立平面座標系
理解兩個座標系:
OLED物理座標系(如圖)
說明::x,y的值是由OLED本身決定,屏幕的原點在屏幕的左上角;但是我們不用這個座標系,因計算很麻煩,我們希望原點就在(64,32)這個地方。因此我們假設一個抽象座標系,此座標系的原點對應於物理座標系的(64,32);
抽象座標系
抽象座標系參數:
- 大圓圓心座標爲(x0=0,y0=0),大圓小圓半徑固定爲R1和R2,R1=32,R2=7。
- 移動圓的圓心座標是(x1,y1),半徑r1爲4;
- 建立平面座標系:
分析移動圓的位置(初中數學)
轉化爲C語言就是
double x1 ,y1 , z1;
x1 = -64; //給定移動圓座標
y1 = -32;
z1= sqrt(pow(x1,2)+pow(y1,2)); //這裏的temp就是勾股定理的長邊;
if(z1 > 32) //移動圓圓心在大圓外
{
/*code*/
}
else //移動圓圓心在大圓內(包含邊)
{
/*code*/
}
分析移動圓在大圓外時如何計算交點座標
解題思路:等比三角形; 這個解題思路比較簡單,用直線與圓的交點太難了,程序很難實現;
程序實現:
void Module_Image_display_Circle(void)
{
double x0 = 64,y0 = 32; //定義偏移量;
double x1 = -64,y1 = -32,z1;
while(Key_F1 == 6)
{
memset(OLED_GRAM,0, sizeof(OLED_GRAM)); //清空數組
//獲取傾斜度數據
x1+=2; //x1 =傾斜值x;
y1++; //y1 =傾斜值y;
if( x >= 127)
{
y1 = -32;
x1 = -64;
}
HAL_Delay(100);
//顯示傾斜度數據
OLED_DrawPoint(64,32); //圓心
OLED_DrawCircle(64,32,32); //大圓(圓域)
OLED_DrawCircle(64,32,7); //中心園
//計算移動圓位置
z1 = sqrt(pow(x1,2)+pow(y1,2)); //這裏的temp就是勾股定理的長邊;
if(z1 > 32) //移動圓圓心在大圓外
{
OLED_DrawPoint(x1*(32.0/z1)+x0,y1*(32.0/z1)+y0); //移動圓圓心
OLED_DrawCircle(x1*(32.0/z1)+x0,y1*(32.0/z1)+y0,4); //移動圓
}
else
{
OLED_DrawPoint(x1+x0,y1+y0); //移動圓圓心
OLED_DrawCircle(x1+x0,y1+y0,4); //移動圓
}
OLED_Refresh(); //將顯存中的數據傳送到OLED的GRAM
}
}
這裏估計有人有疑問:爲什麼最後到顯示的時候會出現+x0,+y0這種情況,原因就是抽象座標系轉化成物理座標系,這樣才能正確的顯示在OLED上