2019-04-26 21:21:50 +02:00
|
|
|
# See LICENSE for licensing information.
|
|
|
|
|
#
|
2022-11-30 23:50:43 +01:00
|
|
|
# Copyright (c) 2016-2022 Regents of the University of California and The Board
|
2019-06-14 17:43:41 +02:00
|
|
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
|
|
|
|
# (acting for and on behalf of Oklahoma State University)
|
|
|
|
|
# All rights reserved.
|
2019-04-26 21:21:50 +02:00
|
|
|
#
|
2016-11-17 00:02:07 +01:00
|
|
|
import math
|
2022-11-27 22:01:20 +01:00
|
|
|
from openram import tech
|
2016-11-08 18:57:35 +01:00
|
|
|
|
2021-09-08 01:49:44 +02:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
class vector():
|
|
|
|
|
"""
|
|
|
|
|
This is the vector class to represent the coordinate
|
|
|
|
|
vector. It makes the coordinate operations easy and short
|
|
|
|
|
so the code is concise.
|
|
|
|
|
It needs to override several operators to support
|
|
|
|
|
concise vector operations, output, and other more complex
|
|
|
|
|
data structures like lists.
|
|
|
|
|
"""
|
2018-10-11 00:58:16 +02:00
|
|
|
def __init__(self, x, y=0):
|
2016-11-08 18:57:35 +01:00
|
|
|
""" init function support two init method"""
|
|
|
|
|
# will take single input as a coordinate
|
2018-10-11 00:58:16 +02:00
|
|
|
if isinstance(x, (list,tuple,vector)):
|
2018-09-06 20:54:14 +02:00
|
|
|
self.x = float(x[0])
|
|
|
|
|
self.y = float(x[1])
|
2016-11-08 18:57:35 +01:00
|
|
|
#will take two inputs as the values of a coordinate
|
2018-10-11 00:58:16 +02:00
|
|
|
else:
|
2018-09-06 20:54:14 +02:00
|
|
|
self.x = float(x)
|
|
|
|
|
self.y = float(y)
|
2020-01-03 11:49:51 +01:00
|
|
|
self._hash = hash((self.x,self.y))
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
""" override print function output """
|
2018-09-07 23:46:58 +02:00
|
|
|
return "v["+str(self.x)+","+str(self.y)+"]"
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
""" override print function output """
|
2018-09-07 23:46:58 +02:00
|
|
|
return "v["+str(self.x)+","+str(self.y)+"]"
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
def __setitem__(self, index, value):
|
2020-11-03 15:29:17 +01:00
|
|
|
"""
|
|
|
|
|
override setitem function
|
2016-11-08 18:57:35 +01:00
|
|
|
can set value by vector[index]=value
|
|
|
|
|
"""
|
|
|
|
|
if index==0:
|
2018-09-06 20:54:14 +02:00
|
|
|
self.x=float(value)
|
2016-11-08 18:57:35 +01:00
|
|
|
elif index==1:
|
2018-09-06 20:54:14 +02:00
|
|
|
self.y=float(value)
|
2016-11-08 18:57:35 +01:00
|
|
|
else:
|
2018-09-06 20:54:14 +02:00
|
|
|
self.x=float(value[0])
|
|
|
|
|
self.y=float(value[1])
|
2022-05-17 22:30:41 +02:00
|
|
|
self._hash = hash((self.x,self.y))
|
2020-11-03 15:29:17 +01:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
def __getitem__(self, index):
|
|
|
|
|
"""
|
2020-11-03 15:29:17 +01:00
|
|
|
override getitem function
|
2016-11-08 18:57:35 +01:00
|
|
|
can get value by value=vector[index]
|
|
|
|
|
"""
|
|
|
|
|
if index==0:
|
|
|
|
|
return self.x
|
|
|
|
|
elif index==1:
|
|
|
|
|
return self.y
|
|
|
|
|
else:
|
2020-11-03 15:29:17 +01:00
|
|
|
return self
|
2016-11-08 18:57:35 +01:00
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
|
|
"""
|
|
|
|
|
Override + function (left add)
|
|
|
|
|
Can add by vector(x1,y1)+vector(x2,y2)
|
|
|
|
|
"""
|
|
|
|
|
return vector(self.x + other[0], self.y + other[1])
|
|
|
|
|
|
2016-11-17 00:02:07 +01:00
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
def __radd__(self, other):
|
|
|
|
|
"""
|
|
|
|
|
Override + function (right add)
|
|
|
|
|
"""
|
|
|
|
|
if other == 0:
|
|
|
|
|
return self
|
|
|
|
|
else:
|
|
|
|
|
return self.__add__(other)
|
|
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
|
|
"""
|
|
|
|
|
Override - function (left)
|
|
|
|
|
"""
|
|
|
|
|
return vector(self.x - other[0], self.y - other[1])
|
|
|
|
|
|
|
|
|
|
def __rsub__(self, other):
|
|
|
|
|
"""
|
|
|
|
|
Override - function (right)
|
|
|
|
|
"""
|
|
|
|
|
return vector(other[0]- self.x, other[1] - self.y)
|
|
|
|
|
|
2018-09-06 20:54:14 +02:00
|
|
|
def __hash__(self):
|
|
|
|
|
"""
|
|
|
|
|
Override - function (hash)
|
|
|
|
|
Note: This assumes that you DON'T CHANGE THE VECTOR or it will
|
|
|
|
|
break things.
|
|
|
|
|
"""
|
2020-01-03 11:49:51 +01:00
|
|
|
return self._hash
|
2018-09-06 20:54:14 +02:00
|
|
|
|
2016-11-20 20:06:53 +01:00
|
|
|
def snap_to_grid(self):
|
|
|
|
|
self.x = self.snap_offset_to_grid(self.x)
|
|
|
|
|
self.y = self.snap_offset_to_grid(self.y)
|
2022-05-17 22:30:41 +02:00
|
|
|
self._hash = hash((self.x,self.y))
|
2016-11-20 20:06:53 +01:00
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def snap_offset_to_grid(self, offset):
|
2016-11-18 02:19:48 +01:00
|
|
|
"""
|
|
|
|
|
Changes the coodrinate to match the grid settings
|
|
|
|
|
"""
|
2020-11-03 15:29:17 +01:00
|
|
|
grid = tech.drc["grid"]
|
2016-11-18 02:19:48 +01:00
|
|
|
# this gets the nearest integer value
|
|
|
|
|
off_in_grid = int(round(round((offset / grid), 2), 0))
|
|
|
|
|
offset = off_in_grid * grid
|
|
|
|
|
return offset
|
|
|
|
|
|
2016-11-08 18:57:35 +01:00
|
|
|
def rotate(self):
|
|
|
|
|
""" pass a copy of rotated vector, without altering the vector! """
|
|
|
|
|
return vector(self.y,self.x)
|
|
|
|
|
|
|
|
|
|
def scale(self, x_factor, y_factor=None):
|
|
|
|
|
""" pass a copy of scaled vector, without altering the vector! """
|
|
|
|
|
if y_factor==None:
|
|
|
|
|
y_factor=x_factor[1]
|
|
|
|
|
x_factor=x_factor[0]
|
|
|
|
|
return vector(self.x*x_factor,self.y*y_factor)
|
2016-11-11 23:33:19 +01:00
|
|
|
|
|
|
|
|
def rotate_scale(self, x_factor, y_factor=None):
|
|
|
|
|
""" pass a copy of scaled vector, without altering the vector! """
|
|
|
|
|
if y_factor==None:
|
|
|
|
|
y_factor=x_factor[1]
|
|
|
|
|
x_factor=x_factor[0]
|
|
|
|
|
return vector(self.y*x_factor,self.x*y_factor)
|
2016-11-17 00:02:07 +01:00
|
|
|
|
|
|
|
|
def floor(self):
|
|
|
|
|
"""
|
|
|
|
|
Override floor function
|
|
|
|
|
"""
|
|
|
|
|
return vector(int(math.floor(self.x)),int(math.floor(self.y)))
|
|
|
|
|
|
|
|
|
|
def ceil(self):
|
|
|
|
|
"""
|
|
|
|
|
Override ceil function
|
|
|
|
|
"""
|
|
|
|
|
return vector(int(math.ceil(self.x)),int(math.ceil(self.y)))
|
|
|
|
|
|
2016-11-17 20:24:17 +01:00
|
|
|
def round(self):
|
|
|
|
|
"""
|
|
|
|
|
Override round function
|
|
|
|
|
"""
|
|
|
|
|
return vector(int(round(self.x)),int(round(self.y)))
|
2020-11-03 15:29:17 +01:00
|
|
|
|
|
|
|
|
|
2016-11-17 00:02:07 +01:00
|
|
|
def __eq__(self, other):
|
|
|
|
|
"""Override the default Equals behavior"""
|
|
|
|
|
if isinstance(other, self.__class__):
|
|
|
|
|
return self.__dict__ == other.__dict__
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def __ne__(self, other):
|
|
|
|
|
"""Override the default non-equality behavior"""
|
|
|
|
|
return not self.__eq__(other)
|
|
|
|
|
|
|
|
|
|
def max(self, other):
|
|
|
|
|
""" Max of both values """
|
|
|
|
|
return vector(max(self.x,other.x),max(self.y,other.y))
|
|
|
|
|
|
|
|
|
|
def min(self, other):
|
|
|
|
|
""" Min of both values """
|
|
|
|
|
return vector(min(self.x,other.x),min(self.y,other.y))
|