or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

database-operations.mdfile-io.mdhierarchical-design.mdindex.mdlayout-viewer.mdshape-operations.mdtransformations.mdverification.md

transformations.mddocs/

0

# Layout Transformations and Coordinates

1

2

Geometric transformations including rotation, mirroring, scaling, and translation operations for precise layout manipulation and coordinate system conversions in IC design workflows.

3

4

## Capabilities

5

6

### Basic Transformations

7

8

```python { .api }

9

class Trans:

10

def __init__(self, rotation: int = 0, mirror: bool = False, displacement: Point = None):

11

"""

12

Create an integer coordinate transformation.

13

14

Parameters:

15

- rotation: Rotation in 90-degree increments (0, 1, 2, 3)

16

- mirror: Mirror across X-axis before rotation

17

- displacement: Translation vector

18

"""

19

20

@property

21

def rot(self) -> int:

22

"""Get rotation value (0-3 for 0°, 90°, 180°, 270°)."""

23

24

@property

25

def is_mirror(self) -> bool:

26

"""Check if transformation includes mirroring."""

27

28

@property

29

def disp(self) -> Point:

30

"""Get displacement vector."""

31

32

def inverted(self) -> Trans:

33

"""Return the inverse transformation."""

34

35

def __mul__(self, other: Trans) -> Trans:

36

"""Combine transformations (self * other)."""

37

38

def transform_point(self, point: Point) -> Point:

39

"""Transform a point."""

40

41

def transform_box(self, box: Box) -> Box:

42

"""Transform a bounding box."""

43

44

class DTrans:

45

def __init__(self, rotation: int = 0, mirror: bool = False, displacement: DPoint = None):

46

"""Create a double precision transformation."""

47

48

@property

49

def rot(self) -> int:

50

"""Get rotation value."""

51

52

@property

53

def is_mirror(self) -> bool:

54

"""Check if transformation includes mirroring."""

55

56

@property

57

def disp(self) -> DPoint:

58

"""Get displacement vector."""

59

```

60

61

### Complex Transformations with Scaling

62

63

```python { .api }

64

class CplxTrans:

65

def __init__(self, mag: float = 1.0, rotation: float = 0.0, mirror: bool = False, displacement: DPoint = None):

66

"""

67

Create a complex transformation with scaling and arbitrary rotation.

68

69

Parameters:

70

- mag: Magnification factor

71

- rotation: Rotation angle in degrees

72

- mirror: Mirror across X-axis before rotation

73

- displacement: Translation vector

74

"""

75

76

@property

77

def mag(self) -> float:

78

"""Get magnification factor."""

79

80

@property

81

def angle(self) -> float:

82

"""Get rotation angle in degrees."""

83

84

@property

85

def is_mirror(self) -> bool:

86

"""Check if transformation includes mirroring."""

87

88

@property

89

def disp(self) -> DPoint:

90

"""Get displacement vector."""

91

92

def inverted(self) -> CplxTrans:

93

"""Return the inverse transformation."""

94

95

def __mul__(self, other: CplxTrans) -> CplxTrans:

96

"""Combine complex transformations."""

97

98

def transform_point(self, point: DPoint) -> DPoint:

99

"""Transform a double precision point."""

100

101

def transform_box(self, box: DBox) -> DBox:

102

"""Transform a double precision bounding box."""

103

104

class ICplxTrans:

105

def __init__(self, mag: float = 1.0, rotation: float = 0.0, mirror: bool = False, displacement: Point = None):

106

"""Create an integer complex transformation."""

107

108

def to_trans(self) -> Trans:

109

"""Convert to simple transformation (if no scaling)."""

110

111

class DCplxTrans:

112

def __init__(self, mag: float = 1.0, rotation: float = 0.0, mirror: bool = False, displacement: DPoint = None):

113

"""Create a double precision complex transformation."""

114

```

115

116

### Matrix Transformations

117

118

