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

curved-geometry.mddocs/

0

# Curved Geometry

1

2

Circles, spheres, and cylinders with specialized methods for curved surface computations, intersections, volume calculations, and fitting operations for point clouds.

3

4

## Capabilities

5

6

### Circle

7

8

Represents a circle in 2D space with center point and radius. Provides area calculations, intersections, and fitting capabilities.

9

10

```python { .api }

11

class Circle:

12

"""

13

A circle in 2D space.

14

15

Parameters:

16

- point: array-like, center point (2D)

17

- radius: float, radius of the circle

18

"""

19

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

20

21

@classmethod

22

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

23

"""

24

Create circle from three points.

25

26

Parameters:

27

- point_a: array-like, first point (2D)

28

- point_b: array-like, second point (2D)

29

- point_c: array-like, third point (2D)

30

- **kwargs: additional keywords passed to numpy functions

31

32

Returns:

33

Circle passing through all three points

34

"""

35

36

@classmethod

37

def best_fit(cls, points) -> 'Circle':

38

"""

39

Find circle of best fit for 2D points.

40

41

Parameters:

42

- points: array-like, 2D points to fit circle to

43

44

Returns:

45

Best fit circle

46

"""

47

48

@property

49

def point(self) -> Point:

50

"""Center point of the circle (2D)."""

51

52

@property

53

def radius(self) -> float:

54

"""Radius of the circle."""

55

56

@property

57

def dimension(self) -> int:

58

"""Dimension of the circle (always 2)."""

59

60

def circumference(self) -> float:

61

"""

62

Calculate circumference of the circle.

63

64

Returns:

65

Circumference (2πr)

66

"""

67

68

def area(self) -> float:

69

"""

70

Calculate area of the circle.

71

72

Returns:

73

Area (πr²)

74

"""

75

76

def intersect_circle(self, other) -> Tuple[Point, Point]:

77

"""

78

Find intersection points with another circle.

79

80

Parameters:

81

- other: Circle, another circle

82

83

Returns:

84

Tuple of two intersection points

85

86

Raises:

87

ValueError if circles don't intersect

88

"""

89

90

def intersect_line(self, line) -> Tuple[Point, Point]:

91

"""

92

Find intersection points with a line.

93

94

Parameters:

95

- line: Line, line to intersect

96

97

Returns:

98

Tuple of intersection points

99

100

Raises:

101

ValueError if line doesn't intersect circle

102

"""

103

104

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

105

"""

106

Calculate distance from point to circle edge.

107

108

Parameters:

109

- point: array-like, point

110

111

Returns:

112

Distance to closest point on circle circumference

113

"""

114

115

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

116

"""

117

Check if circle contains point.

118

119

Parameters:

120

- point: array-like, point to check

121

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

122

123

Returns:

124

True if point is on circle circumference

125

"""

126

127

def project_point(self, point) -> Point:

128

"""

129

Project point onto circle circumference.

130

131

Parameters:

132

- point: array-like, point to project

133

134

Returns:

135

Closest point on circle circumference

136

"""

137

138

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

139

"""

140

Plot 2D circle.

141

142

Parameters:

143

- ax_2d: matplotlib Axes, 2D plotting axes

144

- **kwargs: additional keywords passed to plotting functions

145

"""

146

```

147

148

**Usage Example:**

149

```python

150

from skspatial.objects import Circle, Line, Point

151

152

# Create circle from center and radius

153

circle = Circle([0, 0], radius=5)

154

155

# Create circle from three points

156

circle2 = Circle.from_points([0, 0], [1, 0], [0, 1])

157

158

# Calculate properties

159

area = circle.area() # 25π

160

circumference = circle.circumference() # 10π

161

162

# Find intersections

163

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

164

intersections = circle.intersect_line(line) # Two points where line crosses circle

165

166

# Circle of best fit

167

import numpy as np

168

points_2d = np.random.randn(20, 2) * 3 + [2, 3] # Noisy circle data

169

best_fit_circle = Circle.best_fit(points_2d)

170

```

171

172

### Sphere

173

174

Represents a sphere in 3D space with center point and radius. Provides volume calculations, surface area, intersections, and mesh generation.

175

176

