Category Archives: Geometry

Convex Hull Algorithm

#include <iostream>
#include <complex>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>

using namespace std;
typedef complex<double> point;

#define PI 3.141592653589793
#define EPS 0.0000000001
#define X real()
#define Y imag()
#define vec(a,b) ((b)-(a))
#define cross(a,b)  ((conj(a)*b).imag())
#define dot(a,b)  ((conj(a)*(b)).real())
#define length(a)  hypot((a).X,(a).Y)
#define lenSqr(a)  dot(a,a)
#define len(v) ((int)v.size)

point pivot(0,0);
bool collinear(point &a,point &b,point &c)
{
    return (fabs(cross(vec(a,b),vec(a,c))) < EPS);


}
bool ccw(point a,point b,point c)
{
    return cross(vec(a,b),vec(a,c)) > 0;
}
bool angleCmp(point a,point b)
{
    if(collinear(pivot,a,b))
    {
      return lenSqr(vec(pivot,a)) < lenSqr(vec(pivot,b));
    }
   return ccw(pivot,a,b);

}
vector<point> CH(vector<point> P)
{

    int i,N=(int)P.size();
    int po=0;
    for ( i=0;i<N-1;i++)
        if(P[i].Y < P[po].Y || (P[i].Y== P[po].Y && P[i].X < P[po].X))
            po=i;
    pivot = P[po];

    sort(P.begin(),P.end(),angleCmp);


    point prev(0,0),now(0,0);
    stack<point> S;
    S.push(pivot);
    i=1;
    while(i<N)
    {
        if(S.size()<2)
        {
            S.push(P[i++]);
        }
        else{
        now = S.top();
        S.pop();
        prev=S.top();
        S.push(now);
        if(ccw(prev,now,P[i]))
            S.push(P[i++]);
        else S.pop();
    }
    }

    vector<point> ConvexHull;
    ConvexHull.push_back(pivot);
    while(!S.empty())
    {

        ConvexHull.push_back(S.top());
        S.pop();
    }
    return ConvexHull;
}

3195. Doors and Penguins

get 2 convex hull and then make a pointInsidePoly check

#include <iostream>
#include <complex>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef complex<double> point;

#define PI 3.141592653589793
#define EPS 0.0000000001
#define X real()
#define Y imag()
#define vec(a,b) ((b)-(a))
#define cross(a,b)  ((conj(a)*b).imag())
#define dot(a,b)  ((conj(a)*b).real())
#define length(a)  hypot((a).X,(a).Y)
#define lenSqr(a)  dot(a,a)
#define len(v) ((int)v.size)
#define normalize(a)  (a)/(lenght(a))
point pivot(0,0);
bool collinear(point &a,point &b,point &c)
{
    return (fabs(cross(vec(a,b),vec(a,c))) < EPS);
}
bool angleCmp(point a,point b)
{
    if(collinear(pivot,a,b))
    {
      return lenSqr(vec(pivot,a)) < lenSqr(vec(pivot,b));
    }
   return (atan2(vec(pivot,a).Y,vec(pivot,a).X) - atan2(vec(pivot,b).Y,vec(pivot,b).X))<0;
}
bool ccw(point a,point b,point c)
{
    return cross(vec(a,b),vec(a,c)) >= 0;
}
bool myfunction (int i,int j) { return (i<j); }
vector<point> CH(vector<point> P)
{

    int i,N=(int)P.size();
    // return the vector
    if(N <=3){
    P.push_back(P[0]);
    return P;
    }
    int po=0;
    for ( i=0;i<N;i++)
        if(P[i].Y < P[po].Y || (P[i].Y== P[po].Y && P[i].X > P[po].X))
            po=i;
    point temp = P[0];
    P[0] = P[po];
    P[po]=temp;
    pivot = P[0];
    sort(++P.begin(),P.end(),angleCmp);

    point prev(0,0),now(0,0);
    stack<point> S;
    S.push(P[N-1]);
    S.push(P[0]);
    i=1;
    while(i<N)
    {

        now = S.top();
        S.pop();
        prev=S.top();
        S.push(now);
        if(ccw(prev,now,P[i]))
            S.push(P[i++]);
        else
        {
         S.pop();
    }
    }
    vector<point> ConvexHull;
    while(!S.empty())
    {

        ConvexHull.push_back(S.top());
        S.pop();
    }
    return ConvexHull;
}

