• 검색 결과가 없습니다.

STEAM R&E 연구결과보고서

N/A
N/A
Protected

Academic year: 2022

Share "STEAM R&E 연구결과보고서"

Copied!
20
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

STEAM R&E 연구결과보고서

(수질 분석을 위한 지시약과

분광광도계를 이용한 분광광도계 제작)

2015. 11. 20.

광주과학고등학교

(2)

< 연구결과 요약 >

과 제 명 수질 분석을 위한 지시약과 분광광도계를 이용한 분광광도계 제작

연구목표

수질 측정 장비가 값비싸서 학생들의 연구에 사용되어지기 부담스럽 다는 문제점을 해결하기 위해 설정한 구체적인 연구의 목적은 제작비 용을 15만 원 이하로 하여 학생들이 손쉽게 제작 또는 부답 없이 구매하 여 사용할 수 있는 수질 측정 장치를 개발하는 것이다.

연구방법

1. 지시약과 분광광도계를 이용한 농도 분석 방법 고안 여러 농도를 가지는 pH, 질산염, 아질산염, 암모늄/암 모니아 용액에 대해 지시약을 첨가하고, 분광 광도계를 이용하여 스펙트럼을 분석한다.

2. 분광 분석 프로그램의 제작

Spectral workbench의 오픈 소스를 기반으로 스펙트럼 에서 분광 데이터를 읽을 수 있는 프로그램을 제작한다.

3. 간이 분광광도계의 제작 및 분석

3D 모델링을 이용하여 간이 분광 광도계를 제작하고, 분광 분석 프로그램과 농도 분석 방법을 이용하여 다양 한 농도의 용액에 대해 분석하고, 실제에 응용해본다.

그림 1. 간이 분광광도계 모식도

연구성과

본 연구를 통해 분광 데이터로부터 물질의 농도를 알아낼 수 있는 프로그램을 제작할 수 있었으며, 아쉽게도 간이 분광 광도계를 완성시킬 수는 없었으나 대략 17만원의 제작비용 으로 제작할 수 있도록 계획할 수 있었다.

주요어

(Key words)

분광 광도계, 지시약, 농도, 스펙트럼, 피크 비

(3)

1. 개요

□ 연구 동기 및 목적

학생들의 입장에서 수중 물질의 농도를 측정하는 장비들은 매우 고가인 경우가 많다. 일반적으로 사용되는 pH 미터는 학교에서 사용하는 것이 10만원 정도이 며, 수질측정키트는 30만 원 이상이다. 물론 학교에서 지원을 해준다면 문제가 없겠지만 개인의 힘과 돈으로 연구를 해야 된다면 아마 고난을 겪을 것이다.

우리는 학생들에게 금전적 부담을 줄 수 있는 고가의 수질 측정 장치를 대체할 수 있는 간단하고 값싼, 그리고 정확도가 높은 측정 장비를 제작함으로써 학생들 도 부담 없이 수질에 관련된 연구를 할 수 있도록 할 것이다.

이러한 문제점을 해결하기 위해 설정한 구체적인 연구의 목적은 제작비용을 15만 원 이하로 하여 학생들이 손쉽게 제작 또는 부답 없이 구매하여 사용할 수 있는 수질 측정 장치를 개발하는 것이다. 이 때, 수질의 대표적 지표인 pH, 질산염, 아질산염, 암모늄/암모니아에 대해 각각의 지시약으로 용액이 농도에 따라 색을 나타나게 하고, 그것을 분광광도계를 이용하여 정량 분석함으로써 수중에 존재하는 오염 물질의 농도를 구한다.

2. 연구 수행 내용

□ 이론적 배경 및 선행 연구

(1) 분광광도계의 제작

분광광도계는 일반적으로 실험실에서 사용하는 복잡하고 정밀한 수준보 다는 쉽고 간단하게 만들 수 있도록 하기 위해 회절격자를 이용한 간이 분광광도계로 제작하여야 한다. 이 분광광도계는 과학축전 등에서 흔히 볼 수 있는 간이 분광계에서 아이디어를 얻었다. 다만, 본 연구의 경우에는 간이 분광계와는 달리 측정 결과를 카메라나 광센서 등을 이용하여 기록하 여 스펙트럼을 수치적으로 기록하도록 한다.

