or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-objects.mdcurved-geometry.mdindex.mdlinear-geometry.mdmeasurement.mdtransforms-plotting.md

linear-geometry.mddocs/

0

# Linear Geometry

1

2

Lines, line segments, and planes with comprehensive geometric operations including projections, intersections, and distance calculations. Supports both infinite geometric objects and bounded segments with best-fit operations for data analysis.

3

4

## Capabilities

5

6

### Line

7

8

Represents an infinite line in N-dimensional space defined by a point and direction vector. Provides comprehensive geometric operations including projections, intersections, and transformations.

9

10

```python { .api }

11

class Line:

12

"""

13

An infinite line in N-dimensional space.

14

15

Parameters:

16

- point: array-like, a point on the line

17

- direction: array-like, direction vector of the line

18

"""

19

def __init__(self, point, direction): ...

20

21

@classmethod

22

def from_points(cls, point_a, point_b) -> 'Line':

23

"""

24

Create line from two points.

25

26

Parameters:

27

- point_a: array-like, first point

28

- point_b: array-like, second point

29

30

Returns:

31

Line passing through both points

32

"""

33

34

@classmethod

35

def from_slope(cls, slope, y_intercept) -> 'Line':

36

"""

37

Create 2D line from slope and y-intercept.

38

39

Parameters:

40

- slope: float, slope of the line

41

- y_intercept: float, y-intercept value

42

43

Returns:

44

2D line with specified slope and intercept

45

"""

46

47

@classmethod

48

def best_fit(cls, points, tol=None, return_error=False, **kwargs) -> 'Line':

49

"""

50

Find line of best fit for points.

51

52

Parameters:

53

- points: array-like, points to fit line to

54

- tol: float, optional tolerance for singular value decomposition

55

- return_error: bool, if True return fit error

56

- **kwargs: additional keywords passed to numpy functions

57

58

Returns:

59

Best fit line, optionally with error value

60

"""

61

62

@property

63

def point(self) -> Point:

64

"""Point on the line."""

65

66

@property

67

def direction(self) -> Vector:

68

"""Direction vector of the line (same as vector)."""

69

70

@property

71

def vector(self) -> Vector:

72

"""Direction vector of the line (same as direction)."""

73

74

@property

75

def dimension(self) -> int:

76

"""Dimension of the line."""

77

78

def is_coplanar(self, other, **kwargs) -> bool:

79

"""

80

Check if coplanar with another line.

81

82

Parameters:

83

- other: Line, another line

84

- **kwargs: additional keywords passed to numpy functions

85

86

Returns:

87

True if lines are coplanar

88

"""

89

90

def to_point(self, t=1) -> Point:

91

"""

92

Get point along line using parameter t.

93

94

Parameters:

95

- t: float, parameter value (default: 1)

96

97

Returns:

98

Point at position: point + t * direction

99

"""

100

101

def project_point(self, point) -> Point:

102

"""

103

Project point onto line.

104

105

Parameters:

106

- point: array-like, point to project

107

108

Returns:

109

Projected point on the line

110

"""

111

112

def project_points(self, points) -> Points:

113

"""

114

Project multiple points onto line.

115

116

Parameters:

117

- points: array-like, points to project

118

119

Returns:

120

Projected points on the line

121

"""

122

123

def project_vector(self, vector) -> Vector:

124

"""

125

Project vector onto line.

126

127

Parameters:

128

- vector: array-like, vector to project

129

130

Returns:

131

Projected vector along line direction

132

"""

133

134

def side_point(self, point) -> int:

135

"""

136

Find side of line where point lies (2D only).

137

138

Parameters:

139

- point: array-like, 2D point

140

141

Returns:

142

1 if left side, -1 if right side, 0 if on line

143

"""

144

145

def distance_point(self, point) -> np.float64:

146

"""

147

Calculate distance from point to line.

148

149

Parameters:

150

- point: array-like, point

151

152

Returns:

153

Perpendicular distance to line

154

"""

155

156

def distance_points(self, points) -> np.ndarray:

157

"""

158

Calculate distances from points to line.

159

160

Parameters:

161

- points: array-like, multiple points

162

163

Returns:

164

Array of distances to line

165

"""

166

167

def distance_line(self, other) -> np.float64:

168

"""

169

Calculate distance between lines.

170

171

Parameters:

172

- other: Line, another line

173

174

Returns:

175

Minimum distance between lines

176

"""

177

178

def intersect_line(self, other, check_coplanar=True, **kwargs) -> Point:

179

"""

180

Find intersection with another line.

181

182

Parameters:

183

- other: Line, another line

184

- check_coplanar: bool, check if lines are coplanar (default: True)

185

- **kwargs: additional keywords passed to numpy functions

186

187

Returns:

188

Intersection point

189

190

Raises:

191

ValueError if lines are parallel or skew

192

"""

193

194

def transform_points(self, points) -> np.ndarray:

195

"""

196

Transform points to 1D coordinates along line.

197

198

Parameters:

199

- points: array-like, points to transform

200

201

Returns:

202

1D coordinate array along line

203

"""

204

205

def contains_point(self, point, **kwargs) -> bool:

206

"""

207

Check if line contains point.

208

209

Parameters:

210

- point: array-like, point to check

211

- **kwargs: additional keywords passed to math.isclose

212

213

Returns:

214

True if point lies on line

215

"""

216

217

def is_close(self, other, **kwargs) -> bool:

218

"""

219

Check if close to another line.

220

221

Parameters:

222

- other: Line, another line

223

- **kwargs: additional keywords passed to numpy.allclose

224

225

Returns:

226

True if lines are close

227

"""

228

229

def sum_squares(self, points) -> np.float64:

230

"""

231

Calculate sum of squared distances from points.

232

233

Parameters:

234

- points: array-like, points

235

236

Returns:

237

Sum of squared distances

238

"""

239

240

def plot_2d(self, ax_2d, t_1=0, t_2=1, **kwargs):

241

"""

242

Plot 2D line segment.

243

244

Parameters:

245

- ax_2d: matplotlib Axes, 2D plotting axes

246

- t_1: float, start parameter (default: 0)

247

- t_2: float, end parameter (default: 1)

248

- **kwargs: additional keywords passed to plot

249

"""

250

251

def plot_3d(self, ax_3d, t_1=0, t_2=1, **kwargs):

252

"""

253

Plot 3D line segment.

254

255

Parameters:

256

- ax_3d: matplotlib Axes3D, 3D plotting axes

257

- t_1: float, start parameter (default: 0)

258

- t_2: float, end parameter (default: 1)

259

- **kwargs: additional keywords passed to plot

260

"""

261

```

