Advertisement
captaindavepdx

Untitled

Dec 30th, 2019
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.25 KB | None | 0 0
  1. from decimal import Decimal, getcontext
  2. from vector import Vector
  3.  
  4. getcontext().prec = 30
  5.  
  6. class Line(object):
  7.    
  8.     NO_NONZERO_ELTS_FOUND_MSG = "No nonzero elements found"
  9.  
  10.     def __init__(self, normal_vector=None, constant_term=None):
  11.  
  12.         self.dimension = 2
  13.        
  14.         if not normal_vector:
  15.             all_zeros = [0] * self.dimension
  16.             normal_vector = Vector(all_zeros)
  17.         self.normal_vector = normal_vector
  18.  
  19.         if not constant_term:
  20.             constant_term = Decimal(0)
  21.         self.constant_term = Decimal(constant_term)
  22.  
  23.         self.set_basepoint()
  24.  
  25.     def is_parallel_to(self, ell):
  26.         n1 = self.normal_vector
  27.         n2 = ell.normal_vector
  28.  
  29.         return n1.is_parallel_to(n2)
  30.  
  31.     def set_basepoint(self):
  32.  
  33.         try:
  34.             n = self.normal_vector.coordinates
  35.             c = self.constant_term
  36.             basepoint_coords = [0] * self.dimension
  37.  
  38.             initital_index = Line.first_nonzero_index(n)
  39.             initital_coefficient = n[initital_index]
  40.  
  41.             basepoint_coords[initital_index] = c / initital_coefficient
  42.             self.basepoint = Vector(basepoint_coords)
  43.  
  44.         except Exception as e:
  45.             if str(e) == Line.NO_NONZERO_ELTS_FOUND_MSG:
  46.                 self.basepoint = None
  47.             else:
  48.                 raise e
  49.  
  50.     def __str__(self):
  51.  
  52.         num_decimal_places = 3
  53.  
  54.         def write_coefficient(coefficient, is_initial_term=False):
  55.             coefficient = round(coefficient, num_decimal_places)
  56.             if coefficient % 1 == 0:
  57.                 coefficient = int(coefficient)
  58.  
  59.             output = ""
  60.  
  61.             if coefficient < 0:
  62.                 output += "-"
  63.             if coefficient > 0 and not is_initial_term:
  64.                 output += "+"
  65.  
  66.             if not is_initial_term:
  67.                 output += " "
  68.  
  69.             if abs(coefficient) != 1:
  70.                 output += "{}".format(abs(coefficient))
  71.  
  72.             return output
  73.  
  74.         n = self.normal_vector.coordinates
  75.  
  76.         try:
  77.             initital_index = Line.first_nonzero_index(n)
  78.             terms = [write_coefficient(n[i], is_initial_term=(i==initital_index)) + "x_{}".format(i + 1) for i in range(self.dimension) if round(n[i], num_decimal_places) != 0]
  79.             output = " ".join(terms)
  80.  
  81.         except Exception as e:
  82.             if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG:
  83.                 output = "0"
  84.             else:
  85.                 raise e
  86.  
  87.         constant = round(self.constant_term, num_decimal_places)
  88.         if constant % 1 == 0:
  89.             constant = int(constant)
  90.         output += " = {}".format(constant)
  91.  
  92.         return output
  93.  
  94.     def __eq__(self, ell):
  95.        
  96.         if self.normal_vector.is_zero():
  97.             if not ell.normal_vector.is_zero():
  98.                 return False
  99.             else:
  100.                 diff = self.constant_term - ell.constant_term
  101.                 return MyDecimal(diff).is_near_zero()
  102.         elif ell.normal_vector.is_zero():
  103.             return False
  104.  
  105.         if not self.is_parallel_to(ell):
  106.             return False
  107.  
  108.         x0 = self.basepoint
  109.         y0 = ell.basepoint
  110.  
  111.         basepoint_difference = x0.minus(y0)
  112.  
  113.         n = self.normal_vector
  114.         return basepoint_difference.is_orthogonal_to(n)
  115.  
  116.     def intersection_with(self, ell):
  117.         try:
  118.             A, B = self.normal_vector.coordinates
  119.             C, D = ell.normal_vector.coordinates
  120.             k1 = self.constant_term
  121.             k2 = ell.constant_term
  122.  
  123.             x_numerator = D*k1 - B*k2
  124.             y_numerator = -C*k1 + A*k2
  125.             one_over_denom = Decimal(1) / Decimal(A*D - B*C)
  126.  
  127.             return Vector([x_numerator, y_numerator]).times_scalar(one_over_denom)
  128.  
  129.         except ZeroDivisionError:
  130.             if self == ell:
  131.                 return self
  132.             else:
  133.                 return None
  134.  
  135.     @staticmethod
  136.     def first_nonzero_index(iterable):
  137.         for k, item in enumerate(iterable):
  138.             if not MyDecimal(item).is_near_zero():
  139.                 return k
  140.         raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG)
  141.  
  142. class MyDecimal(Decimal):
  143.     def is_near_zero(self, eps=1e-10):
  144.         return abs(self) < eps
  145.  
  146. ell1 = Line(normal_vector=Vector([4.046, 2.836]), constant_term=1.21)
  147. ell2 = Line(normal_vector=Vector([10.115, 7.09]), constant_term=3.025)
  148. ell1_intersection_with_ell2 = ell1.intersection_with(ell2)
  149. print("ell1_intersection_with_ell2", ell1_intersection_with_ell2, "\n")
  150.  
  151. ell3 = Line(normal_vector=Vector([7.204, 3.182]), constant_term=8.68)
  152. ell4 = Line(normal_vector=Vector([8.172, 4.114]), constant_term=9.883)
  153. ell3_intersection_with_ell4 = ell3.intersection_with(ell4)
  154. print("ell3_intersection_with_ell4", ell3_intersection_with_ell4, "\n")
  155.  
  156. ell5 = Line(normal_vector=Vector([1.182, 5.562]), constant_term=6.744)
  157. ell6 = Line(normal_vector=Vector([1.773, 8.343]), constant_term=9.525)
  158. ell5_intersection_with_ell6 = ell5.intersection_with(ell6)
  159. print("ell3_intersection_with_ell4", ell5_intersection_with_ell6, "\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement