Line Equation From Two Points
EasyUpdated: Sep 13, 2025
Problem
Given two coordinates (x1, y1) and (x2, y2), construct the equation of the line that passes through both points.
The line through two distinct points can be written in point-slope form:
y - y1 = m (x - x1)
where the slope m = (y2 - y1) / (x2 - x1). For a vertical line (x1 == x2) the equation is x = x1.
Examples
Example 1
Input: (x1,y1) = (3,7), (x2,y2) = (5,11)
Output: y = 2x + 1
Explanation: slope = (11-7)/(5-3) = 2, intercept = 7 - 2*3 = 1
Example 2
Input: (x1,y1) = (2,2), (x2,y2) = (4,12)
Output: y = 5x - 8
Explanation: slope = (12-2)/(4-2) = 5, intercept = 2 - 5*2 = -8
Solution
Method 1 - Point-slope (direct computation)
Intuition
Two distinct points uniquely define a line. Compute the slope m using the two points and substitute into point-slope form to obtain the line equation. If the two points share the same x-coordinate the line is vertical and described by x = c.
Approach
- If (x1 == x2) return the vertical line
x = x1. - Compute slope m = (y2 - y1) / (x2 - x1) using floating-point arithmetic to handle non-integer slopes.
- Compute intercept b = y1 - m * x1.
- Return the line as (slope, intercept) or as a formatted equation
y = m x + b. - Edge cases:
- Identical points (x1 == x2 and y1 == y2): the line is undefined (infinite number of lines); treat as a degenerate input — you can return
Noneor indicate the points are identical.
- Identical points (x1 == x2 and y1 == y2): the line is undefined (infinite number of lines); treat as a degenerate input — you can return
Code
C++
class Solution {
public:
struct Point { double x, y; };
struct Line {
bool vertical;
double slope, intercept, x;
Line(double s, double c): vertical(false), slope(s), intercept(c), x(NAN) {}
Line(double xv): vertical(true), slope(NAN), intercept(NAN), x(xv) {}
};
Line lineFromPoints(const Point& a, const Point& b) {
const double EPS = 1e-12;
if (std::abs(a.x - b.x) < EPS && std::abs(a.y - b.y) < EPS) return Line(0.0, 0.0); // identical: degenerate
if (std::abs(a.x - b.x) < EPS) return Line(a.x); // vertical
double m = (b.y - a.y) / (b.x - a.x);
double c = a.y - m * a.x;
return Line(m, c);
}
};
Go
type Point struct{ X, Y float64 }
type Line struct{ Vertical bool; Slope, Intercept, X float64 }
func abs(x float64) float64 { if x < 0 { return -x }; return x }
func LineFromPoints(a, b Point) Line {
const EPS = 1e-12
if abs(a.X-b.X) < EPS && abs(a.Y-b.Y) < EPS { return Line{false, 0, 0, 0} } // identical
if abs(a.X-b.X) < EPS { return Line{true, 0, 0, a.X} }
m := (b.Y - a.Y) / (b.X - a.X)
c := a.Y - m*a.X
return Line{false, m, c, 0}
}
Java
class Solution {
static final double EPS = 1e-12;
static class Point { final double x, y; Point(double x, double y) { this.x = x; this.y = y; } }
static class Line {
final boolean vertical;
final double slope, intercept, x;
Line(double slope, double intercept) { this.vertical = false; this.slope = slope; this.intercept = intercept; this.x = Double.NaN; }
Line(double x) { this.vertical = true; this.slope = Double.NaN; this.intercept = Double.NaN; this.x = x; }
}
public Line lineFromPoints(Point a, Point b) {
if (Math.abs(a.x - b.x) < EPS && Math.abs(a.y - b.y) < EPS) return null; // identical points
if (Math.abs(a.x - b.x) < EPS) return new Line(a.x); // vertical
double m = (b.y - a.y) / (b.x - a.x);
double c = a.y - m * a.x;
return new Line(m, c);
}
}
Kotlin
data class Point(val x: Double, val y: Double)
class Solution {
data class Line(val vertical: Boolean, val slope: Double, val intercept: Double, val x: Double)
fun lineFromPoints(a: Point, b: Point): Line? {
val eps = 1e-12
if (kotlin.math.abs(a.x - b.x) < eps && kotlin.math.abs(a.y - b.y) < eps) return null
if (kotlin.math.abs(a.x - b.x) < eps) return Line(true, Double.NaN, Double.NaN, a.x)
val m = (b.y - a.y) / (b.x - a.x)
val c = a.y - m * a.x
return Line(false, m, c, Double.NaN)
}
}
Python
class Solution:
def line_from_points(self, a: tuple[float, float], b: tuple[float, float]) -> tuple[float, float] | tuple[str, float] | None:
EPS = 1e-12
x1, y1 = a
x2, y2 = b
if abs(x1 - x2) < EPS and abs(y1 - y2) < EPS:
return None
if abs(x1 - x2) < EPS:
return ("vertical", x1)
m = (y2 - y1) / (x2 - x1)
c = y1 - m * x1
return (m, c)
Rust
struct Point { x: f64, y: f64 }
struct Line { vertical: bool, slope: f64, intercept: f64, x: f64 }
fn line_from_points(a: &Point, b: &Point) -> Option<Line> {
let eps = 1e-12;
if (a.x - b.x).abs() < eps && (a.y - b.y).abs() < eps { return None; }
if (a.x - b.x).abs() < eps { return Some(Line { vertical: true, slope: f64::NAN, intercept: f64::NAN, x: a.x }); }
let m = (b.y - a.y) / (b.x - a.x);
let c = a.y - m * a.x;
Some(Line { vertical: false, slope: m, intercept: c, x: f64::NAN })
}
TypeScript
type Point = { x: number; y: number };
type Line = { vertical: boolean; slope?: number; intercept?: number; x?: number } | null;
function lineFromPoints(a: Point, b: Point): Line {
const EPS = 1e-12;
const abs = (v: number) => (v < 0 ? -v : v);
if (abs(a.x - b.x) < EPS && abs(a.y - b.y) < EPS) return null;
if (abs(a.x - b.x) < EPS) return { vertical: true, x: a.x };
const m = (b.y - a.y) / (b.x - a.x);
const c = a.y - m * a.x;
return { vertical: false, slope: m, intercept: c };
}
Complexity
- ⏰ Time complexity:
O(1)— Constant work to compute slope and intercept. - 🧺 Space complexity:
O(1)— Constant extra space for result and temporaries.