19100016tama Saha

Download as pdf or txt
Download as pdf or txt
You are on page 1of 57

Department: COMPUTER SCIENCE AND ENGINEERING

Trimester: Fall 2021

Program: Bachelor of Computer Science and Engineering


Course Title: Computer Graphics Lab
Course Code : CSE 422

LAB REPORT FOR FINAL EXAMINATION EVALUATION

Stud_Name: Tama Saha


Stud_ID: 19100016

Stud_Batch: 15th

Submission Date: 17th January, 2022

Course Teacher: Tanjina Akter

NARAYANGANJ 2022
Experiment No: 1
Experiment Name: Create a line by using DDA and Bresenham’s line drawing
Algorithm.
Line by using DDA line drawing Algorithm: DDA Algorithm is the simplest line
drawing algorithm. DDA stands for Digital Differential Analyzer. It is an
incremental method of scan conversion of line. In this method calculation is
performed at each step but by using results of previous steps. Given the starting
and ending coordinates of a line, DDA Algorithm attempts to generate the points
between the starting and ending coordinates.
Code:
#include <graphics.h>
#include <stdio.h>
#include <math.h>
#include <dos.h>

int main( )
{
float x,y,x1,y1,x2,y2,dx,dy,step;
int i,gd=DETECT,gm;

initgraph(&gd,&gm,"");

printf("Enter the value of x1 and y1 : ");


scanf("%f%f",&x1,&y1);
printf("Enter the value of x2 and y2: ");
scanf("%f%f",&x2,&y2);

dx=abs(x2-x1);
dy=abs(y2-y1);

if(dx>=dy)
step=dx;
else
step=dy;

dx=dx/step;
dy=dy/step;

x=x1;
y=y1;

i=1;
while(i<=step)
{
putpixel(x,y,YELLOW);
x=x+dx;
y=y+dy;
i=i+1;
delay(500);
}

closegraph();
return 0;
}
Input:

Output:
Bresenham’s line drawing Algorithm: Bresenham Line Drawing Algorithm
determines the points of an n-dimensional raster that should be selected in
order to form a close approximation to a straight line between two points. To
draw the line, we have to compute first the slope of the line form two given
points.
Code:
#include<stdio.h>
#include<graphics.h>
#include<dos.h>
void drawline(int x0, int y0, int x1, int y1)
{
int dx, dy, p, x, y;
dx=x1-x0;
dy=y1-y0;
x=x0;
y=y0;
p=2*dy-dx;
while(x<x1)
{
if(p>=0)
{
putpixel(x,y,YELLOW);
y=y+1;
p=p+2*dy-2*dx;
}
else
{
putpixel(x,y,YELLOW);
p=p+2*dy;}

delay(500);
x=x+1;
}
}
int main()
{
int gdriver=DETECT, gmode, error, x0, y0, x1, y1;
initgraph(&gdriver, &gmode, "");
printf("Enter co-ordinates of first point: ");
scanf("%d%d", &x0, &y0);
printf("Enter co-ordinates of second point: ");
scanf("%d%d", &x1, &y1);
drawline(x0, y0, x1, y1);
delay(500);
return 0;
}
Input:
Output:

Experiment No: 2
Experiment Name: Create a line by using Bresenham’s Midpoint line drawing
Algorithm.
Bresenham’s Midpoint line drawing Algorithm: It is an incremental line drawing
algorithm. In this algorithm, we perform incremental calculations. The
calculations are based on the previous step to find the value of the next point.
We perform the same process for each step. By using the mid-point subdivision
algorithm, we can draw a line with close approximation between two points.
The mid-point subdivision line drawing algorithm subdivides the line at its
midpoints continuously.
Code:
#include<stdio.h>
#include<graphics.h>
#include<iostream>
#include<conio.h>
#include<dos.h>

void lineMidPoint(int x1, int y1, int x2, int y2)