(4)

간이 분광광도계는 크게 광원, 회절격자, 측정부로 나뉘는데, 광원의 경우 연속 스펙트럼을 얻어야하기 때문에 LED보다는 손전등에 이용되는 크립 톤 램프 등 가시광선 영역에서 균일한 밝기를 내는 램프를 이용하도록 한다. 회절격자의 경우 과학교구상 등에서 1만 원대에 구할 수 있는 500line/mm이나 1000line/mm 회절격자를 이용한다.

(2) 용액의 흡광 모델링 및 농도에 따른 흡광 분석

지시약은 특정 화학종의 존재 농도에 따라 지시약의 여려 형태간의 평형이 이동하여 각 형태의 농도 비의 변화에 의해 색 변화가 나타난다. 따라서 농도에 따른 흡수 스펙트럼을 측정하면 농도에 따라 지시약의 각 형태의 존재비가 변화하기 때문에 각 피크의 높이 변화가 나타날 것으로 예상된다.

흡수 피크의 높이는 화학종의 농도에 비례하기 때문에 이 피크의 높이 비는 즉 화학종의 농도비가 된다. 이를 토대로 지시약의 평형상수와 반응식 을 세우고, 이를 이용하면 흡광 피크의 높이 비를 가지고 농도를 추정할 수 있을 것이다.

(3) 분광 데이터의 처리

측정된 스펙트럼을 분석하기 위해 이미지 처리 프로그램을 이용하여 촬영 한 스펙트럼 이미지를 파장에 따른 새기 그래프로 변환하여야 한다. 현재 spectral workbench 등의 오픈소스 기반으로 된 관련 프로그램이 존재한 다. 이를 이용하면 카메라의 이미지를 기반으로 흡수 스펙트럼을 얻고, 특정 파장대의 흡광도를 계산하여 농도를 알 수 있다. 이를 이용하면 컴퓨 터와 웹캠이나 스마트폰을 이용하여 스펙트럼과 데이터를 바로 얻도록 하거나, Arduino나 Raspberry Pi 등을 이용하여 측정된 결과를 바로 표시하 도록 구성 가능하다. 특히, Raspberry Pi는 카메라의 연결과 Mathmatica 등 내장 프로그램, 프로그래밍의 용이성 덕분에 이러한 용도로 사용하기 적절하다 할 수 있다.

(5)

□ 연구주제의 선정

본 연구와 관련되어 <만능지시약과 광도계를 이용한 pH 미터 개발> 연구를 진행했었다. 2015년 3월~5월에 진행했으며, 총 3만원의 제작비용으로 pH 1~12의 무색투명한 용액의 pH를 분석할 수 있는 pH 미터를 제작할 수 있었다. 본 연구는 분광광도계를 이용한다는 점에 있어서 단순히 특정 파장에서의 흡광도를 측정하는 광도계를 이용했던 기존의 연구와 다르다 고 할 수 있다. 본 연구의 결과물은 단순히 pH만을 분석하는 것이 아니라 지시약을 변화시켜 다양한 물질의 농도 또한 측정 가능하고, 스펙트럼까지 측정 가능하기 때문에 여러 가지 목적에 의해 사용되어질 수 있다.

우리는 기존의 어려운 원리를 가진 기계 장비와 달리 학생들이 쉽게 이해할 수 있는 지시약과 분광광도계를 이용하여 기존의 오랜 역사와 개발 과정을 가진 장비들을 뛰어넘을 수 없다는 편견을 깨고, 다른 관점에서 측정 대상 의 성질을 분석함으로써 더 값싸고, 편리한 장비를 개발할 것이다.

□ 연구 활동 및 과정

1) 분광광도계를 이용한 수질 분석 지표의 정량 분석 (1) pH 분석