double angle(point &a,point &b,point &c)
{
    double ux = b.X-a.X,uy =b.Y - a.Y;
    double vx = c.X-a.X,vy =c.Y - a.Y;
    return acos((ux*vx+uy*vy)/sqrt((ux*ux+uy*uy)*(vx*vx+vy*vy)));
}
bool inPolygon(point &p,vector<point> polygon)
{
    int n = (int)polygon.size();
    if(n==0)
    return false;
    double sum=0;
    for(int i=0;i<n-1;i++){
        point pp = polygon[i];
        point ppp= polygon[i+1];

        if(cross(vec(p,polygon[i]),vec(p,polygon[i+1])) <= 0)
            sum-=angle(p,polygon[i],polygon[i+1]);
        else sum+=angle(p,polygon[i],polygon[i+1]);
    }return fabs(sum-2*PI) < EPS || fabs(sum+2*PI) < EPS;

}

int main()
{
    int n,m;
    int t =1;
    while(scanf("%d %d",&n,&m)&&n!=0)
{
if(t!=1)
    printf("\n");
    vector<point> P1;
    int x1,x2,y1,y2;
    for(int i=0;i<n;i++)
    {
        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
        point p1(x1,y1);
        point p2(x2,y2);
        point p3(x1,y2);
        point p4(x2,y1);
        P1.push_back(p1);
        P1.push_back(p2);
        P1.push_back(p3);
        P1.push_back(p4);
    }
    vector<point> ans1;
    ans1 = CH(P1);
    vector<point> pp;
    bool check = true;
    for(int i=0;i<m;i++)
    {
        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
        point p1(x1,y1);
        point p2(x2,y2);
        point p3(x1,y2);
        point p4(x2,y1);
        pp.push_back(p1);
        pp.push_back(p2);
        pp.push_back(p3);
        pp.push_back(p4);
       if(inPolygon(p1,ans1) ||inPolygon(p2,ans1) ||inPolygon(p3,ans1) ||inPolygon(p4,ans1) )
            check = false;
    }
    vector<point> ans2;
    ans2 = CH(pp);
    for(int i=0;i<(int)ans1.size();i++)
    {
        point p = ans1[i];
       if(inPolygon(p,ans2) )
            check = false;
    }

    if(check)
    printf("Case %d: It is possible to separate the two groups of vendors.\n",t++);
    else printf("Case %d: It is not possible to separate the two groups of vendors.\n",t++);

}
    return 0;
}

Code Jam Beta 2008 Problem A. Triangle Trilemma

#include <iostream>
#include <complex>
#include <fstream>
#include <algorithm>
#include <cstdlib>

using namespace std;
typedef complex<double> point;
#define EPS 0.00000001
#define vec(a,b)  ((b)-(a))
#define cross(a,b) ((conj(a)*b).imag())
#define dot(a,b) ((conj(a)*b).real())
#define length(a)  dot(a,a)
bool pointOnRay(point &a,point &b,point &p)
{
    return fabs(cross(vec(a,b),vec(a,p)))<EPS;
}

bool pointOnSegment(point &a,point &b,point &p)
{
    if(length(vec(a,b))<EPS)
        return length(vec(a,p))<EPS;
    return pointOnRay(a,b,p)&&pointOnRay(b,a,p);
}
bool makeRight(point &a,point &b,point &c)
{
    return fabs(dot(vec(a,b),vec(a,c)))<EPS;
}
bool isIsos(point &a,point &b,point &c)
{
    return fabs(length(vec(a,b))-length(vec(a,c))) < EPS;
}
int main()
{
    int n,x1,x2,x3,y1,y2,y3;
    ifstream in ("A-large-practice.in");
    ofstream out ("A-large-practice.out");
    in >> n;
    for (int i=1;i<=n;i++)
    {
        in >> x1 >> y1 >>x2 >>y2 >>x3  >>y3  ;
        point a(x1,y1);
        point b(x2,y2);
        point c(x3,y3);
        bool ok = pointOnRay(a,b,c);
        if(ok==true)
        {
            out << "Case #" << i << ": not a triangle\n";
        }
        else{
        bool ok1 = isIsos(a,b,c)||isIsos(b,a,c)||isIsos(c,a,b);
        bool right = makeRight(a,b,c) || makeRight(b,a,c)||makeRight(c,a,b);
        bool acute = dot(vec(a,b),vec(a,c))>0 && dot(vec(b,a),vec(b,c))>0&&dot(vec(c,b),vec(c,a))>0;
        if (ok1) out << "Case #" << i <<": isosceles ";
        else out << "Case #" << i <<": scalene ";
        if(right)
        out<< "right triangle\n";
        else if(acute)
        out << "acute triangle\n";
        else out << "obtuse triangle\n";
        }
    }
    return 0;
}

SRM 550 DIV2 “RotatingBot” 550 problem

package SRM_550_DIV2;

import java.awt.geom.Line2D;