{

int dx=x2-x1;
int dy=y2-y1;

int d=2*dy-dx;

int incrE = 2*dy;


int incrME = 2*(dy-dx);

int x=x1;
int y=y1;

putpixel(x, y, WHITE);
printf("%d,%d,\n",x,y);
while(x<x2)
{
if(d<=0){
d += incrE;
x++;
}
else{
d += incrME;
x++;
y++;
}
putpixel(x, y, WHITE);
printf("%d,%d,\n",x,y);
delay(500);
}

int main()
{
int gd = DETECT, gm, x1,y1,x2,y2;
initgraph (&gd, &gm, " ");

printf("Enter co-ordinates of first point: ");


scanf("%d%d", &x1, &y1);
printf("Enter co-ordinates of second point: ");
scanf("%d%d", &x2, &y2);
lineMidPoint(x1, y1, x2, y2);
getch();
return 0;
}
Input:
Output:
Experiment No: 3
Experiment Name: Create a circle by using Bresenham’s Midpoint Circle
Drawing Algorithm.
Midpoint Circle Drawing Algorithm: The midpoint circle drawing algorithm
helps us to calculate the complete perimeter points of a circle for the first octant.
We can quickly find and calculate the points of other octants with the help of
the first octant points. The remaining points are the mirror reflection of the first
octant points. In this algorithm, we define the unit interval and consider the
nearest point of the circle boundary in each step.
Code:
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<graphics.h>

void draw_circle(int,int,int);
void symmetry(int,int,int,int);

int main(){

int xc,yc,R;
int gd=DETECT,gm;
initgraph(&gd,&gm,"");
printf("Enter the center of the circle:\n");
printf("Xc =");
scanf("%d",&xc);
printf("Yc =");
scanf("%d",&yc);
printf("Enter the redious of the circle:\n");
scanf("%d",&R);
draw_circle(xc,yc,R);
getch();
closegraph();
}

void draw_circle(int xc, int yc, int red){

int x=0,y=red,p=1-red;
symmetry(x,y,xc,yc);

for(x=0;y>x;x++){

if(p<0)
p+= 2*x+3;

else{
p+= 2*(x-y)+5;
y--;
}
symmetry(x,y,xc,yc);
//delay(50);
}
}
void symmetry(int x, int y, int xc, int yc){

putpixel(xc+x,yc-y,GREEN); //For pixel(x,y)


delay(50);
putpixel(xc+y,yc-x,RED); //For pixel(y,x)
delay(50);
putpixel(xc+y,yc+x,GREEN); //For pixel(y,-x)
delay(50);
putpixel(xc+x,yc+y,RED); //For pixel()
delay(50);
putpixel(xc-x,yc+y,BLUE); //For pixel()
delay(50);
putpixel(xc-y,yc+x,YELLOW); //For pixel()
delay(50);
putpixel(xc-y,yc-x,BLUE); //For pixel()
delay(50);
putpixel(xc-x,yc-y,YELLOW); //For pixel()
delay(50);
}
Input:
Output:

Experiment No: 4
Experiment Name: Show the program on Translation, Rotation and Scaling
system of a triangle by using function.
Transformation: In Computer graphics, Transformation is a process of modifying
and re-positioning the existing graphics. 2D Transformations take place in a two-
dimensional plane. Transformations are helpful in changing the position, size,
orientation, shape etc. of the object.
Translation: A translation moves an object to a different position on the
screen. You can translate a point in 2D by adding translation coordinate (tx, ty)
to the original coordinate X,Y to get the new coordinate X′,Y′.
Rotation: In rotation, we rotate the object at particular angle θ theta from
its origin. From the following figure, we can see that the point P(X,Y) is located
at angle φ from the horizontal X coordinate with distance r from the origin.
Let us suppose you want to rotate it at the angle θ. After rotating it to a new
location, you will get a new point P’ X′,Y′.
Scaling: To change the size of an object, scaling transformation is used. In
the scaling process, you either expand or compress the dimensions of the object.
Scaling can be achieved by multiplying the original coordinates of the object with
the scaling factor to get the desired result.
Let us assume that the original coordinates are X,Y, the scaling factors are (SX,
SY), and the produced coordinates are X′,Y′.
Code:
#include<conio.h>
#include<math.h>
#include<graphics.h>
#include<stdlib.h>
#include<iostream>

int
gd=DETECT,gm,n,i,x[100],y[100],tx,ty,xne[100],yne[100],theta,sx,sy,rsx,rsy,xr,y
r;

void draw(){
setcolor(WHITE);
for(i=0;i<n;i++)
{
line(x[i],y[i],x[(i+1)%n],y[(i+1)%n]);

}
}

void translate(){
setcolor(RED);
printf("\nEnter the translator factors = ");
scanf("%d%d",&tx,&ty);
for(i=0;i<n;i++)
{
xne[i]=x[i]+tx;
yne[i]=y[i]+ty;
}
for(i=0;i<n;i++)
{
line(xne[i],yne[i],xne[(i+1)%n],yne[(i+1)%n]);
}
}

void rotation(){
setcolor(GREEN);
printf("\nEnter the rotation angle = ");
scanf("%d",&theta);
theta=(theta*3.14)/180;
printf("\nEnter reference points = ");
scanf("%d%d",&xr,&yr);
for(i=0;i<n;i++)
{
xne[i]=xr+(x[i]-xr)*cos(theta)-(y[i]-yr)*sin(theta);
yne[i]=yr+(x[i]-xr)*sin(theta)-(y[i]-yr)*cos(theta);
}
for(i=0;i<n;i++)
{
line(xne[i],yne[i],xne[(i+1)%n],yne[(i+1)%n]);
}
}

void scaling(){
setcolor(YELLOW);
printf("\nEnter scaling factors = ");
scanf("%d%d",&sx,&sy);
printf("\nEnter reference points = ");
scanf("%d%d",&rsx,&rsy);
for(i=0;i<n;i++)
{
xne[i]=x[i]*sx+rsx*(1-sx);
yne[i]=y[i]*sy+rsy*(1-sy);
}
for(i=0;i<n;i++)
{
line(xne[i],yne[i],xne[(i+1)%n],yne[(i+1)%n]);
}
}

int main(){
initgraph(&gd,&gm,"");
printf("\nEnter the number of co-ordinates of the polygon = ");
scanf("%d", &n);
printf("\nEnter the number of co-ordinates = ");
for(i=0;i<n;i++){
scanf("%d%d", &x[i],&y[i]);
}

draw();
scaling();
translate();
rotation();

getch();
closegraph();
return 0;
}

Input:
Output:
Experiment No: 5
Experiment Name: Show the program on Shearing Transformation on X axis
and Y axis.
Shearing Transformation: Shearing deals with changing the shape and size of
the 2D object along x-axis and y-axis. It is similar to sliding the layers in one
direction to change the shape of the 2D object. It is an ideal technique to change
the shape of an existing object in a two-dimensional plane.
Code:
#include<stdio.h>
#include<conio.h>
#include<graphics.h>

int main()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"");

