日期:2018/3/17
前言
這是之前測試成功,用 Gnuplot 畫出等位線的方法,雖然可以做出我想要的效果,但是我不太確定其中部分指令的功能,還需要再多測試一下。 目前試過兩種作法:
- 用 Gnuplot 指令計算每個位置的電位並畫圖
- 用 C 語言寫一支小程式計算每個位置的電位,將資料存成文字檔,再用 Gnuplot 讀取文字檔的資料畫圖
方法1成果
方法2成果
使用版本為 Gnuplot 5.2 patchlevel 2,下載頁面為 https://sourceforge.net/projects/gnuplot/files/gnuplot/5.2.2/
方法1:用 Gnuplot 指令
reset # 清除所有設定
# 設定輸出格式, wxt: 顯示於視窗, png: 存成 png 圖檔
#set terminal wxt
set terminal png size 600,450
set output "electric_potential.png"
# 設定靜電力常數, 點電荷電量及位置
k = 8.988E9
x1 = -0.1
y1 = 0
q1 = 1E-8
x2 = 0.1
y2 = 0
q2 = -1E-8
# 設定計算距離r, 電位V的函式
r(x,y) = sqrt(x*x+y*y)
V1(x,y)= k*q1/r(x-x1,y-y1)
V2(x,y)= k*q2/r(x-x2,y-y2)
V(x,y) = V1(x,y)+V2(x,y)
# 設定x, y軸繪圖範圍
set xrange [-0.2:0.2]
set yrange [-0.1:0.1]
# 設定x,y取點數
set isosamples 80,80
# 設定座標軸標籤, 為了使z軸標籤不會和數字重疊, 加上 offset 移動位置
set xlabel "x(m)"
set ylabel "y(m)"
set zlabel "V(volt)" offset -2
set grid # 設定底部的格線
set pm3d # 著色
set hidden3d # 隱藏3d曲線上的線條
# 設定數值對應的顏色, rainbow (blue-green-yellow-red)
set palette rgb 33,13,10
#set view map # 由正上方向下看
#set contour base # 於底部畫出等高線
#set cntrparam levels 20 # 等高線數量為20
splot V(x,y)
將以上的文字複製、貼上到文字編輯器中,存成 electric_potential_data_plot.plt,開啟 Gnuplot,切換到存於這個檔案的資料夾,輸入並執行
load 'electric_potential_data_plot.plt'
這個方法的好處在於只要用到 Gnuplot,不需要用到其它的軟體。
方法2:用 Gnuplot 讀取資料檔
reset # 清除所有設定
# 設定輸出格式, wxt: 顯示於視窗, png: 存成 png 圖檔
#set terminal wxt
set terminal png size 600,450
set output "electric_potential_data_plot.png"
# 設定座標軸標籤, 為了使z軸標籤不會和數字重疊, 加上 offset 移動位置
set xlabel "x(m)"
set ylabel "y(m)"
set zlabel "V(volt)" offset -2
set grid # 設定底部的格線
set pm3d # 著色
set hidden3d # 隱藏3d曲線上的線條
set dgrid3d 100,100 qnorm 3 # 將讀取的資料切為100*100格並使數值平滑
# 設定數值對應的顏色, rainbow (blue-green-yellow-red)
set palette rgb 33,13,10
#set view map # 由正上方向下看
#set contour base # 於底部畫出等高線
#set cntrparam levels 20 # 等高線數量為20
# 讀取資料檔, 使用1, 2, 3欄資料作為x, y, z數值, 將數值連線
splot "electric_potential_data.txt" using 1:2:3 with lines
這是用來產生資料的程式
/* 產生繪製等電位線用的數值資料
作者: 王一哲 Yi-Zhe Wang
日期: 2018/3/13 */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// 定義計算電位的運算式
double potential(double x, double y, double q1, double x1, double y1, double q2, double x2, double y2) {
double k = 8.988*pow(10, 9);
return k*(q1/sqrt(pow((x-x1), 2) + pow((y-y1), 2)) + q2/sqrt(pow((x-x2), 2) + pow((y-y2), 2)));
}
int main(void){
//定義繪圖範圍及分割數量
double xmin, xmax, dx, ymin, ymax, dy, num;
xmin = -2.0;
xmax = +2.0;
ymin = -2.0;
ymax = +2.0;
num = 100.0;
dx = (xmax - xmin) / num;
dy = (ymax - ymin) / num;
//定義點電荷電量及位置
double q1, x1, y1, q2, x2, y2;
q1 = +2.0*pow(10, -8);
x1 = -1.0;
y1 = 0.0;
q2 = -1.0*pow(10, -8);
x2 = +1.0;
y2 = 0.0;
//建立計算結果的輸出檔案, 寫入欄位標題
FILE *fPtr;
fPtr = fopen("electric_potential_data.txt", "w");
if (!fPtr){
printf("檔案建立失敗\n");
exit(1);
} else {
fprintf(fPtr, "x(m) \t y(m) \t V(volt) \n");
}
//自動改變(x, y)計算電位並寫入輸出檔
int i, j;
double x, y, result;
for(i = 0; i <= (int)num; i++) {
for(j = 0; j <= (int)num; j++) {
x = xmin + dx*(double)i;
y = ymin + dy*(double)j;
if((x!=x1 && y!=y1) || (x!=x2 && y!=y2)) {
result = potential(x, y, q1, x1, y1, q2, x2, y2);
fprintf(fPtr, "%f \t %f \t %f \n", x, y, result);
}
}
}
fclose(fPtr);
return 0;
}
資料檔名稱為 electric_potential_data.txt,格式如下
x(m) y(m) V(volt)
-2.000000 -2.000000 55.462889
-2.000000 -1.960000 56.614089
-2.000000 -1.920000 57.802880
-2.000000 -1.880000 59.030634
-2.000000 -1.840000 60.298756
-2.000000 -1.800000 61.608685
-2.000000 -1.760000 62.961885
如果學會這個方法,以後就可以用指令將大量的數據丟進 Gnuplot 畫圖,也是有好處的。
結語
實在是太久沒用 Gnuplot,指令都快忘光了,正好複習一下。以後如果需要畫類似的圖,就可以拿這個檔案去修改,速度會快很多。
HackMD 版本連結:https://hackmd.io/@yizhewang/H1Ohp0i3L
沒有留言:
張貼留言