262

263

**Usage Example:**

264

```python

265

from skspatial.objects import Line, Point

266

267

# Create line from point and direction

268

line = Line(point=[0, 0, 0], direction=[1, 1, 0])

269

270

# Create line from two points

271

line2 = Line.from_points([1, 2, 3], [4, 5, 6])

272

273

# Create 2D line from slope

274

line_2d = Line.from_slope(slope=2, y_intercept=1)

275

276

# Project point onto line

277

point = Point([5, 6, 7])

278

projected = line.project_point(point)

279

280

# Find intersection

281

intersection = line.intersect_line(line2)

282

283

# Line of best fit

284

import numpy as np

285

points = np.random.randn(20, 3)

286

best_fit_line = Line.best_fit(points)

287

```

288

289

### Plane

290

291

Represents an infinite plane in N-dimensional space defined by a point and normal vector. Provides comprehensive operations for projections, intersections, and geometric analysis.

292

293

```python { .api }

294

class Plane:

295

"""

296

An infinite plane in N-dimensional space.

297

298

Parameters:

299

- point: array-like, a point on the plane

300

- normal: array-like, normal vector to the plane

301

"""

302

def __init__(self, point, normal): ...

303

304

@classmethod

305

def from_vectors(cls, point, vector_a, vector_b, **kwargs) -> 'Plane':

306

"""

307

Create plane from point and two vectors.

308

309

Parameters:

310

- point: array-like, point on the plane

311

- vector_a: array-like, first vector in plane

312

- vector_b: array-like, second vector in plane

313

- **kwargs: additional keywords passed to numpy functions

314

315

Returns:

316

Plane defined by point and span of vectors

317

"""

318

319

@classmethod

320

def from_points(cls, point_a, point_b, point_c, **kwargs) -> 'Plane':

321

"""

322

Create plane from three points.

323

324

Parameters:

325

- point_a: array-like, first point

326

- point_b: array-like, second point

327

- point_c: array-like, third point

328

- **kwargs: additional keywords passed to numpy functions

329

330

Returns:

331

Plane passing through all three points

332

"""

333

334

@classmethod

335

def best_fit(cls, points, tol=None, return_error=False, **kwargs) -> 'Plane':

336

"""

337

Find plane of best fit for points.

338

339

Parameters:

340

- points: array-like, points to fit plane to

341

- tol: float, optional tolerance for singular value decomposition

342

- return_error: bool, if True return fit error

343

- **kwargs: additional keywords passed to numpy functions

344

345

Returns:

346

Best fit plane, optionally with error value

347

"""

348

349

@property

350

def point(self) -> Point:

351

"""Point on the plane."""

352

353

@property

354

def normal(self) -> Vector:

355

"""Normal vector to the plane (same as vector)."""

356

357

@property

358

def vector(self) -> Vector:

359

"""Normal vector to the plane (same as normal)."""

360

361

@property

362

def dimension(self) -> int:

363

"""Dimension of the plane."""

364

365

def cartesian(self) -> Tuple[np.float64, np.float64, np.float64, np.float64]:

366

"""

367

Return Cartesian equation coefficients.

368

369

Returns:

370

Tuple (a, b, c, d) for equation ax + by + cz = d

371

"""

372

373

def project_point(self, point) -> Point:

374

"""

375

Project point onto plane.

376

377

Parameters:

378

- point: array-like, point to project

379

380

Returns:

381

Projected point on the plane

382

"""

383

384

def project_points(self, points) -> Points:

385

"""

386

Project multiple points onto plane.

387

388

Parameters:

389

- points: array-like, points to project

390

391

Returns:

392

Projected points on the plane

393

"""

394

395

def project_vector(self, vector) -> Vector:

396

"""

397

Project vector onto plane.

398

399

Parameters:

400

- vector: array-like, vector to project

401

402

Returns:

403

Projected vector in the plane

404

"""

405

406

def project_line(self, line, **kwargs) -> Line:

407

"""

408

Project line onto plane.

409

410

Parameters:

411

- line: Line, line to project

412

- **kwargs: additional keywords passed to numpy functions

413

414

Returns:

415

Projected line in the plane

416

"""

417

418

def distance_point_signed(self, point) -> np.float64:

419

"""

420

Calculate signed distance from point to plane.

421

422

Parameters:

423

- point: array-like, point

424

425

Returns:

426

Signed distance (positive on normal side)

427

"""

428

429

def distance_points_signed(self, points) -> np.ndarray:

430

"""

431

Calculate signed distances from points to plane.

432

433

Parameters:

434

- points: array-like, multiple points

435

436

Returns:

437

Array of signed distances

438

"""

439

440

def distance_point(self, point) -> np.float64:

441

"""

442

Calculate absolute distance from point to plane.

443

444

Parameters:

445

- point: array-like, point

446

447

Returns:

448

Absolute distance to plane

449

"""

450

451

def distance_points(self, points) -> np.ndarray:

452

"""

453

Calculate absolute distances from points to plane.

454

455

Parameters:

456

- points: array-like, multiple points

457

458

Returns:

459

Array of absolute distances

460

"""

461

462

def side_point(self, point) -> int:

463

"""

464

Find side of plane where point lies.

465

466

Parameters:

467

- point: array-like, point

468

469

Returns:

470

1 if on normal side, -1 if opposite, 0 if on plane

471

"""

472

473

def intersect_line(self, line, **kwargs) -> Point:

474

"""

475

Find intersection with line.

476

477

Parameters:

478

- line: Line, line to intersect

479

- **kwargs: additional keywords passed to numpy functions

480

481

Returns:

482

Intersection point

483

484

Raises:

485

ValueError if line is parallel to plane

486

"""

487

488

def intersect_plane(self, other, **kwargs) -> Line:

489

"""

490

Find intersection with another plane.

491

492

Parameters:

493

- other: Plane, another plane

494

- **kwargs: additional keywords passed to numpy functions

495

496

Returns:

497

Intersection line

498

499

Raises:

500

ValueError if planes are parallel

501

"""

502

503

def to_mesh(self, lims_x=(-1, 1), lims_y=(-1, 1)):

504

"""

505

Generate mesh coordinates for plotting.

506

507

Parameters:

508

- lims_x: tuple, x-axis limits (default: (-1, 1))

509

- lims_y: tuple, y-axis limits (default: (-1, 1))

510

511

Returns:

512

X, Y, Z mesh arrays for plotting

513

"""

514

515

def to_points(self, **kwargs) -> Points:

516

"""

517

Return points on the plane surface.

518

519

Parameters:

520

- **kwargs: additional keywords for mesh generation

521

522

Returns:

523

Points sampled on plane surface

524

"""

525

526

def contains_point(self, point, **kwargs) -> bool:

527

"""

528

Check if plane contains point.

529

530

Parameters:

531

- point: array-like, point to check

532

- **kwargs: additional keywords passed to math.isclose

533

534

Returns:

535

True if point lies on plane

536

"""

537

538

def plot_3d(self, ax_3d, lims_x=(-1, 1), lims_y=(-1, 1), **kwargs):

539

"""

540

Plot 3D plane surface.

541

542

Parameters:

543

- ax_3d: matplotlib Axes3D, 3D plotting axes

544

- lims_x: tuple, x-axis limits (default: (-1, 1))

545

- lims_y: tuple, y-axis limits (default: (-1, 1))

546

- **kwargs: additional keywords passed to plot_surface

547

"""

548

```

