Witam miałem ostatnio taki problem. Chciałem narysować za pomocą biblioteki Allegro 5 wielokąt. W tej bibliotece owszem funkcja do tego była lecz nie rysowała "normalnego" wielokąta.
Tzn. czasem rysowała a czasem nie zależnie od tego jakie tam były punkty podane. Więc napisałem funkcje sam do tego i chcę się nią podzielić może się komuś do czegoś przyda.
A jak by ktoś wytłumaczył mi jak za pomocą samej Allegro to zrobić to też będę wdzięczny. Gdzieś przeczytałem że A5 rysuje tylko selfoverlaped poligons tylko nie wiem co to znaczy.
Wiem że może nie napisałem tego zbyt wydajnie no ale lepsze coś niż nic i może komuś się przyda.
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
bool bolik=true;
typedef double posu;
class punkt{
public:
posu x,y;
punkt(posu xp=0,posu yp=0,ALLEGRO_COLOR cp=al_map_rgb(255,255,255))
{
x=xp;
y=yp;
}
void pisz()
{
cout<<" ("<<x<<","<<y<<")"<<endl;
}
ALLEGRO_COLOR c;
};
bool operator<(punkt p1,punkt p2)
{
return p1.x<p2.x;
}
punkt operator+(punkt p1,punkt p2)
{
return punkt(p1.x+p2.x,p1.y+p2.y);
}
punkt operator-(punkt p1,punkt p2)
{
return punkt(p1.x-p2.x,p1.y-p2.y);
}
punkt rotatepoint(punkt ptr,punkt pw,double k)// funkcja obracająca punkt ptr wzglendem punku pw i zwracajaca juz obrucony
{
if(!k)return ptr;
punkt wynik;
double x1=ptr.x;
double y1=ptr.y;
double xo=pw.x;
double yo=pw.y;
wynik.x=(x1-xo)*cos(k) - (y1-yo)*sin(k)+xo;
wynik.y=(x1-xo)*sin(k) + (y1-yo)*cos(k)+yo;
return wynik;
}
void mm_draw_filled_polygon2(vector<punkt> v,ALLEGRO_COLOR c);
const int szer=800,wys=600;
ALLEGRO_DISPLAY * display = NULL;
ALLEGRO_EVENT_QUEUE * kolejka=NULL;
ALLEGRO_EVENT zdazenie;
ALLEGRO_TIMER * czas=NULL;
ALLEGRO_MOUSE_STATE state;
punkt m(szer/2,wys/2);
vector<punkt> wielok;
bool wci=false;
bool rysuj=false;
struct poligony{
vector<vector<punkt> > p;
vector<ALLEGRO_COLOR> c;
void rysuj()
{
for(int i=0;i<p.size();i++)
{
mm_draw_filled_polygon2(p[i],c[i]);
}
}
void obracaj(double a)
{
for(int i=0;i<p.size();i++)
for(int j=0;j<p[i].size();j++)
p[i][j]=rotatepoint(p[i][j],punkt(szer/2,wys/2),a);
}
};
poligony gony;
int main( int argc, char * argv[] )
{
unsigned char r=0;
/* Inicjalizacja biblioteki */
if( !al_init() )
{
fprintf( stderr, "Failed to initialize allegro!\n" );
return - 1;
}
al_install_keyboard();
al_install_mouse();
al_init_font_addon();
al_init_primitives_addon();
al_init_image_addon();
ALLEGRO_KEYBOARD_STATE klawiatura;
ALLEGRO_FONT* font8 = al_create_builtin_font();
int x=140,y=100;
int xm,ym;
double t=al_get_time();
kolejka=al_create_event_queue();
display = al_create_display( szer, wys );
if( !display )
{
fprintf( stderr, "Failed to create display!\n" );
return - 1;
}
al_register_event_source(kolejka,al_get_display_event_source(display));
czas=al_create_timer(1.0/30);
al_register_event_source(kolejka,al_get_timer_event_source(czas));
al_register_event_source(kolejka,al_get_keyboard_event_source());
al_start_timer(czas);
while(0){
al_wait_for_event(kolejka,&zdazenie);
if(zdazenie.type==ALLEGRO_EVENT_DISPLAY_CLOSE)
break;
if(zdazenie.type==ALLEGRO_EVENT_TIMER)
{
al_clear_to_color( al_map_rgb( ++r, 100, 150 ) );
al_flip_display();
}
}
double time=al_get_time();
string nap="dupa";
while(!al_key_down(&klawiatura,ALLEGRO_KEY_ESCAPE))//,al_draw_bitmap(bitmapa,x,y,0
{
al_get_keyboard_state(&klawiatura);
al_get_mouse_state(&state);
xm=state.x;
ym=state.y;
if(al_get_time()>time+0.01)
{
if(al_key_down(&klawiatura,ALLEGRO_KEY_R))rysuj=true;
if(al_key_down(&klawiatura,ALLEGRO_KEY_X)){
wielok.clear();
rysuj=false;
}
if(al_key_down(&klawiatura,ALLEGRO_KEY_B))
{
bolik=!bolik;
if(bolik)
nap="wlonczone";
else
nap="wylonczone";
}
time=al_get_time();
}
al_wait_for_event(kolejka,&zdazenie);
if(zdazenie.type==ALLEGRO_EVENT_KEY_CHAR)
{
int kl=0;
kl=zdazenie.keyboard.unichar;
//cout<<kl<<endl;
char asc = kl;// & 0xff;
//char scancode = kl >>8;
//if(asc>32 && asc<126)
nap+=asc;
//if(scancode==KEY_BACKSPACE)
//{
// if( nap.length()>0)
// nap=nap.substr(0,nap.length()-1);
//}
}
if(zdazenie.type==ALLEGRO_EVENT_DISPLAY_CLOSE)
break;
al_clear_to_color( al_map_rgb( ++r, 100, 150 ) );
al_draw_text(font8,al_map_rgb(0,255,0),100,100,0,nap.c_str());
int count=5;
if(rysuj)
mm_draw_filled_polygon2(wielok,al_map_rgba(0,0,0,123));
//gony.rysuj();
if(al_get_time()>12)
gony.obracaj(0.01);
if((state.buttons & 1)&&!wci)
{
wci=true;
wielok.push_back(punkt(xm,ym));
}
for(int i=0;i<wielok.size();i++)
al_draw_filled_ellipse(wielok[i].x,wielok[i].y,5,5,al_map_rgb(255,0,0));
if(state.buttons & 1)
wci=true;
else
wci=false;
al_flip_display();
}
// al_rest( 10.0 );
al_destroy_display( display );
al_destroy_event_queue(kolejka);
return 0;
}
void wyjmij(punkt t,vector<punkt>&v)
{
for(int i=0;i<v.size();i++)
{
if(t.x==v[i].x&&t.y==v[i].y)
v.erase(v.begin()+i);
}
}
struct lil{
double a,b;
punkt p1,p2;
bool ruw;
posu minx,miny,maxx,maxy;
void oblicz()
{
if(p1.x==p2.x)
{
ruw=true;
return;
}
ruw=false;
a=(p1.y-p2.y)/(p1.x-p2.x);
b=p1.y-a*p1.x;
}
bool jest(posu y)
{
if(y>miny&&y<maxy)
return true;
return false;
}
punkt traw(posu y)
{
if(!ruw && jest(y))
return punkt((y-b)/a,y);// y=ax+b / y-b=ax x=(y-b)/a
else
return punkt(0,0);
}
punkt wart(posu x){
if(x<minx||x>maxx)
return punkt(0,0);
else if(ruw)
return punkt(0,0);
else
return punkt(x,a*x+b);
}
lil(punkt p1p,punkt p2p)
{
p1=p1p;
p2=p2p;
minx=min(p1.x,p2.x);
maxx=max(p1.x,p2.x);
miny=min(p1.y,p2.y);
maxy=max(p1.y,p2.y);
oblicz();
}
};
bool isiny(posu y,vector<punkt>&v,vector<punkt>&v2)
{
int prew,next;
bool dxp,dyp,dxn,dyn;
bool w=false;
for(int i=0;i<v.size();i++)
{
if(i==v.size()-1)
{
prew=i-1;
next=0;
}else if(i==0)
{
prew=v.size()-1;
next=i+1;
}else{
prew=i-1;
next=i+1;
}
if(v[i].y==y)
{
// dxp=v[prew].x<v[i].x;
/// dxn=v[next].x<v[i].x;
dyp=v[prew].y<v[i].y;
dyn=v[next].y<v[i].y;
if(dyp==dyn||!dyp==!dyn)
wyjmij(v[i],v2);
else{
v2.push_back(v[i]);
w=true;
}
}
}
return w;
}
void mm_draw_filled_polygon2(vector<punkt> v,ALLEGRO_COLOR c)
{
//cout<<"wykonuje funkcje: mm_draw_filled_polygon2"<<endl;
vector<lil> linie;
for(int i=0;i<v.size();i++)
{
if(i==v.size()-1)
linie.push_back(lil(v[i],v[0]));
else
linie.push_back(lil(v[i],v[i+1]));
}
vector<punkt> zakazane;
vector<punkt> punkty;
punkt temp;
bool byl=false;
int fr,to;
for(int y=0;y<wys;y++)
{
//cout<<"poczatek lini:"<<endl;
for(int i=0;i<linie.size();i++)
{
if(linie[i].jest(y)){
// temp.pisz();
temp=linie[i].traw(y);
for(int i=0;i<punkty.size();i++)
if((int)punkty[i].x==(int)temp.x)
continue;
punkty.push_back(temp);
}
else
continue;
}
//cout<<"koniec lini:"<<endl;
if(bolik)isiny(y,v,punkty);
sort(punkty.begin(),punkty.end());
bool draw=true;
for(int i=0;i<punkty.size();i++)
{
fr=punkty[i].x;
to=punkty[i+1].x;
if(draw)
al_draw_line(fr,y,to,y,c,1);//pasek(y,fr,to,c);
draw=!draw;
}
punkty.clear();
}
}