1. pH 5~9(1 단위)의 완충용액에 BTB와 만능지시약을 용액 : 지시약 = 10:1 비율로 첨가한다.

2. 분광광도계(350~750nm, 5nm 간격)로 분석한다.

(2) NO2- 분석

1. 0.3, 0.8, 0.16, 0.33 ppm의 NO2-용액에 Tetra사의 NO2- 지시약을 매뉴얼에 따라 첨가한다.

2. 분광광도계(350~750nm, 5nm 간격)로 분석한다.

(3) NO3- 분석

1. 12.5, 25.0, 50.0, 100 ppm의 NO3-용액에 Tetra사의 NO3- 지시약을 매뉴얼에 따라 첨가한다.

2. 분광광도계(350~750nm, 5nm 간격)로 분석한다.

(6)

(4) NH3 / NH4+ 분석

1. 12.5, 25.0, 50.0, 100 ppm의 NO3-용액에 Tetra사의 NO3- 지시약을 매뉴얼에 따라 첨가한다.

2. 분광광도계(350~750nm, 5nm 간격)로 분석한다.

2) 3D 모델링을 이용한 간이 분광광도계 제작 (1) 본체 구성

그림 2. 1차 모델 설계

그림 3. 2차 모델 설계

(7)

1. Google Sketchup을 이용하여 분광광도계를 3D 모델로 구성한다. 교수님께서 3D 프린터의 도안을 작성하는데 있어서 Skectchup을 추천해주셨고 간단한 사용법을 가르쳐주셨다.

2. 이 때, 본체는 아래 모식도와 같이 광원 부분, 샘플 부분, 측 정 부분으로 구성되며, 광원에는 램프가 위치하고, 슬릿을 사이에 두고 샘플 부분이 있다. 샘플 부분 다음에는 또 슬릿이 하나 더 있 고 최종적으로 회절격자를 거친 후에 카메라를 이용하여 측정한다.

그림 4. 간이 분광광도계 모식도

3) 웹캠을 이용한 분광 분석 프로그램 제작

기존의 분광광도계는 휴대가 어렵고 가격이 비싸 웹캠과 3D프린터를 이용하여 휴대용 분광광도계를 만들 수 있도록 하였다. 웹캠을 이용하기 위해서는 영상분석에 사용되는 OpenCV 라이브러리를 사용하였다. 프로그 램에서는 먼저 웹캠에서 영상을 촬영한 뒤, 그 영상을 토대로 사용자가 스펙트럼의 시작과 끝을 지정하면 그 선의 픽셀을 따라 각각의 밝기를 다른 창에 그래프로 나타내게 된다. 스펙트럼을 기록하기 위해서는 Enter 키를 누르면 csv 파일로 밝기 데이터가 저장되게 된다. 그러나 이 때 만들어 진 파일은 이미지 상의 위치만 존재하고, 파장 데이터는 없으므로 수은등이 나 나트륨 등 등 파장이 알려진 등을 이용하여 위치에 따른 파장 데이터로 보정을 해야 한다. 파장 보정까지 완료하면 baseline을 3회 측정한 평균치 로 잡고, 지시약과 시료를 넣은 후 5회 흡광도를 측정한다. 측정이 완료되면 미리 알려진 스펙트럼 데이터와 비교하여 농도를 측정하게 된다.

(8)

웹캠 이미지

그래프

데이터

그림 5. 분석 화면

3. 연구 결과 및 시사점

□ 연구 결과

○ 1. 분광광도계를 이용한 pH 지시약의 분석

- pH에 대해서 지시약으로는 BTB와 만능지시약을 사용하였으나, 만능지 시약의 경우 변색범위는 넒지만 peak 수도 많고, 수질 분석이라는 목표 자체가 넒은 pH 범위를 요구하지 않기 때문에 변색범위가 일반적인 수질의 pH와 비슷하면서 분석이 쉬운 BTB만 사용하게 되었다. BTB의 pH에 따른 흡광스펙트럼은 다음과 같다.

(9)

그림 6. BTB를 이용한 pH 분석