```python { .api }

177

class Sphere:

178

"""

179

A sphere in 3D space.

180

181

Parameters:

182

- point: array-like, center point (3D)

183

- radius: float, radius of the sphere

184

"""

185

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

186

187

@classmethod

188

def best_fit(cls, points) -> 'Sphere':

189

"""

190

Find sphere of best fit for 3D points.

191

192

Parameters:

193

- points: array-like, 3D points to fit sphere to

194

195

Returns:

196

Best fit sphere

197

"""

198

199

@property

200

def point(self) -> Point:

201

"""Center point of the sphere (3D)."""

202

203

@property

204

def radius(self) -> float:

205

"""Radius of the sphere."""

206

207

@property

208

def dimension(self) -> int:

209

"""Dimension of the sphere (always 3)."""

210

211

def surface_area(self) -> float:

212

"""

213

Calculate surface area of the sphere.

214

215

Returns:

216

Surface area (4πr²)

217

"""

218

219

def volume(self) -> float:

220

"""

221

Calculate volume of the sphere.

222

223

Returns:

224

Volume (4/3 πr³)

225

"""

226

227

def intersect_line(self, line) -> Tuple[Point, Point]:

228

"""

229

Find intersection points with a line.

230

231

Parameters:

232

- line: Line, line to intersect

233

234

Returns:

235

Tuple of intersection points

236

237

Raises:

238

ValueError if line doesn't intersect sphere

239

"""

240

241

def to_mesh(self, n_angles=30):

242

"""

243

Generate mesh coordinates for plotting.

244

245

Parameters:

246

- n_angles: int, number of angles for discretization (default: 30)

247

248

Returns:

249

X, Y, Z mesh arrays for plotting

250

"""

251

252

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

253

"""

254

Return points on the sphere surface.

255

256

Parameters:

257

- **kwargs: additional keywords for mesh generation

258

259

Returns:

260

Points sampled on sphere surface

261

"""

262

263

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

264

"""

265

Calculate distance from point to sphere surface.

266

267

Parameters:

268

- point: array-like, point

269

270

Returns:

271

Distance to closest point on sphere surface

272

"""

273

274

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

275

"""

276

Check if sphere contains point.

277

278

Parameters:

279

- point: array-like, point to check

280

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

281

282

Returns:

283

True if point is on sphere surface

284

"""

285

286

def project_point(self, point) -> Point:

287

"""

288

Project point onto sphere surface.

289

290

Parameters:

291

- point: array-like, point to project

292

293

Returns:

294

Closest point on sphere surface

295

"""

296

297

def plot_3d(self, ax_3d, n_angles=30, **kwargs):

298

"""

299

Plot 3D sphere surface.

300

301

Parameters:

302

- ax_3d: matplotlib Axes3D, 3D plotting axes

303

- n_angles: int, number of angles for discretization (default: 30)

304

- **kwargs: additional keywords passed to plot_surface

305

"""

306

```

307

308

**Usage Example:**

309

```python

310

from skspatial.objects import Sphere, Line, Point

311

312

# Create sphere from center and radius

313

sphere = Sphere([0, 0, 0], radius=3)

314

315

# Calculate properties

316

volume = sphere.volume() # 36π

317

surface_area = sphere.surface_area() # 36π

318

319

# Find intersections with line

320

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

321

intersections = sphere.intersect_line(line) # Entry and exit points

322

323

# Sphere of best fit

324

import numpy as np

325

# Generate noisy sphere data

326

theta = np.random.uniform(0, 2*np.pi, 100)

327

phi = np.random.uniform(0, np.pi, 100)

328

points_3d = np.column_stack([

329

3 * np.sin(phi) * np.cos(theta),

330

3 * np.sin(phi) * np.sin(theta),

331

3 * np.cos(phi)

332

]) + np.random.normal(0, 0.1, (100, 3))

333

best_fit_sphere = Sphere.best_fit(points_3d)

334

```

335

336

### Cylinder

337

338

Represents a cylinder in 3D space defined by base center, axis vector, and radius. Provides volume calculations, surface areas, and intersection operations.

339

340