int n, x[100],y[100], sh,i,axis;

printf("Enter the number of coordinates: ");


scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter the coordinates value: ");
scanf("%d %d",&x[i],&y[i]);
}
for(i=0;i<n;i++)
{
setcolor(WHITE);
line(x[i],y[i],x[(i+1)%n],y[(i+1)%n]);
}

printf("Enter the shear value: ");


scanf("%d",&sh);

printf("Enter 1 for shearing in x-axis.");


printf("Enter 0 for shearing in y-axis.");
printf("Enter the axis for shearing: ");
scanf("%d",&axis);
for(i=0;i<=n;i++)
{
if(axis==1)
{
setcolor(RED);
x[i] = x[i]+sh*y[i];
}
else
{
setcolor(BLUE);
y[i] = y[i]+sh*x[i];
}
}
for(i=0;i<n;i++)
{
line(x[i],y[i],x[(i+1)%n],y[(i+1)%n]);
}

getch();
closegraph();
return 0;
}

Input:

Output for x-axis:


Input:

Output for y-axis:


Experiment No: 6
Experiment Name: Show the operation on 8Connected and 4Connected Flood
Filling Algorithm.
Flood Filling Algorithm: In this method, a point or seed which is inside region is
selected. This point is called a seed point. Then four connected approaches or
eight connected approaches is used to fill with specified color. The flood fill
algorithm has many characters similar to boundary fill. But this method is more
suitable for filling multiple colors boundary. When boundary is of many colors
and interior is to be filled with one color we use this algorithm.
Code:
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<math.h>

