import
java.io.*;
class
GFG {
public
static
void
main (String[] args) {
int
a[][] = {{
0
,
3
}, {
1
,
1
}, {
2
,
2
}, {
4
,
4
},
{
0
,
0
}, {
1
,
2
}, {
3
,
1
}, {
3
,
3
}};
int
[][] ans = FindConvexHull(a);
System.out.println(
"The points in Convex Hull are: "
);
for
(
int
i =
0
; i < ans.length; i++)
System.out.print(
"("
+ ans[i][
0
] +
","
+ ans [i][
1
]+
") "
);
}
public
static
int
[][] FindConvexHull(
int
[][] points_list)
{
int
n= points_list.length;
int
small =
0
;
for
(
int
i=
1
;i<n;i++){
if
( points_list[i][
1
] < points_list[small][
1
])
small = i;
}
if
(n ==
1
)
return
new
int
[][]{{-
1
, -
1
}};
int
t[] = points_list[small];
points_list[small] = points_list[
0
];
points_list[
0
] = t;
quickSort( points_list,
1
, n-
1
,
true
);
int
stack[] =
new
int
[n];
int
p=
1
;
stack[
0
] =
0
;
stack[
1
]=n-
1
;
for
(
int
i=n-
2
;i>
0
;i--){
long
prod = -
1
;
while
(prod <=
0
&& p>
0
){
int
p1[] = points_list[stack[p]];
int
p2[] = points_list[stack[p-
1
]];
long
y1 = p1[
1
]-p2[
1
];
long
x1 = p1[
0
]-p2[
0
];
long
x2 = points_list[i][
0
]-p1[
0
];
long
y2 = points_list[i][
1
]-p1[
1
];
prod = x1 * y2 - x2 * y1;
if
(prod <=
0
){
p--;
}
}
p++;
stack[p] = i;
}
if
(p+
1
<=
2
)
return
new
int
[][]{{-
1
, -
1
}};
int
ans[][] =
new
int
[p+
1
][
2
];
for
(
int
i=p;i>=
0
;i--){
ans[i] = points_list[stack[i]];
}
quickSort(ans,
0
,p,
false
);
return
ans;
}
public
static
void
quickSort(
int
arr[][],
int
low,
int
end,
boolean
flag){
if
(low >= end)
return
;
int
p = -
1
;
if
(flag)
p = partition(arr, low, end);
else
p = part(arr,low,end);
quickSort(arr, low, p-
1
, flag);
quickSort(arr, p+
1
,end, flag);
}
private
static
int
part(
int
arr[][],
int
low,
int
end){
int
p=low;
for
(
int
i=low+
1
;i <= end;i++){
if
((arr[i][
0
] < arr[p][
0
]) || (arr[i][
0
] == arr[p][
0
] && arr[i][
1
]< arr[p][
1
])){
low++;
int
t[] = arr[low];
arr[low] = arr[i];
arr[i] = t;
}
}
int
t[] = arr[low];
arr[low] = arr[p];
arr[p]=t;
return
low;
}
private
static
int
partition(
int
arr[][],
int
low,
int
end){
int
p = low;
double
a1 = angle(arr[low], arr[
0
]);
for
(
int
i=low+
1
;i <= end;i++){
double
a2 = angle(arr[i],arr[
0
]);
if
(a1 < a2){
low++;
int
t[] = arr[low];
arr[low] = arr[i];
arr[i] = t;
}
}
int
t[] = arr[low];
arr[low] = arr[p];
arr[p] = t;
return
low;
}
private
static
double
angle(
int
p1[],
int
p2[]){
double
x=p1[
0
]-p2[
0
];
double
y = p1[
1
] - p2[
1
];
return
-(x/Math.sqrt(x*x + y*y));
}
}