```python { .api }

119

class Matrix2d:

120

def __init__(self, m11: float = 1.0, m12: float = 0.0, m21: float = 0.0, m22: float = 1.0):

121

"""

122

Create a 2x2 transformation matrix.

123

124

Parameters:

125

- m11, m12, m21, m22: Matrix elements

126

"""

127

128

def determinant(self) -> float:

129

"""Calculate matrix determinant."""

130

131

def inverted(self) -> Matrix2d:

132

"""Return inverted matrix."""

133

134

def __mul__(self, other: Matrix2d) -> Matrix2d:

135

"""Matrix multiplication."""

136

137

def transform_point(self, point: DPoint) -> DPoint:

138

"""Transform a point using the matrix."""

139

140

class Matrix3d:

141

def __init__(self):

142

"""Create a 3x3 transformation matrix."""

143

144

def translate(self, dx: float, dy: float) -> Matrix3d:

145

"""Add translation to the transformation."""

146

147

def rotate(self, angle: float) -> Matrix3d:

148

"""Add rotation to the transformation (in radians)."""

149

150

def scale(self, sx: float, sy: float = None) -> Matrix3d:

151

"""

152

Add scaling to the transformation.

153

154

Parameters:

155

- sx: X scale factor

156

- sy: Y scale factor (defaults to sx if not provided)

157

"""

158

159

def shear(self, shx: float, shy: float) -> Matrix3d:

160

"""Add shear transformation."""

161

162

def inverted(self) -> Matrix3d:

163

"""Return inverted matrix."""

164

165

def transform_point(self, point: DPoint) -> DPoint:

166

"""Transform a point."""

167

```

168

169

### Coordinate System Utilities

170

171

```python { .api }

172

def coord_from_dbu(coord_dbu: int, dbu: float) -> float:

173

"""

174

Convert coordinate from database units to user units.

175

176

Parameters:

177

- coord_dbu: Coordinate in database units

178

- dbu: Database unit in user units

179

180

Returns:

181

float: Coordinate in user units

182

"""

183

184

def coord_to_dbu(coord: float, dbu: float) -> int:

185

"""

186

Convert coordinate from user units to database units.

187

188

Parameters:

189

- coord: Coordinate in user units

190

- dbu: Database unit in user units

191

192

Returns:

193

int: Coordinate in database units

194

"""

195

196

class Layout:

197

@property

198

def dbu(self) -> float:

199

"""Get database unit in micrometers."""

200

201

def set_dbu(self, dbu: float) -> None:

202

"""Set database unit."""

203

204

def scale_and_snap(self, layout_target: Layout, cell_mapping, layers, factor: float) -> None:

205

"""Scale layout and snap to grid."""

206

```

207

208

## Usage Examples

209

210

### Basic Transformations

211

212

```python

213

import klayout.db as db

214

215

# Create basic transformations

216

trans1 = db.Trans(1, False, db.Point(100, 200)) # 90° rotation + translation

217

trans2 = db.Trans(0, True, db.Point(0, 0)) # Mirror only

218

trans3 = db.Trans(db.Point(50, 75)) # Translation only

219

220

# Apply transformations to shapes

221

original_box = db.Box(0, 0, 100, 50)

222

rotated_box = trans1.transform_box(original_box)

223

mirrored_box = trans2.transform_box(original_box)

224

225

# Combine transformations

226

combined = trans1 * trans2 # Apply trans2, then trans1

227

228

print(f"Original: {original_box}")

229

print(f"Rotated: {rotated_box}")

230

print(f"Combined transformation: {combined}")

231

```

232

233

### Complex Transformations with Scaling

234

235

```python

236

import klayout.db as db

237

import math

238

239

# Create complex transformation

240

angle = 45.0 # 45 degrees

241

scale = 1.5 # 150% scaling

242

displacement = db.DPoint(100.0, 200.0)

243

244

ctrans = db.CplxTrans(scale, angle, False, displacement)

245

246

# Transform double precision shapes

247

dbox = db.DBox(0.0, 0.0, 10.0, 5.0)

248

transformed_dbox = ctrans.transform_box(dbox)

249

250

print(f"Original: {dbox}")

251

print(f"Transformed: {transformed_dbox}")

252

print(f"Scale: {ctrans.mag}, Angle: {ctrans.angle}°")

253

```

254

255

### Matrix-Based Transformations

256

257

```python

258

import klayout.db as db

259

import math

260

261

# Create transformation using matrices

262

matrix = db.Matrix3d()

263

matrix.rotate(math.pi / 4) # 45 degrees in radians

264

matrix.scale(2.0, 1.5) # Scale X by 2, Y by 1.5

265

matrix.translate(100.0, 50.0)

266

267

# Apply to points

268

points = [db.DPoint(0, 0), db.DPoint(10, 0), db.DPoint(10, 10), db.DPoint(0, 10)]

269

transformed_points = [matrix.transform_point(p) for p in points]

270

271

print("Original points:", points)

272

print("Transformed points:", transformed_points)

273

```

274

275

### Cell Instance Transformations

276

277