void flood4(int,int,int,int);
void flood8(int,int,int,int);

int main()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"");
int x, x1,y1,x2,y2,x3,y3,x4,y4;
int xi,yi,c;

while(1)
{
printf("\n<----- 4 & 8 connected Flood filling Algorithm for Rectangle -----
>\n\n");

printf(" Enter rectangle coordinates ----->(put value clock wise)\n\n");


printf(" Enter the 1st point (x1, y1): ");
scanf("%d %d",&x1,&y1);
printf(" Enter the 2nd point (x2, y2): ");
scanf("%d %d",&x2,&y2);
printf(" Enter the 3rd point (x3, y3): ");
scanf("%d %d",&x3,&y3);
printf(" Enter the 4th point (x4, y4): ");
scanf("%d %d",&x4,&y4);

setcolor(4);
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x4,y4);
line(x4,y4,x1,y1);

printf("\nWhich type of filling you want to do");


printf("\n 1. 4 connected Flood filling\n 2. 8 connected Flood filling\n");
printf("\n Enter value between 1 to 2 : ");
scanf("%d",&x);

printf("\nNote: Filling start point must be inside rectangle!\n");


printf("Enter starting point (x,y): ");
scanf("%d %d",&xi,&yi);
printf("Set color(1 to 10): ");
scanf("%d",&c);

//4 connected Flood filling


if(x==1)
{
flood4(xi,yi,c,0);
}

//8 connected Flood filling


else if(x==2)
{
flood8(xi,yi,c,0);
}
else
printf("Invalid entry!");

}
getch();
closegraph();
}

void flood4(int x,int y, int fill_col, int old_col){

if(getpixel(x,y)==old_col){
delay(1);
putpixel(x,y,fill_col);

flood4(x+1,y,fill_col,old_col);
flood4(x-1,y,fill_col,old_col);
flood4(x,y+1,fill_col,old_col);
flood4(x,y-1,fill_col,old_col);
}
}
void flood8(int x,int y, int fill_col, int old_col){

if(getpixel(x,y)==old_col){
delay(1);
putpixel(x,y,fill_col);
flood8(x+1,y,fill_col,old_col);
flood8(x-1,y,fill_col,old_col);
flood8(x,y+1,fill_col,old_col);
flood8(x,y-1,fill_col,old_col);

flood8(x+1,y-1,fill_col,old_col);
flood8(x+1,y+1,fill_col,old_col);
flood8(x-1,y-1,fill_col,old_col);
flood8(x-1,y+1,fill_col,old_col);
}
}
Input:

Output for 4 connected:


Input:

Output for 8 connected:


Experiment No: 7
Experiment Name: Show the operation on 8Connected and 4 Connected
Boundary Filling Algorithm.
Boundary Filling Algorithm: Boundary Fill Algorithm starts at a pixel inside the
polygon to be filled and paints the interior proceeding outwards towards the
boundary. This algorithm works only if the color with which the region has to be
filled and the color of the boundary of the region are different. If the boundary
is of one single color, this approach proceeds outwards pixel by pixel until it hits
the boundary of the region.
Code:
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<graphics.h>
#include<math.h>

void boundary4(int,int,int,int);
void boundary8(int,int,int,int);