여기서 430nm 부근에 산성 형태의 HInd의 peak와, 615nm 부근에 염기성 형태의 Ind-의 peak가 보인다.

흡광도와 pH의 관계는 Handerson-Hasselbach 식과 Beer-Lambert 법칙을 이용하면 된다. 먼저 Handerson-Hasselbach 식에서,

  

 log



이고, Beer-Lambert 법칙을 각각에 대해 적용하면

  

 





  

 

 



이다.

이를 이용하면 다음 식과 같이 흡광도와 pH를 계산 가능하다.

  

 

 log

 



  

⋅

 



 

 

 

 log

  





  log

  



  

또한 실제 데이터에 적용하면, pH=7.12+1.21 log(AInd- /AHInd)이 된다.

이를 이용하면 흡광도 비를 측정하는 것으로부터 간단히 pH를 얻을 수 있다.

- NO2-의 경우, 사용된 시약을 알 수 없어 어떠한 반응이 일어나는지 알 수 없었고, 이 때문에 pH의 측정 때와는 달리 실험으로 얻은 결과를 토대로 식을 세울 수밖에 없다. NO2- 시약의 경우, 505nm~555nm 부근에 NO2-의 농도와 관계없이 흡광도가 엇비슷한 구간이 나타났는데, 이를

(10)

기준점으로 두고 실제 NO2-와 반응을 한 지시약이 540nm에서 흡수한 흡광도와 비교를 하여 NO2-의 농도를 결정한다. 이 경우,



 

 ⋅ 

  

이라는 식을 얻을 수 있었다. (농도단위:ppm)

그림 6. NO2- 분석

- NO3-의 경우, peak가 뚜렷하지 않아 peak를 찾지는 못했지만, 농도에 따라 흡광도가 크게 차이가 나는 지점인 530nm을 측정 대상으로 하고, 445nm의 피크를 기준으로 두었다. 이를 토대로



 

 ⋅ 

  

임을 알 수 있다. 이를 역으로 이용하면 분광광도계로 측정한



 에서



를 계산할 수 있다.

기준

그림 7. NO3- 분석

기준

(11)

- NH3/NH4+의 경우도 역시 동일하게 농도에 따라 흡광도가 크게 변하지 않는 기준점을 390nm로 잡고, 700nm에서의 흡광도를 측정하여 NO2-의 경우와 동일하게 처리하였다. 이 경우에서는



 

 ⋅ 

  

임을 알 수 있었다. (농도단위:ppm)

그림 7. NH3/NH4+ 분석

□ 시사점

아쉽게도 제품을 완성시키지는 못했으나 연구 과정을 통해 지시약과 분광 광도계를 이용한 농도 분석 방법을 고안해낼 수 있었으며, 연구의 목적인 저렴한 수질 분석 장치의 개발이 가능하다는 것을 알 수 있었다.

4. 추후 활용 방안

본 연구에서 진행한 방법대로 간이 분광 광도계의 제작을 완료한다면 간단한 수질 분석에 활용될 수 있다. 그리고 다른 수질의 지표를 분 석할 수 있는 기능을 추가하거나 수질이 매우 좋지 않아 물 자체가

(12)

색을 띠는 경우에 대해 같은 보정 작업을 거쳐 농도를 분석할 수 있 도록 한다면 더 좋은 간이 수질 분석 분광광도계로써 기능할 수 있을 것이라 기대한다. 그렇다면 이 제품을 3D 프린터와 공정을 이용해 생 산하여 상업적으로 충분히 활용할 가치가 있을 것이다.

5. 참고문헌

□ Spectralworkbench. Capture. https://spectralworkbench.org/captur e에서 2015년 10월 6일 인출

□ Wikipedia. Spectrophotometry. https://en.wikipedia.org/wiki/Sp ectrophotometry에서 2015년 8월 26일 검색

(13)

6. 부록

<분광 분석 프로그램의 소스코드>

#include <opencv2/opencv.hpp>

#include <iostream>

#include <vector>

#include <string>