549

550

**Usage Example:**

551

```python

552

from skspatial.objects import Plane, Line, Point

553

554

# Create plane from point and normal

555

plane = Plane(point=[0, 0, 0], normal=[0, 0, 1])

556

557

# Create plane from three points

558

plane2 = Plane.from_points([0, 0, 0], [1, 0, 0], [0, 1, 0])

559

560

# Create plane from vectors

561

plane3 = Plane.from_vectors([0, 0, 0], [1, 0, 0], [0, 1, 0])

562

563

# Project point onto plane

564

point = Point([5, 6, 7])

565

projected = plane.project_point(point) # Point([5, 6, 0])

566

567

# Find intersection with line

568

line = Line([0, 0, -5], [0, 0, 1])

569

intersection = plane.intersect_line(line) # Point([0, 0, 0])

570

571

# Plane of best fit

572

import numpy as np

573

points = np.random.randn(50, 3)

574

best_fit_plane = Plane.best_fit(points)

575

```

576

577

### LineSegment

578

579

Represents a finite line segment between two endpoints. Provides intersection testing and visualization for bounded linear geometry.

580

581

```python { .api }

582

class LineSegment:

583

"""

584

A finite line segment between two points.

585

586

Parameters:

587

- point_a: array-like, first endpoint

588

- point_b: array-like, second endpoint

589

"""

590

def __init__(self, point_a, point_b): ...

591

592

@property

593

def point_a(self) -> Point:

594

"""First endpoint of the segment."""

595

596

@property

597

def point_b(self) -> Point:

598

"""Second endpoint of the segment."""

599

600

def contains_point(self, point, **kwargs) -> bool:

601

"""

602

Check if point lies on the line segment.

603

604

Parameters:

605

- point: array-like, point to check

606

- **kwargs: additional keywords passed to math.isclose

607

608

Returns:

609

True if point is on the segment between endpoints

610

"""

611

612

def intersect_line_segment(self, other, **kwargs) -> Point:

613

"""

614

Find intersection with another line segment.

615

616

Parameters:

617

- other: LineSegment, another line segment

618

- **kwargs: additional keywords passed to numpy functions

619

620

Returns:

621

Intersection point

622

623

Raises:

624

ValueError if segments don't intersect

625

"""

626

627

def plot_2d(self, ax_2d, **kwargs):

628

"""

629

Plot 2D line segment.

630

631

Parameters:

632

- ax_2d: matplotlib Axes, 2D plotting axes

633

- **kwargs: additional keywords passed to plot

634

"""

635

636

def plot_3d(self, ax_3d, **kwargs):

637

"""

638

Plot 3D line segment.

639

640

Parameters:

641

- ax_3d: matplotlib Axes3D, 3D plotting axes

642

- **kwargs: additional keywords passed to plot

643

"""

644

```

645

646

**Usage Example:**

647

```python

648

from skspatial.objects import LineSegment, Point

649

650

# Create line segment

651

segment = LineSegment([0, 0], [3, 4])

652

653

# Check if point is on segment

654

point = Point([1.5, 2])

655

on_segment = segment.contains_point(point) # True

656

657

# Find intersection with another segment

658

segment2 = LineSegment([0, 3], [3, 0])

659

intersection = segment.intersect_line_segment(segment2)

660

```