int main(){
int gd=DETECT,gm;
initgraph(&gd,&gm,””);
int x, x1,y1,x2,y2,x3,y3,x4,y4;
int xi,yi,c;

while(1){
printf(“\n--- 4 & 8 connected Boundary filling Algorithm for Rectangle ---
→\n\n”);
printf(“ Enter rectangle coordinates ---→(put value clock wise)\n\n”);
printf(“ Enter the 1st point (x1, y1): “);
scanf(“%d %d”,&x1,&y1);
printf(“ Enter the 2nd point (x2, y2): “);
scanf(“%d %d”,&x2,&y2);
printf(“ Enter the 3rd point (x3, y3): “);
scanf(“%d %d”,&x3,&y3);
printf(“ Enter the 4th point (x4, y4): “);
scanf(“%d %d”,&x4,&y4);

setcolor(4);
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x4,y4);
line(x4,y4,x1,y1);

printf(“\nWhich type of filling you want to do”);


printf(“\n 1. 4 connected boundary filling\n 2. 8 connected boundary
filling\n”);
printf(“\n Enter value between 1 to 2 : “);
scanf(“%d”,&x);

printf(“\nNote: Filling start point must be inside rectangle!\n”);


printf(“Enter starting point (x,y): “);
scanf(“%d %d”,&xi,&yi);
printf(“Set color(1 to 10): “);
scanf(“%d”,&c);

//4 connected Boundary filling


if(x==1){
boundary4(xi,yi,c,4);
}

//8 connected Boundary filling


else if(x==2){
boundary8(xi,yi,c,4);
}
else
printf(“Invalid entry!”);

}
getch();
closegraph();
}

void boundary4(int x,int y, int f_color,int b_color){

if((getpixel(x,y)!=b_color)&&(getpixel(x,y)!=f_color)){
delay(1);
putpixel(x,y,f_color);
boundary4(x+1,y,f_color,b_color);
boundary4(x,y+1,f_color,b_color);
boundary4(x+1,y+1,f_color,b_color);
boundary4(x-1,y-1,f_color,b_color);
}
}

void boundary8(int x,int y, int f_color,int b_color){

if((getpixel(x,y)!=b_color)&&(getpixel(x,y)!=f_color)){
delay(1);
putpixel(x,y,f_color);

boundary8(x+1,y,f_color,b_color);
boundary8(x,y+1,f_color,b_color);
boundary8(x+1,y+1,f_color,b_color);
boundary8(x-1,y-1,f_color,b_color);

boundary8(x-1,y,f_color,b_color);
boundary8(x,y-1,f_color,b_color);
boundary8(x-1,y+1,f_color,b_color);
boundary8(x+1,y-1,f_color,b_color);
}
}
Input:

Output for 4 connected:


Input:

Output for 8 connected:


Experiment No: 8
Experiment Name: Write the program on Bezier curve system.
Bezier curve system: Bezier curve is discovered by the French engineer Pierre
Bézier. These curves can be generated under the control of other points.
Approximate tangents by using control points are used to generate curve.
Code:
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>
#include<conio.h>

void bezier(int x[4], int y[4]){


int gd=DETECT,gm;
initgraph(&gd,&gm,"");
int i;
double t;

for(i=0.0; t<1.0; t+=0.0005){


double xt = pow(1-t,3)*x[0]+3*t*pow(1-t,2)*x[1] +
3*pow(t,2)*(1-t)*x[2]+pow(t,3)*x[3];

double yt = pow(1-t,3)*y[0]+3*t*pow(1-t,2)*y[1] +
3*pow(t,2)*(1-t)*y[2]+pow(t,3)*y[3];
putpixel(xt,yt, WHITE);
}
for(i=0;i<4;i++){
putpixel(x[i],y[i],YELLOW);
getch();
closegraph();
return;
}
}
int main(){
int i=0, x[4],y[4];

printf("\nEnter the x & y coordinates for the four control point.\n");


for(i=0;i<4;i++){
printf("\nEnter X%d & Y%d control point: ",i,i);
scanf("%d %d",&x[i],&y[i]);
}
bezier(x,y);
}
Input:
Output:
My Experiment for lab Final
Name of the experiment: Fishing Animation.
Description: This is a simple project showing a man catching fish near a pond
animation. After the thread of the fishing rod goes down into the water, the fish
gets caught. Finally, the man pulls up the thread along with the thread.
Code:
#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>

int a=0,b=0,c=0,d=0,e=0,f=0;
int g,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;
int p=0,q=0,r=0,s=0,t=0,u=0;
void man();
void land();
void sea();
void fish();
void thrd();
void stick();
void fish2();
void fish3();

int main()
{
int gdriver = DETECT,gmode;
initgraph(&gdriver,&gmode,"");

land();
sea();
man();
stick();
thrd();

delay(2000);
b=0;
//thrd down
for(g=0;g<17;g++)
{
thrd();
delay(100);
cleardevice();
sea();
man();
stick();
land();

b=b+3;
}
thrd();
delay(1000);
fish();

h=0;
//fish move
for(g=0;g<53;g++)
{
fish();
delay(100);
cleardevice();
sea();
man();
land();
stick();
thrd();
h=h+5;
}
fish();

//fish with thrd down


for(g=0;g<17;g++)
{
thrd();
fish();
delay(100);
cleardevice();
sea();
land();
man();
stick();
b=b+1;
i=i+1;
}
fish();
thrd();

fish2();
delay(100);
//thrd fish2 up
for(g=0;g<30;g++)
{
thrd();
fish2();
delay(50);
cleardevice();
land();
man();
sea();
stick();
b=b-3;
j=j+3;
}

thrd();
fish2();

for(g=0;g<18;g++)
{
stick();
fish2();
thrd();
delay(100);
cleardevice();
land();
man();
sea();
k=k+4;
n=n+4;
l=l+4;
m=m+2;
o=o+2;
}
stick();
fish2();
thrd();
delay(200);

cleardevice();
fish3();
stick();
thrd();
sea();
man();
land();

// up and down
for(u=0;u<10;u++)
{
//tail up
for(g=0;g<5;g++)
{
fish3();
delay(50);
cleardevice();
land();
sea();
man();
thrd();
stick();
r=r+2;
s=s+2;
t=t+2;
}
fish3();
delay(100);
//tail down
for(g=0;g<10;g++)
{
fish3();
delay(50);
cleardevice();
land();
sea();
man();
stick();
thrd();
r=r-1;
s=s-1;
t=t-1;
}
fish3();
}
fish3();
getch();
return 0;

}
void land()
{
//land
line(0,400,300,400);
line(300,400,300,470);
rectangle(150,377,190,400);
circle(600,50,30);
}
void sea()
{
//sea
d=0;
for(c=0;c<4;c++)
{
e=0;
for(a=0;a<10;a++)
{
ellipse(310+e,410+d,0,180,10,2);
ellipse(330+e,410+d,180,360,10,2);
e=e+40;
}
d=d+20;
}
}

void man()
{
//man
circle(170,300,10);
circle(174,297,1);
line(174,303,180,303);
line(168,310,168,317);
line(172,310,172,317);
rectangle(164,317,176,340);
//leg
line(164,340,166,370);
line(176,340,172,370);
rectangle(166,370,175,375);
floodfill(167,371,WHITE);
line(175,370,178,375);
//hand
line(170,325,178,335);
line(172,322,178,330);
line(178,335,188,330);
line(178,330,185,328);
rectangle(186,328,190,332);

}
void fish()
{
//fish
ellipse(620-h,440+i,0,360,10,4);
rectangle(610-h,440+i,616-h,440+i);
line(638-h,435+i,638-h,445+i);
line(638-h,435+i,630-h,440+i);
line(638-h,445+i,630-h,440+i);

}
void stick()
{
//stick
line(190,328,340-l,250-m);
line(190,330,340-l,252-m);
circle(341-l,252-m,5);

void thrd()
{

//thrd
line(346-n,254-o,346-n,390+b);
circle(346-n,350+b,4);
circle(346-n,390+b,2);
rectangle(342-n,390+b,350-n,392+b);

}
void fish2()
{
ellipse(347-k,467-j,0,360,4,10);
line(342-k,484-j,353-k,484-j);
line(342-k,484-j,347-k,477-j);
line(353-k,484-j,347-k,477-j);
line(347-k,457-j,347-k,463-j);

}
void fish3()
{
//fish
p=34;
q=5;
ellipse(240+p,390+q,0,360,10,4);
rectangle(232+p,390+q,236+p,390+q);
line(258+p-r,385+q-t,258+p-s,394+q-t);
line(258+p-r,385+q-t,250+p,390+q);
line(258+p-s,394+q-t,250+p,390+q);

}
Output:

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy