cppAcademy
← Learning PathLESSON 3 / 25 · COMPUTATIONAL GEOMETRY · 30 MIN✕

Dot Product

The dot product converts two vectors into a scalar measuring how strongly their directions align. It gives an exact angle-sign test on bounded integer coordinates and also supports approximate angle recovery and projection. These operations solve right-angle tests, nearest-point questions and geometric optimization. The program compares two vectors from the origin, prints their angle type and finds the projection of the first onto the second.

Prerequisites: Points and Vectors; cosine and perpendicularity.

Build the idea

  1. Connect algebra to angle

    For u=(ux,uy),v=(vx,vy), define u·v=ux·vx+uy·vy. Geometry gives u·v=|u||v|cosθ. For nonzero nonparallel vectors, a positive value means an acute angle, zero a right angle and a negative value an obtuse angle. Parallel vectors have angle zero in the same direction or 180 degrees in opposite directions; the code labels these ZERO ANGLE and STRAIGHT separately. Integer sign tests need no trigonometry and remain exact within the documented bounds.

  2. Derive projection

    The projection lies on the line through v, so write it as t·v. The residual u−t·v must be perpendicular to v. Taking its dot product with v gives u·v−t(v·v)=0, hence t=(u·v)/(v·v). This projection is onto an infinite line through the origin; clamping t is a separate operation for a segment.

    u·v=ux·vx+uy·vy

  3. Recover an angle only when needed

    Divide the dot product by the product of lengths, clamp the resulting cosine to [−1,1], and use acos. Rounding could otherwise create a value slightly above 1 and produce an invalid result. Convert radians to degrees using 180/π. A zero input vector has no angle or projection direction, so the program prints UNDEFINED after the dot value.

  4. Trace perpendicular vectors

    For u=(3,4), v=(4,−3), the products 12 and −12 cancel, yielding zero. Their angle is 90 degrees. The projection multiplier is zero, giving (0,0). If v were (1,0), the projection would instead be (3,0), demonstrating that projecting preserves only the component along the chosen direction.

  5. Match representation to operations

    Point stores integer components bounded by 10^6, so each dot product magnitude is at most 2·10^12. Multiplying two squared lengths could exceed long long; the code converts one operand to long double before multiplying for the cosine denominator. The factor is also floating-point to avoid truncating a fractional projection. Only the dot value and angle classification are exact; determinant zero separates the two parallel cases.

C++17 implementation

This is a complete program. Compile with C++17 and enter the input described below.

#include<iostream>
#include<cmath>
#include<algorithm>
#include<iomanip>
struct Point{
    long long x,y;
};
long long dot(Point a,Point b){
    return a.x*b.x+a.y*b.y;
}
int main(){
    Point u,v;
    std::cin>>u.x>>u.y>>v.x>>v.y; // Each coordinate within +/-10^6.
    long long product=dot(u,v),uu=dot(u,u),vv=dot(v,v);
    std::cout<<product<<'\n';
    if(uu==0||vv==0){
        std::cout<<"UNDEFINED\n";
        return 0;
    }
    long long determinant=u.x*v.y-u.y*v.x;
    std::cout<<(determinant==0?(product>0?"ZERO ANGLE":"STRAIGHT")
                            :product==0?"RIGHT"
                            :product>0?"ACUTE"
                                        :"OBTUSE")
                <<'\n';
    long double cosine=(long double)product/std::sqrt((long double)uu*vv);
    cosine=std::clamp(cosine,-1.0L,1.0L); // Protect acos from rounding outside its domain.
    // The projection multiplier solves (u - factor*v) dot v = 0.
    long double factor=(long double)product/vv;
    std::cout<<std::fixed<<std::setprecision(6)<<std::acos(cosine)*180/std::acos(-1.0L)<<'\n'
                <<(factor*v.x==0?0.0L:factor*v.x)<<' '<<(factor*v.y==0?0.0L:factor*v.y)
                <<'\n';
}

Complexity analysis

O(1) time and auxiliary space. Exact dot/sign work uses integer arithmetic; acos and projection add a constant number of floating operations.

Common mistakes and edge cases. Do not multiply squared lengths as integers before casting. Avoid integer division in the projection factor. Orthogonality of a zero vector is algebraically true but does not define an angle. Clamp an approximate cosine, not the exact integer dot product.

Example input and output

Read ux uy vx vy as integers within ±10^6. Print the dot product. For two nonzero vectors also print angle type, approximate degrees, and projection of u onto v; otherwise print UNDEFINED.

Input

3 4 4 -3

Output

0
RIGHT
90.000000
0.000000 0.000000

The scalar product is 12−12=0, so the nonzero vectors are perpendicular and the projection vanishes.

Practical applications

Use dot products for angle signs, orthogonal projections, point-to-segment distances and checking whether a point lies before or beyond an endpoint. Use cross products when the question is left versus right, which dot products cannot determine.

Check your understanding

What does a negative dot product imply for nonzero, nonparallel vectors?

Put it into practice

Test parallel, opposite and zero vectors.

Show a hint

Check which outputs remain meaningful when a direction has length zero.

Further reading