```python

278

import klayout.db as db

279

280

layout = db.Layout()

281

top_cell = layout.create_cell("TOP")

282

sub_cell = layout.create_cell("SUB")

283

284

# Add content to subcell

285

layer = layout.layer(db.LayerInfo(1, 0))

286

sub_cell.shapes(layer).insert(db.Box(0, 0, 100, 100))

287

288

# Create instances with various transformations

289

transformations = [

290

db.Trans(0, False, db.Point(0, 0)), # Original position

291

db.Trans(1, False, db.Point(200, 0)), # 90° rotation

292

db.Trans(2, False, db.Point(200, 200)), # 180° rotation

293

db.Trans(3, False, db.Point(0, 200)), # 270° rotation

294

db.Trans(0, True, db.Point(400, 0)), # Mirrored

295

]

296

297

for i, trans in enumerate(transformations):

298

instance = db.CellInstArray(sub_cell.cell_index, trans)

299

top_cell.insert(instance)

300

301

layout.write("transformed_instances.gds")

302

```

303

304

### Coordinate System Conversion

305

306

```python

307

import klayout.db as db

308

309

layout = db.Layout()

310

print(f"Default DBU: {layout.dbu} micrometers")

311

312

# Work with different coordinate systems

313

# Coordinates in micrometers

314

user_coord = 10.5 # 10.5 μm

315

316

# Convert to database units

317

dbu_coord = db.coord_to_dbu(user_coord, layout.dbu)

318

print(f"{user_coord} μm = {dbu_coord} DBU")

319

320

# Convert back to user units

321

recovered_coord = db.coord_from_dbu(dbu_coord, layout.dbu)

322

print(f"{dbu_coord} DBU = {recovered_coord} μm")

323

324

# Create shapes using converted coordinates

325

box_in_um = db.Box(

326

db.coord_to_dbu(0.0, layout.dbu),

327

db.coord_to_dbu(0.0, layout.dbu),

328

db.coord_to_dbu(10.5, layout.dbu),

329

db.coord_to_dbu(5.25, layout.dbu)

330

)

331

332

cell = layout.create_cell("TOP")

333

layer = layout.layer(db.LayerInfo(1, 0))

334

cell.shapes(layer).insert(box_in_um)

335

```

336

337

### Advanced Transformation Chains

338

339

```python

340

import klayout.db as db

341

342

# Create a chain of transformations

343

base_trans = db.Trans(db.Point(100, 100)) # Base translation

344

rotate_90 = db.Trans(1, False, db.Point(0, 0)) # 90° rotation

345

mirror_x = db.Trans(0, True, db.Point(0, 0)) # Mirror

346

347

# Build transformation chain

348

step1 = base_trans * rotate_90

349

step2 = step1 * mirror_x

350

351

# Apply to create pattern

352

layout = db.Layout()

353

cell = layout.create_cell("PATTERN")

354

layer = layout.layer(db.LayerInfo(1, 0))

355

356

# Original shape

357

original = db.Box(0, 0, 50, 25)

358

cell.shapes(layer).insert(original)

359

360

# Transformed copies

361

cell.shapes(layer).insert(step1.transform_box(original))

362

cell.shapes(layer).insert(step2.transform_box(original))

363

364

# Verify inverse transformations

365

inverse_step2 = step2.inverted()

366

recovered = inverse_step2.transform_box(step2.transform_box(original))

367

print(f"Original: {original}")

368

print(f"Recovered: {recovered}")

369

print(f"Match: {original == recovered}")

370

371

layout.write("transformation_chain.gds")

372

```

373

374

### Working with Arbitrary Angles

375

376

```python

377

import klayout.db as db

378

import math

379

380

# For arbitrary angles, use CplxTrans

381

angles = [15, 30, 45, 60, 75] # Degrees

382

center = db.DPoint(50, 50)

383

384

layout = db.Layout()

385

cell = layout.create_cell("ROTATIONS")

386

layer = layout.layer(db.LayerInfo(1, 0))

387

388

# Create base shape

389

base_points = [

390

db.Point(0, 0), db.Point(20, 0),

391

db.Point(20, 10), db.Point(0, 10)

392

]

393

base_polygon = db.Polygon(base_points)

394

395

for angle in angles:

396

# Create transformation: translate to origin, rotate, translate back

397

to_origin = db.CplxTrans(1.0, 0.0, False, db.DPoint(-center.x, -center.y))

398

rotate = db.CplxTrans(1.0, angle, False, db.DPoint(0, 0))

399

from_origin = db.CplxTrans(1.0, 0.0, False, center)

400

401

# Combine transformations

402

full_trans = from_origin * rotate * to_origin

403

404

# Convert to integer transformation for polygon

405

# (Note: This approximates arbitrary angles to nearest valid Trans rotation)

406

# For exact arbitrary angles, work with DPolygon instead

407

approx_trans = db.ICplxTrans(full_trans).to_trans()

408

409

rotated_polygon = base_polygon.transformed(approx_trans)

410

cell.shapes(layer).insert(rotated_polygon)

411

412

layout.write("arbitrary_rotations.gds")

413

```