#include <deque>

#include <fstream>

#include <limits>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <fcntl.h>

#include <libv4l2.h>

#include <sys/ioctl.h>

#include <linux/videodev2.h>

using namespace cv;

using namespace std;

Point pt1, pt2;

void drawArrow(Mat& image, Point p, Point q, CvScalar color, int arrowMagnitude = 9, int thickness=1, int line_type=8, int shift=0)

{

//Draw the principle line

line(image, p, q, color, thickness, line_type, shift);

const double PI = 3.141592653;

//compute the angle alpha

double angle = atan2((double)p.y-q.y, (double)p.x-q.x);

//compute the coordinates of the first segment

p.x = (int) ( q.x + arrowMagnitude * cos(angle + PI/4));

p.y = (int) ( q.y + arrowMagnitude * sin(angle + PI/4));

//Draw the first segment

line(image, p, q, color, thickness, line_type, shift);

//compute the coordinates of the second segment p.x = (int)(q.x+arrowMagnitude*cos(angle-PI/4));

p.y = (int)(q.y+arrowMagnitude*sin(angle-PI/4));

//Draw the second segment

line(image, p, q, color, thickness, line_type, shift);

}

// Calculate Luminance double calcLuma(Vec3b px) {

// 0.2126 R+0.7152 G+0.0722 B

(14)

return 0.2126*px[2] + 0.7152*px[1] + 0.0722*px[0];

}

// Plot graph

void plotGraph(Mat& graph,vector<Vec3b> data) {

static bool firstrun=true;

int cnt=data.size();

// For first run, initialize matrix if(firstrun)

graph=Mat(300,cnt+10,CV_8UC3);

graph=CV_RGB(0,0,0);

rectangle(graph,Point(5,15),Point(cnt+5,270),CV_RGB(0x7f,0x7f,0x7f));

for(int i=0; i<cnt-1; i++) {

line(graph,Point(i+5,270-data[i][0]),Point(i+6,270-data[i+1][0]),CV_RGB(0x00,0x00,0xff));

line(graph,Point(i+5,270-data[i][1]),Point(i+6,270-data[i+1][1]),CV_RGB(0x00,0xff,0x00));

l i n e ( g r a p h , P o i n t ( i + 5 , 2 7 0 - d a t a [ i ] [ 2 ] ) , P o i n t ( i + 6 , 2 7 0 - d a t a [ i + 1 ] [ 2 ] ) , C V _ R G B ( 0 x f f , 0 x 0 0 , 0 x 0 0 ) ) ; line(graph,Point(i+5,270-calcLuma(data[i])),Point(i+6,270-calcLuma(data[i+1])),CV_RGB(0xff

,0xff,0xff));

}

imshow("Graph",graph);

}

void CallBackFunc(int event, int x, int y, int flags, void* userdata) {

static bool clicked=false;

static Point temp;

if(event==EVENT_LBUTTONDOWN) if(flags==EVENT_FLAG_CTRLKEY) {

pt1=Point(x,y);

clicked=true;

}

else if(clicked) {

clicked=false;

}

if(event == EVENT_MOUSEMOVE && clicked) pt2=Point(x,y);

}

inline bool file_exists(const std::string& name) {

ifstream f(name.c_str());

if (f.good()) {

(15)

f.close();

return true;

} else {

f.close();

return false;

} }

//void calcAvg(deque< vector<Vec3b> >& buff, vector<Vec3b>& avg) //{

// int minsize=buff.front().size();

// for(deque< vector<Vec3b> >::iterator iter=buff.begin(); iter<buff.end(); iter++) // minsize=min(minsize,(int)(*iter).size());

// //cout << minsize << endl;

// vector<Vec3b>(minsize).swap(avg);

// for(deque< vector<Vec3b> >::iterator iter=buff.begin(); iter<buff.end(); iter++) // {

// for(int i=0; i<minsize; i++) // {

// avg.at(i)[0]+=(*iter).at(i)[0];

// avg.at(i)[1]+=(*iter).at(i)[1];

// avg.at(i)[2]+=(*iter).at(i)[2];

// } // }

// for(vector<Vec3b>::iterator iter=avg.begin(); iter<avg.end(); iter++) // {

// (*iter)[0]/=buff.size();

// (*iter)[1]/=buff.size();

// (*iter)[2]/=buff.size();

// }

// avg=buff.front();

//}

int main(int argc, char *argv[]) {

int x,y;

int device=0;

std::vector<int> devicelist;

string ofn,conffile;

ofstream outfile;

//Mat img = imread("lena.jpg", CV_LOAD_IMAGE_COLOR);

VideoCapture cap;

while(1) {

(16)

try {

cap.open(device);

if(cap.isOpened()) {

devicelist.push_back(device);

cap.release();

}

else break;

device++;

} catch(...) { } }

for(vector<int>::iterator iter=devicelist.begin(); iter<devicelist.end(); iter++) cout << "Device " << *iter << "\n";

while(1) {

cout << "Enter device to use:";

if(cin >> device)

if(!cin.bad()&&find(devicelist.begin(),devicelist.end(),device)!=devicelist.end()) {

cout << "Using device " << device << "!\n";

break;

} cin.clear();

cin.ignore( std::numeric_limits<streamsize>::max(), '\n' );

cin.clear();

cerr << "Wrong device!!" << endl;

}

stringstream sstr;

sstr<<device;

// int descriptor = v4l2_open(string("/dev/video"+sstr.str()).c_str(), O_RDWR);

// v4l2_control c;

//c.id = V4L2_CID_EXPOSURE_AUTO;

//c.value = V4L2_EXPOSURE_AUTO;

//if(v4l2_ioctl(descriptor, VIDIOC_S_CTRL, &c) == 0) // cout << "Success!" << endl;

// auto priority control

//c.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;

//c.value = 0;

//if(v4l2_ioctl(descriptor, VIDIOC_S_CTRL, &c) == 0) // cout << "Success!" << endl;

(17)

cap.open(device);

if(!cap.isOpened()) return -1;

cap.set(CV_CAP_PROP_FRAME_WIDTH,640);

cap.set(CV_CAP_PROP_FRAME_HEIGHT,480);

Mat img,graph,img2;

cap >> img;

if(img.empty()) return -1;

// cout << "Enter Filename:";

// getline(cin,ofn);

// for(int i=1; file_exists(ofn); i++) // {

// if(file_exists(ofn)) // {

// string sel;

// cout << "File exists!("<<ofn<<")\n";

// cout << "Rename or Overwrite[R/O]:";

// getline(cin.sel);

// if(toupper(sel.at(1))=='R') // ofn+=

// } // }

// outfile=ofstream(ofn,ios::out);

pt1=pt2=Point(0,0);

namedWindow( "Image", CV_WINDOW_AUTOSIZE );

setMouseCallback("Image",CallBackFunc,NULL);

LineIterator it=LineIterator(img,pt1,pt2);

vector<Vec3b> buff;

vector<Vec3b> avg;

//deque< vector<Vec3b> > hold;

int key,inputnum=0,subsect=0;

bool displaystr=false,isinput=false;

string str,temp;

while(1) {

while(1) {

buff.clear();

cap >> img;

img.copyTo(img2);

if(displaystr)

putText(img2,str,Point(0,15),CV_FONT_HERSHEY_SIMPLEX,0.4,CV_RGB(0xff,0xff,0xff),1,8);

drawArrow(img2,pt1,pt2,CV_RGB(0xff,0xff,0x00),9,1,CV_AA);

it=LineIterator(img,pt1,pt2);

for(int i=0; i<it.count; i++,++it) {

buff.push_back((Vec3b)*it);

(18)

//cout << (inten[i]=calcLuma(buff[i])) << endl;

}

//hold.push_back(buff);

//if(hold.size()>10) hold.pop_front();

//calcAvg(hold,avg);

if(it.count>2)

plotGraph(graph,buff);

imshow("Image", img2);

if((key=waitKey(30))>=0) break;

} if(isinput) {

if(key=='\n') {

isinput=false;

if(temp.size()<=0) {

subsect=0,inputnum=0,isinput=false,displaystr=false;

key=0;

}

switch(subsect) {

case 1:

x=atoi(temp.c_str());

temp.clear();

isinput=true;

break;

case 2:

y=atoi(temp.c_str());

temp.clear();

break;

} } else {

if(isdigit(key)) {

temp+=(char)key;

str+=(char)key;

}

else if(key==0xFF08) {

if(temp.size()>=1) {

str.erase(str.end()-1);

temp.erase(temp.end()-1);

}

(19)

}

continue;

} }

if(key=='\n'&&!inputnum) {

for(int i=0; i<buff.size(); i++)

cout << calcLuma(buff[i]) << " ";

cout << endl;

}

else if(key=='c') {

str.clear();

displaystr=false;

}

else if(key=='d') {

displaystr=~displaystr;

stringstream sstr;

sstr<<"("<<pt1.x<<","<<pt1.y<<"),("<<pt2.x<<","<<pt2.y<<")";

str=sstr.str();

}

else if(key=='o'||(inputnum==1)) {

displaystr=true;

if(subsect==0)

str=string("Enter Point 1 (X?):");

else if(subsect==1)

str=string("Enter Point 1 (Y?):");

inputnum=1;

isinput=true;

if(subsect==0) subsect=1;

else if(subsect==1) subsect=2;

else if(subsect==2)

pt1=Point(x,y),subsect=0,inputnum=0,isinput=false,displaystr=false;

}

else if(key=='e'||(inputnum==2)) {

displaystr=true;

if(subsect==0)

str=string("Enter Point 2 (X?):");

else if(subsect==1)

str=string("Enter Point 2 (Y?):");

inputnum=2;

(20)

isinput=true;

if(subsect==0) subsect=1;

else if(subsect==1) subsect=2;

else if(subsect==2)

pt2=Point(x,y),subsect=0,inputnum=0,isinput=false,displaystr=false;

}

else if(key=='q'||key==33) break;

} return 0;

}