```python { .api }

341

class Cylinder:

342

"""

343

A cylinder in 3D space.

344

345

Parameters:

346

- point: array-like, center of cylinder base (3D)

347

- vector: array-like, axis vector (3D)

348

- radius: float, radius of the cylinder

349

"""

350

def __init__(self, point, vector, radius): ...

351

352

@classmethod

353

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

354

"""

355

Create cylinder from two points and radius.

356

357

Parameters:

358

- point_a: array-like, first point on axis (3D)

359

- point_b: array-like, second point on axis (3D)

360

- radius: float, radius of the cylinder

361

362

Returns:

363

Cylinder with axis from point_a to point_b

364

"""

365

366

@classmethod

367

def best_fit(cls, points) -> 'Cylinder':

368

"""

369

Find cylinder of best fit for 3D points.

370

371

Parameters:

372

- points: array-like, 3D points to fit cylinder to

373

374

Returns:

375

Best fit cylinder

376

"""

377

378

@property

379

def point(self) -> Point:

380

"""Center of cylinder base (3D)."""

381

382

@property

383

def vector(self) -> Vector:

384

"""Axis vector of the cylinder (3D)."""

385

386

@property

387

def radius(self) -> float:

388

"""Radius of the cylinder."""

389

390

@property

391

def dimension(self) -> int:

392

"""Dimension of the cylinder (always 3)."""

393

394

def length(self) -> np.float64:

395

"""

396

Calculate length of the cylinder.

397

398

Returns:

399

Length along axis vector

400

"""

401

402

def lateral_surface_area(self) -> np.float64:

403

"""

404

Calculate lateral surface area of the cylinder.

405

406

Returns:

407

Lateral surface area (2πrh)

408

"""

409

410

def surface_area(self) -> np.float64:

411

"""

412

Calculate total surface area of the cylinder.

413

414

Returns:

415

Total surface area (2πr² + 2πrh)

416

"""

417

418

def volume(self) -> np.float64:

419

"""

420

Calculate volume of the cylinder.

421

422

Returns:

423

Volume (πr²h)

424

"""

425

426

def is_point_within(self, point) -> bool:

427

"""

428

Check if point is inside the cylinder.

429

430

Parameters:

431

- point: array-like, point to check (3D)

432

433

Returns:

434

True if point is within cylinder volume

435

"""

436

437

def intersect_line(self, line, n_digits=None, infinite=True):

438

"""

439

Find intersection points with a line.

440

441

Parameters:

442

- line: Line, line to intersect

443

- n_digits: int, optional precision for calculations

444

- infinite: bool, treat cylinder as infinite (default: True)

445

446

Returns:

447

Intersection points with cylinder surface

448

449

Raises:

450

ValueError if line doesn't intersect cylinder

451

"""

452

453

def to_mesh(self, n_along_axis=100, n_angles=30):

454

"""

455

Generate mesh coordinates for plotting.

456

457

Parameters:

458

- n_along_axis: int, points along axis (default: 100)

459

- n_angles: int, angular discretization (default: 30)

460

461

Returns:

462

X, Y, Z mesh arrays for plotting

463

"""

464

465

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

466

"""

467

Return points on the cylinder surface.

468

469

Parameters:

470

- **kwargs: additional keywords for mesh generation

471

472

Returns:

473

Points sampled on cylinder surface

474

"""

475

476

def plot_3d(self, ax_3d, n_along_axis=100, n_angles=30, **kwargs):

477

"""

478

Plot 3D cylinder surface.

479

480

Parameters:

481

- ax_3d: matplotlib Axes3D, 3D plotting axes

482

- n_along_axis: int, points along axis (default: 100)

483

- n_angles: int, angular discretization (default: 30)

484

- **kwargs: additional keywords passed to plot_surface

485

"""

486

```

487

488

**Usage Example:**

489

```python

490

from skspatial.objects import Cylinder, Line, Point

491

492

# Create cylinder from base center, axis, and radius

493

cylinder = Cylinder([0, 0, 0], [0, 0, 5], radius=2)

494

495

# Create cylinder from two points

496

cylinder2 = Cylinder.from_points([0, 0, 0], [0, 0, 10], radius=1.5)

497

498

# Calculate properties

499

volume = cylinder.volume() # 20π

500

surface_area = cylinder.surface_area() # 28π

501

length = cylinder.length() # 5

502

503

# Check if point is inside

504

point = Point([1, 1, 2.5])

505

is_inside = cylinder.is_point_within(point) # True (within radius and height)

506

507

# Find intersections with line

508

line = Line([-3, 0, 2.5], [1, 0, 0]) # Horizontal line through cylinder

509

intersections = cylinder.intersect_line(line) # Entry and exit points

510

511

# Cylinder of best fit

512

import numpy as np

513

# Generate cylindrical point cloud

514

theta = np.random.uniform(0, 2*np.pi, 200)

515

z = np.random.uniform(0, 5, 200)

516

points_3d = np.column_stack([

517

2 * np.cos(theta) + np.random.normal(0, 0.1, 200),

518

2 * np.sin(theta) + np.random.normal(0, 0.1, 200),

519

z + np.random.normal(0, 0.1, 200)

520

])

521

best_fit_cylinder = Cylinder.best_fit(points_3d)

522

```