You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We can rotate a point by angle θ counter clockwise around origin (0, 0) by the following code,
Insert point code struct above it
#definePIacos(-1.0)
// important constant; alternative #define PI (2.0 * acos(0.0))// Angles conversion from 360 to rad
double DEG_to_RAD(double d) { return d * PI / 180.0; }
doubleRAD_to_DEG(double r) { return r * 180.0 / PI; }
point rotate(point p, double theta)
{
double rad = DEG_to_RAD(theta);
returnpoint(p.x * cos(rad) - p.y * sin(rad),
p.x * sin(rad) + p.y * cos(rad));
}
Reflection Point
Distance To Line
Two points a and b (a and b must be different) to make a line, find the closet point to line
Like closestPoint function but it's in a points form instead of standard line form
vec toVec(point a, point b){returnvec(b.x - a.x, b.y - a.y);}
point translate(point p, vec v){returnpoint(p.x + v.x , p.y + v.y);}
vec scale(vec v, double s){returnvec(v.x * s, v.y * s);}
doublenorm_sq(vec v) { return v.x * v.x + v.y * v.y; }
doubledist(point p1, point p2){returnhypot(p1.x - p2.x, p1.y - p2.y);}
doubledistToLine(point p, point a, point b, point &c)
{
// formula: c = a + u * ab
vec ap = toVec(a, p), ab = toVec(a, b);
double u = dot(ap, ab) / norm_sq(ab);
c = translate(a, scale(ab, u));
returndist(p, c);
}
Distance To Line Segment
Put all the functions of Distance to line, find the closet point to line segment
doubledistToLineSegment(point p, point a, point b, point &c)
{
vec ap = toVec(a, p), ab = toVec(a, b);
double u = dot(ap, ab) / norm_sq(ab);
if (u < 0.0)
{ // closer to a
c = point(a.x, a.y);
returndist(p, a);
}
if (u > 1.0)
{ // closer to b
c = point(b.x, b.y);
returndist(p, b);
}
returndistToLine(p, a, b, c);
}
Collinear
Returns true if point r is on the same line as the line pq
#defineEPS1e-9
vec toVec(point a, point b) {returnvec(b.x - a.x, b.y - a.y);}
doublecross(vec a, vec b) { return a.x * b.y - a.y * b.x; }
boolcollinear(point p, point q, point r)
{
returnfabs(cross(toVec(p, q), toVec(p, r))) < EPS;
}
Counter Clockwise
Returns true if point r is on the left side of line pq
vec toVec(point a, point b) {returnvec(b.x - a.x, b.y - a.y);}
doublecross(vec a, vec b) { return a.x * b.y - a.y * b.x; }
boolccw(point p, point q, point r)
{
returncross(toVec(p, q), toVec(p, r)) > 0;
}
Point On Line Segment
Check and see if point p1 is on the line segment s1 and s2
boolpointOnLineSegment(point p1, point s1, point s2)
{
// not inside itif ((s1 < p1 && s2 < p1) || (p1 < s1 && p1 < s2))
returnfalse;
returntrue;
}
// orboolpointOnSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
returntrue;
returnfalse;
}
Point On Line
boolpointOnLine(point p, point q, point r)
{
returncollinear(p, q, r)
}
#defineEPS1e-9boolareSame(line l1, line l2)
{ // also check coefficient creturnareParallel(l1 , l2) && (fabs(l1.c - l2.c) < EPS);
}
Intersect Lines
Returns true (+ intersection point) if two lines are intersect
#defineEPS1e-9boolareIntersect(line l1, line l2, point &p)
{
if (areParallel(l1, l2)) returnfalse;
// solve system of 2 linear algebraic equations with 2 unknowns
p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
// special case: test for vertical line to avoid division by zeroif (fabs(l1.b) > EPS) p.y = -(l1.a * p.x + l1.c);
else p.y = -(l2.a * p.x + l2.c);
returntrue;
}
Closet Point To Line
We have 3 cases Vertical, Horizontal or Normal line
Like distToLine function but it's in a line standard form instead of points form
boolareParallel(line l1, line l2)
{
return (fabs(l1.a - l2.a) < EPS) && (fabs(l1.b - l2.b) < EPS);
}
boolareIntersect(line l1, line l2, point &p)
{
if (areParallel(l1, l2)) returnfalse;
p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
if (fabs(l1.b) > EPS) p.y = -(l1.a * p.x + l1.c);
else p.y = -(l2.a * p.x + l2.c);
returntrue;
}
voidpointSlopeToLine(point p, double m, line &l)
{
l.a = -m;
l.b = 1;
l.c = -((l.a * p.x) + (l.b * p.y));
}
voidclosestPoint(line l, point p, point &ans)
{
line perpendicular; // perpendicular to l and pass through pif (fabs(l.b) < EPS)
{ // special case 1: vertical line//y of line and point is the same
ans.x = -(l.c); ans.y = p.y; return;
}
if (fabs(l.a) < EPS)
{ // special case 2: horizontal line;//x of line and point is the same
ans.x = p.x; ans.y = -(l.c); return;
}
// normal linepointSlopeToLine(p, 1 / l.a, perpendicular);
areIntersect(l, perpendicular, ans);
}
Two Lines Angle
The angle between two lines
#definePIacos(-1.0)
vec toVec(point a, point b) {returnvec(b.x - a.x, b.y - a.y);}
doubledot(vec a, vec b) { return (a.x * b.x + a.y * b.y); }
doublenorm_sq(vec v) { return v.x * v.x + v.y * v.y; }
doubleangle(point a, point o, point b)
{ // returns angle aob in rad
vec oa = toVec(o, a), ob = toVec(o, b);
returnacos(dot(oa, ob) / sqrt(norm_sq(oa) * norm_sq(ob)));
}
If I have only two corners (upper left and lower right corners) of the rectangle, I can find the other two
vector<point> P;
double x1, y1, x3, y3;
cin >> x1 >> y1 >> x3 >> y3;
P.push_back(point(x1,y1)); // upper left corner
P.push_back(point(x3,y1)); // upper right corner
P.push_back(point(x3,y3)); // lower right corner
p.push_back(point(x1,y3)); // lower left corner
Segments
Intersect Lines Segment
boolpointOnSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
returntrue;
returnfalse;
}
intorientation(Point p, Point q, Point r)
{
int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0) return0;
return (val > 0) ? 1 : 2;
}
booldoIntersect(Point p1, Point q1, Point p2, Point q2)
{
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
if (o1 != o2 && o3 != o4) returntrue;
if (o1 == 0 && onSegment(p1, p2, q1)) returntrue;
if (o2 == 0 && onSegment(p1, q2, q1)) returntrue;
if (o3 == 0 && onSegment(p2, p1, q2)) returntrue;
if (o4 == 0 && onSegment(p2, q1, q2)) returntrue;
returnfalse;
}