Saya sudah membahas tentang cara mewarnai segi-n beraturan.
Selanjutnya, saya akan membahas tentang cara mengetahui apakah suatu
titik berada di dalam atau di luar segi-n beraturan. Dasarnya hampir
sama dengan saat mewarnai segi-N yaitu dengan membaginya menjadi
beberapa segitiga. Kita bisa memodifikasi function untuk mengecek
tabrakan segitiga. Kita bisa menggunakan loop dan sin cos untuk
menentukan posisi titik dalam segitiga-segitiga yang kita dapatkan dari
potongan segi-N.
Selain menggunakan fungsi untuk mengecek tabrakan, kita juga bisa menggunakan function untuk menggambar segi-N. Function tersebut membutuhkan function untuk menggambar segitiga. Setelah kode program diketik atau dicopas ke project atau file source code, silakan compile dan jalankan programnya! Program akan menampilkan segi-N yang berubah warna jika dilewati mouse.
float tanda (SDL_Point *p1, SDL_Point *p2, SDL_Point *p3){
return (p1->x - p3->x) * (p2->y - p3->y) - (p2->x - p3->x) * (p1->y - p3->y);
}
int cekTabrakan (SDL_Point *pt, int xpos, int ypos, int r, int n){
float t1, t2, t3;
int tabrakan=0;
float sudut, putaran;
SDL_Point p1, p2, p3;
p1.x=xpos;
p1.y=ypos;
sudut=360/n;
putaran=sudut;
p2.x=cos(0)*r+xpos;
p2.y=sin(0)*r+ypos;
for(int i=1;i<=n;i++){
p3.x=cos(grad*putaran)*r+xpos;
p3.y=sin(grad*putaran)*r+ypos;
t1 = tanda(pt, &p1, &p2);
t2 = tanda(pt, &p2, &p3);
t3 = tanda(pt, &p3, &p1);
if((t1 <= 0 && t2 <= 0 && t3 <= 0) || (t1 >= 0 && t2 >= 0 && t3 >= 0)){
tabrakan=1;
break;
}
p2.x=p3.x;
p2.y=p3.y;
putaran+=sudut;
if(putaran>=360)putaran=0;
}
return tabrakan;
}
Fungsi cekTabrakan di atas bisa kita gunakan dalam kode
program. Parameternya secara berurutan adalah pointer mouse, koordinat
titik x, koordinat titik y, radius, dan jumlah sisi atau titik sudutnya.
Karena itu adalah modifikasi dari function pengecekan titik dalam segitiga, maka kita juga akan butuh function tanda untuk mempersingkat penulisan function. Kita bisa menggabungkannya dengan program utama sehingga jadi seperti
di bawah ini.
#include <SDL2/SDL.h>
#include <math.h>
#define playar 640
#define tlayar 480
#define grad 3.14285714286/180
SDL_Renderer *trender=NULL;
float tanda (SDL_Point *p1, SDL_Point *p2, SDL_Point *p3){
return (p1->x - p3->x) * (p2->y - p3->y) - (p2->x - p3->x) * (p1->y - p3->y);
}
int cekTabrakan (SDL_Point *pt, int xpos, int ypos, int r, int n){
float t1, t2, t3;
int tabrakan=0;
float sudut, putaran;
SDL_Point p1, p2, p3;
p1.x=xpos;
p1.y=ypos;
sudut=360/n;
putaran=sudut;
p2.x=cos(0)*r+xpos;
p2.y=sin(0)*r+ypos;
for(int i=1;i<=n;i++){
p3.x=cos(grad*putaran)*r+xpos;
p3.y=sin(grad*putaran)*r+ypos;
t1 = tanda(pt, &p1, &p2);
t2 = tanda(pt, &p2, &p3);
t3 = tanda(pt, &p3, &p1);
if((t1 <= 0 && t2 <= 0 && t3 <= 0) || (t1 >= 0 && t2 >= 0 && t3 >= 0)){
tabrakan=1;
break;
}
p2.x=p3.x;
p2.y=p3.y;
putaran+=sudut;
if(putaran>=360)putaran=0;
}
return tabrakan;
}
int gambarSegiN(int xpos, int ypos, int r, int n){
float x, y, xprev, yprev, sudut, putaran;
putaran=0;
sudut=360/n;
xprev=cos(0)*r+xpos;
yprev=sin(0)*r+ypos;
for(int i=0;i<=n;i++){
x=cos(grad*putaran)*r+xpos;
y=sin(grad*putaran)*r+ypos;
SDL_RenderDrawLine(trender, xprev, yprev, x, y);
xprev=x;
yprev=y;
putaran+=sudut;
if(putaran>=360)putaran=0;
}
return 0;
}
int warnaiSegitiga(SDL_Point *s1, SDL_Point *s2, SDL_Point *s3){
int x, y;
float mx, my;
SDL_Point *tmp;
if(abs(s1->x-s2->x) > abs(s1->y-s2->y)){
if(s1->x > s2->x){
tmp=s1;
s1=s2;
s2=tmp;
}
mx=s2->x-s1->x;
my=s2->y-s1->y;
for(int i=0;i<mx;i++){
x=s1->x+i;
y=s1->y+(i*my/mx);
SDL_RenderDrawLine(trender, x, y, s3->x, s3->y);
SDL_RenderDrawLine(trender, x, y+1, s3->x, s3->y);//kalau garisnya nggak miring sepertinya ini nggak diperlukan
}
}else{
if(s1->y>s2->y){
tmp=s1;
s1=s2;
s2=tmp;
}
mx=s2->x-s1->x;
my=s2->y-s1->y;
for(int i=0;i<my;i++){
x=s1->x+(i*mx/my);
y=s1->y+i;
SDL_RenderDrawLine(trender, x, y, s3->x, s3->y);
SDL_RenderDrawLine(trender, x+1, y, s3->x, s3->y);//kalau garisnya nggak miring sepertinya ini nggak diperlukan
}
}
}
int warnaiSegiN(int xpos, int ypos, int r, int n){
float sudut, putaran;
SDL_Point p1, p2, p3;
p1.x=xpos;
p1.y=ypos;
sudut=360/n;
putaran=sudut;
p2.x=cos(0)*r+xpos;
p2.y=sin(0)*r+ypos;
for(int i=1;i<=n;i++){
p3.x=cos(grad*putaran)*r+xpos;
p3.y=sin(grad*putaran)*r+ypos;
warnaiSegitiga(&p1, &p2, &p3);
p2.x=p3.x;
p2.y=p3.y;
putaran+=sudut;
if(putaran>=360)putaran=0;
}
return 0;
}
int main(int argc, char* args[]){
SDL_Window* window = NULL;
SDL_Event evt;
SDL_Point pt;
SDL_Point stiga[]={{10, 10}, {300, 50}, {200, 300}, {10, 10}};
if( SDL_Init( SDL_INIT_VIDEO ) < 0){
printf( "Error: %s\n", SDL_GetError() );
}else{
window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, playar, tlayar, SDL_WINDOW_SHOWN );
if( window == NULL ){
printf( "Error : %s", SDL_GetError() );
}else{
trender = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
while(evt.type!=SDL_QUIT){
while(SDL_PollEvent(&evt)){
}
SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(trender);
pt.x=evt.button.x;
pt.y=evt.button.y;
if(cekTabrakan(&pt, 100, 100, 100, 6)==1)SDL_SetRenderDrawColor(trender, 0x00, 0x00, 0xFF, 0xFF);
else SDL_SetRenderDrawColor(trender, 0xFF, 0x00, 0x00, 0xFF);
warnaiSegiN(100, 100, 100, 6);
SDL_RenderPresent(trender);
}
}
}
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
Selain menggunakan fungsi untuk mengecek tabrakan, kita juga bisa menggunakan function untuk menggambar segi-N. Function tersebut membutuhkan function untuk menggambar segitiga. Setelah kode program diketik atau dicopas ke project atau file source code, silakan compile dan jalankan programnya! Program akan menampilkan segi-N yang berubah warna jika dilewati mouse.