"จะไปเป็นดาวววววโดดเด่นบนฟากฟ้าาาาา~~"
ถ้าพูดถึงดาว แต่ละคนก็มีดาวในจินตนาการตัวเองอยู่
แต่สำหรับผมแล้ว ถ้าพูดถึงดาว ผมนึกถึงสิ่งนี้
ไคบะ : เทิร์นของข้า ขอสังเวยมอนสเตอร์ 3 ตัว เพื่อเรียก Blue Eye White Dragon !!
ยูกิ : หึ เจ้าจบสิ้นแล้ว ขอเปิดการ์ดกับดัก "คำสาปดาวหกแฉก" !!
ไคบะ : ม่ายยยยยยยยยยยยยยยยยยยยย~~~
ใช่แล้วครับ มันคือ การ์ดกับดัก "คำสาปดาวหกแฉก" จากการ์ตูนเรื่อง YU-GI-OH แม้เรื่องนี้มันจะเป็นการ์ตูนที่เก่าแล้ว แต่การ์ดใบนี้ ผมยังจำมันได้เสมอ
ว่าแล้ว ผมก็ใช้ Processing วาดรูปเลียนแบบการ์ดใบนี้เอาซะเลย
ส่วนนี่ก็คือ code ของผม
void setup()
{
// initialization
size(300,300);
background(0);
strokeWeight(4);
stroke(255,255,0);
translate(width/2,height/2);
// variable
int CenterStarX,CenterStarY;
int WidthStar,HeightStar;
int d;
int SpaceBetweenCircle;
float RVertical,RSqrt,RCircle;
// assign variable
CenterStarX = 0;
CenterStarY = 0;
WidthStar = 160;
HeightStar = 184;
d = 100; //space between base of both triangle
SpaceBetweenCircle = 40; //space between inside and outside circle
RVertical = HeightStar/2; //radius from center of star to top vertex of star
RSqrt = sqrt((pow((d/2),2))+(pow((WidthStar/2),2))); //radius from center of star to side vertex of star
if(RVertical > RSqrt)
{
RCircle = RVertical;
}
else
{
RCircle = RSqrt;
}
// draw outside circle
fill(0,120,0);
ellipse(CenterStarX,CenterStarY,(RCircle*2)+(SpaceBetweenCircle*2),(RCircle*2)+(SpaceBetweenCircle*2));
// draw inside circle
fill(0,0,100);
ellipse(CenterStarX,CenterStarY,(RCircle*2),(RCircle*2));
// draw top vertex triangle
noFill();
triangle(CenterStarX,CenterStarY-(HeightStar/2)+3,CenterStarX-(WidthStar/2)+3,CenterStarY+(d/2),CenterStarX+(WidthStar/2)-3,CenterStarY+(d/2));
// draw bottom vertex triangle
noFill();
triangle(CenterStarX,CenterStarY+(HeightStar/2)-3,CenterStarX-(WidthStar/2)+3,CenterStarY-(d/2),CenterStarX+(WidthStar/2)-3,CenterStarY-(d/2));
}
ขอบ่นแปปนึง
อย่างแรกเลย ผมเกลียดระบบพิกัดแกน X,Y ของ Processing มากเลย
ทำไมรึ ? ก็เพราะว่ามันไม่เหมือนกับระบบพิกัดฉากในวิชาคณิตศาสตร์ไงล่ะครับ
จุด (0,0) ไปอยู่มุมซ้ายบนของ background ผมเลยใช้คำสั่ง translation(width/2,height/2) เพื่อให้จุด (0,0) อยู่ตรงกลาง
และก็อีกอย่างที่ทำให้ผมเกลียดมัน คือ แกน Y เมื่อเลื่อนขึ้นด้านบน แทนที่จะเป็นค่า +Y ดันเป็น -Y ซะอย่างงั้น
ช่างมันเถอะ !! เรามาต่อกันดีกว่า
รูปดาวรูปนี้ เพิ่มใช้เป็นสามเหลี่ยม 2 รูปกลับหัวแล้วมาซ้อนกัน อีกทั้งยังใส่วงกลม 2 วงซ้อนกัน จนกลายเป็นดาวอย่างที่เห็น
ต่อมา จาก code ด้านบน เราสามารถแก้อะไรได้บ้าง
CenterStarX : พิกัด X ของจุดศูนย์กลางของดาว
CenterStarY : พิกัด Y ของจุดศูนย์กลางของดาว
HeightStar : ความสูงของดาว
WidthStar : ความกว้างของดาว
d : ระยะห่างระหว่างฐานของสามเหลี่ยม
แล้วจากการที่เราสามารถปรับขนาดของดาวได้ ทำให้บางครั้งยอดแหลมของดาวอาจจะทะลุออกนอกวงกลมไป ทำให้ผมต้องทำการปรับขนาดของวงกลมให้พอดีกับยอดของดาว แต่ถ้าให้ผมมานั่งปรับเองทุกครั้งที่ปรับขนาดของดาว ก็คงจะเหนื่อย ผมก็เลยต้องเขียนโปรแกรมให้วงกลมปรับขนาดเอง
อย่างแรก เราต้องหารัศมีของวงกลมก่อน โดยรัศมีของวงกลม คือ ตั้งแต่จุดศูนย์กลางของดาว จนถึงยอดแหลมของดาว แต่ทว่า มันมีตั้งหลายยอดแหลม แล้วจะใช้รัศมีของยอดแหลมไหนล่ะ
งั้นเอาอย่างงี้ละกัน ผมดูคร่าวๆแล้ว มันมีรัศมีอยู่ 2 ค่า คือ รัศมีจากจุดศูนย์กลางไปยอดแนวตั้ง กับ รัศมีจากจุดศูนย์กลางไปยอดด้านข้าง
จากรูป RVertical = HeightStar/2
ส่วน RSqrt หาโดยทฤษฏีบทที่แสนยาก (หรอ)
ด้วยทฤษฏีบทของพีทาโกรัส
RSqrt^2 = (d/2)^2 + (WidthStar/2)^2
เพระาฉะนั้น
RSqrt = sqrt((d/2)^2 + (WidthStar/2)^2)
แล้วทีนี้ เราจะใช้รัศมีค่าไหนในการสร้างวงกลมล่ะ ?
สิ่งที่ผมต้องการ ก็แค่ต้องการไม่ให้ยอดแหลมใดๆเกินออกมานอกวงกลม ดังนั้น ผมจึงเลือกใช้รัศมีที่มีค่ามากที่สุดมาเป็นรัศมีของวงกลม ด้วย code นี้
if(RVertical > RSqrt)
{
RCircle = RVertical;
}
else
{
RCircle = RSqrt;
}
ทีนี้ ผมก็จะได้ค่า RCircle มาเป็นรัศมีของวงกลมวงในแล้ว เย้ๆ
ส่วนวงกลมวงนอก ผมก็สร้างตัวแปรชื่อ SpaceBetweenCircle เพื่อเก็บค่าระยะห่างระหว่างวงกลมวงนอกและวงกลมวงใน
เวลาผมสร้างวงกลมวงนอก ผมก็นำ RCircle มาบวกกับ SpaceBetweenCircle แค่นี้ผมก็ได้วงกลมวงนอกแล้ว
แต่สุดท้าย เวลาสร้างรูป ผมต้องสร้างวงกลมวงนอกก่อน ตามด้วยวงกลมวงใน และปิดท้ายด้วยสร้างดาว เป็นอันเสร็จสมบูรณ์ เย้