수식 1. 분광 분석 프로그램 소스코드

참조

관련 문서

학생들이 문제를 인지한 후에 토론 과정을 통하여 학습 동아리를 구성했다는 점에서 학생들의 공동 작업의 우수성이 기대됨... 홍보

철근에 해당하는 것은 교원 섬유로 짜여진 바구니이며, 그 그물눈을 채우고 있는 시멘트에 해당하는 것이 골질이다.. 골질은 탄산 칼슘·인산 칼슘

가속도 및 자이로 값이 주기적으로 변화하는 것으로 보아 회전체 내에서 주기적으로 반복되는 물리적 효과가 나타난다고 판단하였다. 또한 회전축 을 향하는 방향에

본 연구에서는 병원에서 환자에게 링거액을 주입할 경우 발생할 수 있는 여러 문제점을 파악하고 , 그 중에 링거액의 정상적인 주입 여부, 링거 교환 시간 알림 기능과 같이 스마트

나.. YIXIN 자체도 프로그램으로 배포되고 있다. 룰의 종류는 Free, Renju, RIF가 있다. Free 룰은 위의 룰 하나만 있는 룰이다. Renju 룰은 흑이 필승하는 것을 제어하기

※ 이 때 스탠드에 매단 알루미늄 공을 사이에 둔 평행판 축전기를 설치하는 이유는 알루미늄 공의 움직임으로 콘덴서의 충전되었음을 확인하기 위한 일종의 측정

관측되었고 로진 카제인 페인트와 수성 페인트가 비슷한 정도로 두 번째로 우수한 측정값을 나타냈기 때문에 이 실험에서 역시 로진을 이용한 페인트들이 우수하였다고

- 측정 온도 값에 대한 계산 결과를 통해 경제적 효과에 대한 구체적인 수치를 구함. 학교에 설치된 냉난방기의 현황을 조사하고 그 값을 적용하여 전기 에너지