한문장으로 :
1)엘리트 계수(음주지출(월)/전체수입(월))와 2)좋아하는 주류 종류(복수 응답 가능)를 조사해서 우리 클래스만의 재미있는 관
계도를 만들자.
같은 클래스 여러분의 많은 관심과 참여를 적극 권장합니다 ^^
진행사항 입니다.
일단 프로세싱으로 하기전에 뭘 어떻게 할것인지, 어떤게 필요할지 정리를 해봤습니다.
http://aliceon2010.googlegroups.com/web/2010-02-12_07-07-30_553.jpg?gsc=uGLaSAsAAACynwWkbA6stc8b8Y85MU9T
(실제 진행을 하면서 조금씩 달라지네요..)
그다음으로는
processing.org에 있는 XML 예제를 실행 해봤습니다.
(http://processing.org/reference/XMLElement.html)
data 폴더에 sites.xml를 만들고
<?xml version="1.0"?>
<websites>
<site id="0" url="processing.org">Processing</site>
<site id="1" url="mobile.processing.org">Processing Mobile</site>
</websites>
프로세싱엔 다음코드를 넣었습니다.
XMLElement xml;
void setup() {
size(200, 200);
xml = new XMLElement(this, "sites.xml");
int numSites = xml.getChildCount();
for (int i = 0; i < numSites; i++) {
XMLElement kid = xml.getChild(i);
int id = kid.getIntAttribute("id");
String url = kid.getStringAttribute("url");
String site = kid.getContent();
println(id + " : " + url + " : " + site);
}
}
그래서, 아 이렇게 하는거구나! 대~충 알게되었는데,
('대~충' 보고 넘어가는 바람에 나중에 막혔습니다;;;;)
데이터를 긁어올 xml파일을 가라로 만들고,
프로세싱에서 잘 들어오는지 아까 배운 메시지 윈도우에 띄워 보자 까지가 이번 데모의 목표였습니다.
[data.xml]
<?xml version="1.1" ?>
<data>
<datas id="classmate1" favorite="beer" value1="100" value2="300"
value3="10"></datas>
<datas id="classmate2" favorite="soju" value1="50" value2="500"
value3="15"></datas>
<datas id="classmate3" favorite="liquor" value1="100" value2="100"
value3="1"></datas>
</data>
[aliton_0002.pde]
int Num;
//Classmate[] classmates = new Classmate[Num];
XMLElement xml;
//XMLElement[] data = new XMLElement[];
float value;
int r1, r2, r3;
/*
float value;
int classmateNum;
XMLElement xml;
XMLElement[] data = new XMLElement[classmateNum];
Classmate[] classmates = new Classmate[classmateNum];
*/
void setup(){
println("----- data visualization workshop 엘리트온 계수 -----");
// XML에서 필요한 Attribute 가져 오기 //
xml = new XMLElement(this, "data.xml");
XMLElement[] datas = xml.getChildren();
for(int i=0; i<datas.length; i++){
String id = datas[i].getStringAttribute("id");
String favorite = datas[i].getStringAttribute("favorite");
int value1 = datas[i].getIntAttribute("value1");
int value2 = datas[i].getIntAttribute("value2");
value = value1/value2*100;
// vlaue의 값을 소수점 세자리 이하를 구하고 싶은데, 소수점 한자리 까지 밖에 안나옴.
println(id+"는 "+favorite+"를 가장 좋아하고, 엘리트온 계수는"+value+"이다.");
}
/* XML 엘리먼트에서 array를 사용하지 않을때는 다음의 xml.getChild를 사용한다.
int datasNum = xml.getChildCount();
for(int i = 0; i<datasNum; i++){
XMLElement datas = xml.getChild(i);
String id = datas.getStringAttribute("id");
String favorite = datas.getStringAttribute("favorite");
int value1 = datas.getIntAttribute("value1");
int value2 = datas.getIntAttribute("value2");
}
// 확인 //
println("datas의 Num : "+datasNum);
*/
size(1300,500); // 캔버스 사이즈
area(); // 각 그룹의 영역 그리기
}
/*
void draw(){
for(int i=0; i<Num; i++){
classmates[i].draw();
}
}*/
// beer, liquor, soju 그룹의 영역 //
void area(){
// beer의 영역 //
r1 = 250;
fill(255,255,0, 100);
ellipse(r1,250,300,300);
// liquor의 영역 //
r2 = 650;
fill(255,150,0, 100);
ellipse(r2,250,300,300);
// soju의 영역 //
r3 = 1050;
fill(0,200,0, 100);
ellipse(r3,250,300,300);
}
[Classmate.pde]
/*Class Classmate{
int id;
int value;
String favorite;
float posX, posY; // 각 변수마다 ;를 붙여야 하는지
PImage imgBeer, imgLiquor, imgSoju; // 각 변수마다 ;를 붙여야 하는지
imgBeer = loadImage("beer.png");
imgLiquor = loadImage("liquor.png");
imgSoju = loadImage("soju.png");
void Classmate(int id, int value, String favorite){
}
void draw(){
size();
colorAndPosition();
}
void size(){
}
void colorAndPosition(){
if(favorite != null){
if(favorite == beer){
posX = random(100,400);
posY = random(100,400);
image(imgBeer,posX,posY);
}
else if(favorite == liquor){
posX = random(500,800);
posY = random(100,400);
image(imgLiquor,posX,posY);
}
else{
posX = random(900,1200);
posY = random(100,400);
image(imgSoju,posX,posY);
}
}
}
}*/
처음 먹은 목표보다 욕심좀 부려서 필요한 이미지도 만들어보고, 클래스? 객체?를 사용하기 위해서 좀 만져봤는데
일단 맘같이 잘 안되서 주석으로 가렸습니다.
그리고 먼저번에 '대~충' 보고 지나갔던 레퍼런스부분에서
XMLEliment에서 array를 사용할 때는 xml.getChild()가 아니라 xml.getChildren()을 써야 하는
구나하고 알면서 동시에, 역시 대충보면 안되겠구나 했습니다;;;
소스는 processing.org와 워크샵에서 배웠던 소스 celeb, dataVi_01,02,03을 참고 했습니다.
일단, 완전 더 이상하고 난잡해 졌지만
[data.xml]
수정없이 그대로 사용.
[aliteon_0003.pde]
int Num;
Classmate[] classmates = new Classmate[Num]; // Classmate라는 클래스의
classmates라는 객체를 Num만큼 생성
int r1, r2, r3;
Area areas1, areas2, areas3;
void setup(){
println("----- data visualization workshop 엘리트온 계수 -----");
size(1300,500); // 캔버스 사이즈
area(); // 각 그룹의 영역 그리기
areas1 = new Area(00C800,250,150);
areas2 = new Area(50,650,150);
areas3 = new Area(0,1050,150);
areas1.update();
areas2.update();
areas3.update();
}
void draw(){
// println(id+"는 "+favorite+"를 가장 좋아하고, 엘리트온 계수는"+value+"이다.");
for(int i=0; i<Num; i++){
classmates[i].draw();
}
}
// beer, liquor, soju 그룹의 영역 //
void area(){
// beer의 영역 //
r1 = 250;
fill(255,255,0, 100);
ellipse(r1,250,300,300);
// liquor의 영역 //
r2 = 650;
fill(255,150,0, 100);
ellipse(r2,250,300,300);
// soju의 영역 //
r3 = 1050;
fill(0,200,0, 100);
ellipse(r3,250,300,300);
}
// 각 그룹의 영역을 지정해 주는 또 다른 방법 //
class Area{
float f = 0.0;
String hexColor;
int posX, posY;
String gg="#";
void Area(int c, int posX, int posY){
posX = posX;
posY = posY;
String gl = gg+c;
color(gl);
beginShape(POLYGON);
while(f < TWO_PI) {
fill(c);
vertex(posX + cos(f)*150, posY + sin(f)*150);
f += PI/12.0; // 12.0이라는 숫자가 어떻게 나왔는지?
}
endShape();
}
void update(PApplet parent){
}
}
[Classmate.pde]
class Classmate{
XMLElement xml;
String id;
float value;
String favorite;
float posX, posY;
PImage imgBeer, imgLiquor, imgSoju;
void Classmate(PApplet parent){
imgBeer = loadImage("beer.png");
imgLiquor = loadImage("liquor.png");
imgSoju = loadImage("soju.png");
// XML에서 필요한 Attribute 가져 오기 //
xml = new XMLElement(parent, "data.xml");
XMLElement[] datas = xml.getChildren();
for(int i=0; i<datas.length; i++){
id = datas[i].getStringAttribute("id");
favorite = datas[i].getStringAttribute("favorite");
int value1 = datas[i].getIntAttribute("value1");
int value2 = datas[i].getIntAttribute("value2");
value = value1/value2*100;
// vlaue의 값을 소수점 세자리 이하를 구하고 싶은데, 소수점 한자리 까지 밖에 안나옴.
println(id+"는 "+favorite+"를 가장 좋아하고, 엘리트온 계수는"+value+"이다.");
}
}
void draw(){
size();
colorAndPosition();
}
void size(){
}
void colorAndPosition(){
if(favorite != null){
if(favorite == "beer"){
posX = random(100,400);
posY = random(100,400);
image(imgBeer,posX,posY);
}
else if(favorite == "liquor"){
posX = random(500,800);
posY = random(100,400);
image(imgLiquor,posX,posY);
}
else{
posX = random(900,1200);
posY = random(100,400);
image(imgSoju,posX,posY);
}
}
}
}
이렇게 했는데 중간중간 실행 시켜보다가 이젠 안됩니다.
암튼 이제 창가로 햇빛은 들고, 졸려 죽겠고,
누군가 도와줬음 좋겠고,,,
일단 데모 두가지 만들어 봤는데,
마지막에 합쳐보는게 또 문제네요.
다음은 일단 중간 과정을 생략한 aliteon_0006과 aliteon_0007의 소스입니다.
[aliton_0006.pde]
PImage beer_img, liquor_img, soju_img;
PFont visible_id;
String[] datas;
int index = 0;
float aliteon;
void setup() {
size(800, 400);
background(0);
stroke(255);
frameRate(15);
datas = loadStrings("data.txt");
beer_img = loadImage("beer.png");
liquor_img = loadImage("liquor.png");
soju_img = loadImage("soju.png");
visible_id = loadFont("AlbaSuper-20.vlw");
imageMode(3);
textAlign(CENTER);
}
void draw() {
float beer_X, beer_Y;
beer_X=random(0,200); beer_Y=random(0,200);
float liquor_X, liquor_Y;
liquor_X=random(200,400); liquor_Y=random(0,200);
float soju_X, soju_Y;
soju_X=random(400,600); soju_Y=random(0,200);
if (index < datas.length) {
String[] pieces = split(datas[index], '\t');
if (pieces.length == 6) {
String visible = pieces[0]; // pieces[0]은 visible로, 보여지는 id
String envisible = pieces[1]; // pieces[1]은 envisible로, 보이지 않는
id
int favorite = int(pieces[2]); // pieces[2]는 favorite으로, 좋아하는
술
float value1 = int(pieces[3]); // pieces[3]은 value1로, 지출
float value2 = int(pieces[4]); // pieces[4]는 value2로, 수입
int value3 = int(pieces[5]); // pieces[5]는 value3으로, 주량
aliteon = (1/2);
println(aliteon);
// float map_aliteon;
// map_aliteon = map(aliteon, 0,1,0,100);
if(favorite == 1){
pushMatrix();
// scale();
image(beer_img,beer_X,beer_Y);
popMatrix();
textFont(visible_id,20);
text(visible,beer_X,beer_Y);
}else if(favorite == 2){
image(liquor_img,liquor_X,liquor_Y);
textFont(visible_id,20);
text(visible,liquor_X,liquor_Y);
}else{
image(soju_img,soju_X,soju_Y);
textFont(visible_id,20);
text(visible,soju_X,soju_Y);
}
}
// Go to the next line for the next run through draw()
index ++;
}
}
[aliton_0007.pde]
// 수정 동영상 버벅거림!!!, 싱크 안맞음!!!!, 소리는 한번나오고 loop끝남 하긴, 계속 나오면 시끄러울거 같음;;;
import processing.video.*;
String link;
float floating1, floating2;
Movie beer_mov,liquor_mov,soju_mov;
PFont myFont, font;
void setup(){
size(400,400,P3D);
camera(1200,1200,200, 900,900,0, 0,0,-1.0); // 카메라의 정확한 구도 맞추기 힘듬! 뒤
에 힌트도 주고 소개하는 글도 다 읽혀야 하는데,,, 계속 삽질...
char[] charset = new char[0xD7A3 - 0xAC00 + 1];
StringBuilder strB = new StringBuilder();
for (int i = 0, code = 0xAC00; code <= 0xD7A3; i++, code++){
charset[i] = Character.toChars(code)[0];
}
println("loading, quite aaaaaa minutes");
myFont = createFont("malgun", 50, true, charset); //"Arial Unicode
MS" Mac에선 기본 한글 서체 모르니까.... 알아서~ 그렇다고 맑음고딕 실행되지도 않음;;;;
font = loadFont("1YDIYGO140-KSCPC-EUC-H-48.vlw");
noStroke();
lights();
smooth();
link = "http://구글도큐멘트에서 설문조사하는 링크주소blarblar..";
beer_mov = new Movie(this, "beer.mov");
liquor_mov = new Movie(this, "liquor.mov");
soju_mov = new Movie(this, "soju.mov");
beer_mov.loop();
liquor_mov.loop();
soju_mov.loop();
}
void draw(){
background(255);
floating1=abs(sin(frameCount)*5.0); // 술잔에 빠진듯 출렁출렁 하고 싶은데 잘 안
됨!!!!!;;;;
floating2=abs(tan(frameCount)*.9);
println(floating1+" "+floating2);
pushMatrix();
textAlign(CENTER);
fill(0);
textFont(myFont);
text("엘리트온 지수\n\"아직 설문에 답을 안하셨으면",800+floating1,700+floating2);
fill(0,0,200);
textFont(font, 50);
text(link, 800+floating1,800+floating2); // 인터넷 브라우저로 바로가기 링크 하고 싶은
데 못하겠음~
fill(0);
textFont(myFont);
text("숫자 1\2\3을 누르면\n각각 맥주 양주 소주 선호도를 볼 수 있습니다.\n피드백은",
800+floating1+10, 900+floating2); // 아 그리고 숫자도 안나옴~ 못찾겠음~
textFont(font, 50);
fill(20,150,200);
text("alice...@googlegroups.com",
800+floating1+20,1100+floating2);
popMatrix();
//beer구역///////////////////////////////////////
fill(200,240,0,100);
ellipse(0,0,200,200);
pushMatrix();
scale(0.5);
translate(beer_mov.width/2,0);
rotateZ(PI-PI/6);
image(beer_mov, 0,0);
popMatrix();
//liquor구역///////////////////////////////////////
fill(200,140,0,100);
ellipse(0,200,200,200);
pushMatrix();
scale(0.5);
// rotateX(PI/2);
// liquor_mov.angle(10); 로테이트를 하면 중점(0,0) 기준으로 로테이트 되서 맘에 안듬;
image(liquor_mov, 0,400);
popMatrix();
//soju구역///////////////////////////////////////
fill(10,200,10,100);
ellipse(173.2,100,200,200);
pushMatrix();
scale(0.5);
// rotateX(PI/2);
// soju_mov.rotateY(PI/3*2); 얘도 마찬가지~ 거울 세워 놓은 것처럼 기울여져서 보이게 수정하고 싶음
~!!!!!
image(soju_mov, 346.2,200);
popMatrix();
}
void keyPressed(){
if(key=='1'){
camera(-50,-86.6,100, 0,0,0, 0,0, -1.0);
}else if(key=='2'){
camera(-50,286.6,100, 0,200,0, 0,0, -1.0);
}else if(key=='3'){
camera(273.2,100,100, 173.2,100,0, 0.0,0, -1.0);
}else if(key==ENTER){
camera(0,0,0, 0,0,0, 0,0,0);
}
}
void movieEvent(Movie myMovie) {
beer_mov.read();
liquor_mov.read();
soju_mov.read();
}
인터넷 상에서 각부분에 대단한 (선생님)분들의 많은(많은~많은~많은~)도움을 받았습니다.
but, 말이 안통하는게 흠 이었지만...
쨋던, 오늘한 과정중 빠진 중간과정,
그리고 도움받은 소스, 참고한 링크, 토론등은 시간이 될때 마저 올리겠습니다.
On 2월16일, 오후2시11분, "agonia j. amsterdam" <agonia...@gmail.com> wrote:
> 좋은 자료 감사합니다.^^
> 설 연휴 기간에 생각 해봤는데,
> 프로세싱으로 직접 설문지를 파싱하는 거보다,
> 일단 설문을 받아서 Array등에 수동으로 입력 하는건 어떨까 생각 해봤습니다.
> 이렇게 1단계를 완성하고,
> 시간을 봐서 프로세싱으로 파싱하는 다음 2단계를 하는건 어떨까요?
> 의견주세요~
>
aliteon_0006은
[data.txt]
2/18/2010 2:53:23 hwani 1 100 200 1
2/18/2010 2:54:00 shrek 2 100 200 3
2/18/2010 2:55:10 atom 3 200 200 4
2/18/2010 4:20:42 pororo 1 142 948 4
2/20/2010 4:29:59 X123 2 492 699 2
2/18/2010 2:53:23 hwani2 2 200 100 5
2/18/2010 2:54:00 shrek2 1 500 1000 5
2/18/2010 2:55:10 atom2 1 200 987 2
2/18/2010 4:20:42 pororo2 3 388 999 1
2/20/2010 4:29:59 X1232 3 200 200 3
[AlbaSuper-20.vlw]
[beer.png]
[liquor.png]
[soju.png]
그리고 aliteon_0007은
[beer.mov]
[liquor.mov]
[soju.mov]
[1YDIYGO140-KSCPC-EUC-H-48.vlw]
을 사용했는데,
지금보니까 몇몇 리소스가 저작권에 문제가 될 수도 있다는 생각이 드네요;;;;
> ...
>
> 추가 정보 >>