public class RotatingBot {
	public static int minArea(int[] moves) {
		int[][] lines = new int[moves.length][4];
		int dirc = 0;
		int x = 0;
		int y = 0;
		int minX = 0;
		int minY = 0;
		int maxX = 0;
		int maxY = 0;
		for (int i = 0; i < moves.length; i++) {
			if (dirc == 0) {
				lines[i][0] = x;
				lines[i][1] = y;
				lines[i][2] = x + moves[i];
				lines[i][3] = y;
				x = lines[i][2];

			} else if (dirc == 1) {
				lines[i][0] = x;
				lines[i][1] = y;
				lines[i][2] = x;
				lines[i][3] = y + moves[i];
				y = lines[i][3];
			} else if (dirc == 2) {
				lines[i][0] = x;
				lines[i][1] = y;
				lines[i][2] = x - moves[i];
				lines[i][3] = y;
				x = lines[i][2];
			} else if (dirc == 3) {
				lines[i][0] = x;
				lines[i][1] = y;
				lines[i][2] = x;
				lines[i][3] = y - moves[i];
				y = lines[i][3];

			}
			dirc++;
			dirc %= 4;
			minX = Math.min(minX, x);
			minY = Math.min(minY, y);
			maxX = Math.max(maxX, x);
			maxY = Math.max(maxY, y);
		}
		boolean check = true;
		for (int i = 0; i < lines.length && check; i++)
			for (int j = i + 2; j < lines.length && check; j++) {
				if (Line2D.linesIntersect(lines[i][0], lines[i][1],
						lines[i][2], lines[i][3], lines[j][0], lines[j][1],
						lines[j][2], lines[j][3])) {
					check = false;
				}
			}
		boolean[][] v = new boolean[maxY - minY + 1][maxX - minX + 1];
		int xx = Math.abs(0 - minX);
		int yy = Math.abs(0 - minY);
		for (int i = 0; i < lines.length; i++) {
			lines[i][0] += xx;
			lines[i][1] += yy;
			lines[i][2] += xx;
			lines[i][3] += yy;
		}

		int turn = 0;
		for (int i = 0; i < lines.length-1 && check; i++) {
			if (turn == 0) {
				for (int j = lines[i][0]; j <= lines[i][2]; j++)
					v[lines[i][1]][j] = true;
				if (lines[i][2] + 1 < v[0].length
						&& !v[lines[i][1]][lines[i][2] + 1])
					check = false;
			} else if (turn == 1) {
				for (int j = lines[i][1]; j <= lines[i][3]; j++)
					v[j][lines[i][0]] = true;
				if (lines[i][3] + 1 < v.length
						&& !v[lines[i][3] + 1][lines[i][0]])
					check = false;

			} else if (turn == 2) {
				for (int j = lines[i][0]; j >= lines[i][2]; j--)
					v[lines[i][1]][j] = true;
				if (lines[i][2] - 1 >= 0 && !v[lines[i][1]][lines[i][2] - 1])
					check = false;

			} else if (turn == 3) {
				for (int j = lines[i][1]; j >= lines[i][3]; j--)
					v[j][lines[i][0]] = true;
				if (lines[i][3] - 1 >= 0 && !v[lines[i][3] - 1][lines[i][0]])
					check = false;

			}
			turn++;
			turn %= 4;
		}
		if (!check)
			return -1;

		return (maxX - minX + 1) * (maxY - minY + 1);
	}

	public static void main(String[] args) {
		System.out.println(minArea(new int[] {5,4,5,3,3}));
	}

}

SRM 546 DIV 2 “TwoRectangles” 550 problem

i used a boolean array and fill with true the celss which represents the first rectangle and then used a counter to count the number of intersections if zero then none if one then point else i use an if statement to check whether it is a segment or a rectangle

package SRM_546_DIV_2;

public class TwoRectangles {
	public static String describeIntersection(int[] A, int[] B) {

		boolean[][] board = new boolean[1001][1001];
		for (int i = A[0]; i <= A[2]; i++)
			for (int j = A[1]; j <= A[3]; j++)
				board[i][j] = true;
		int count = 0;
		boolean flag = false;
		for (int i = B[0]; i <= B[2]; i++)
			for (int j = B[1]; j <= B[3]; j++) {
				if (board[i][j]) {
					count++;
				}
			}
		if (A[0] == B[2] || A[2] == B[0] || A[1] == B[3] || A[3] == B[1])
			flag = true;
		if (count == 0)
			return "none";
		else if (count == 1)
			return "point";
		else if (flag)
			return "segment";
		else
			return "rectangle";
	}

	public static void main(String[] args) {
		System.out.println(describeIntersection(
				new int[] { 28, 669, 700, 698 },
				new int[] { 28, 164, 700, 669 }));
	}
}