Пример #1
0
 def __init__(self, M1, M2, tangent):
     self.M1 = M1.copy()
     self.M2 = M2.copy()
     self.tangent = tangent.copy()
     self.C = self.center()
     self.r = self.radius()
     self.theta1 = Vector_M1M2(self.C, self.M1).theta_x()
     self.theta2 = Vector_M1M2(self.C, self.M2).theta_x()
     self.ccw = self._get_ccw()
Пример #2
0
    def normal(self, normalized=False):
        """Return a normal to the segment.
		
		Args:
			normalized (bool):  if True, return a unit vector.
		Returns:
			:class:`~.elements.vector.Vector`
		
		"""
        return Vector_M1M2(self.M1, self.M2).normal(normalized=normalized)
Пример #3
0
    def intersection(self, other, sign_of_s=0):
        """Intersections of the segment with another element.
		
		Args:
			other (Line): another element (as of v0.18, it must be a Line)
			sign_of_s (int): if `sign_of_s !=0`,
				consider other as a half line.
				i.e. `s_other` must have the same sign
				as `sign_of_s` or intersection will be empty
		Returns:
			:obj:`list` of :class:`.Intersection`: list of intersections
		"""
        if isinstance(other, Line):
            result = Line(self.M1,
                          Vector_M1M2(self.M1,
                                      self.M2)).intersection(other, sign_of_s)
            if not result:
                # no intersection
                return []
            else:
                # there should be only one intersection
                # split the sequence unpacking in two chunks for
                # kdevelop semantic analysis
                intersection, = result
                Mi, s, eN, eT = intersection
                if abs(self.M2.x - self.M1.x) > abs(self.M2.y - self.M1.y):
                    # M1M2 closer to x axis
                    if (self.M2.x > self.M1.x):
                        # M2 to the right of M1
                        if (Mi.x < self.M1.x) or (Mi.x > self.M2.x):
                            # outside
                            return []
                    else:
                        # M2 to the left of M1
                        if (Mi.x < self.M2.x) or (Mi.x > self.M1.x):
                            # outside
                            return []
                else:
                    # M1M2 closer to y axis
                    if (self.M2.y > self.M1.y):
                        # M2 above M1
                        if (Mi.y < self.M1.y) or (Mi.y > self.M2.y):
                            # outside
                            return []
                    else:
                        # M2 below M1
                        if (Mi.y < self.M2.y) or (Mi.y > self.M1.y):
                            # outside
                            return []
        else:
            raise NotImplementedError(
                "intersection between Line and {}".format(type(other)))
        return result
Пример #4
0
    def intersection(self, other, sign_of_s=0):
        """Intersections of the arc with another element.
		
		Args:
			other (Line): another element (as of v0.18, it must be a Line)
			sign_of_s (int):
				if `sign_of_s !=0`, consider other as a half line.
				i.e. `s_other` must have the same sign
				as `sign_of_s` or intersection will be empty
		
		Returns:
			:obj:`list` of :class:`.Intersection`: list of intersections
		
		"""
        result = []
        if isinstance(other, Line):
            s_list = []
            a = other.u.x**2 + other.u.y**2
            if a != 0:
                b = (other.u.x * (other.p.x - self.C.x) + other.u.y *
                     (other.p.y - self.C.y))
                c = ((other.p.x - self.C.x)**2 + (other.p.y - self.C.y)**2 -
                     self.r**2)
                # reduced discriminant
                delta = b**2 - a * c
                # compute roots
                if delta > 0:
                    # this way is numerically more stable (?)
                    if b >= 0:
                        q = -b - sqrt(delta)
                    else:
                        q = -b + sqrt(delta)
                    # two roots
                    s1 = q / a
                    s2 = c / q
                    s_list.extend([s1, s2])
                elif delta == 0:
                    # one root
                    s = -b / a
                    s_list.append(s)
            for s in s_list:
                # intersection point
                M = other.point(s)
                if (M in self) and (s * sign_of_s >= 0):
                    # normal is \vec{CM}/CM
                    eN = Vector_M1M2(self.C, M).normalize()
                    # tangent is orthogonal to normal for a circle
                    eT = eN.normal(normalized=True)
                    result.append(Intersection(M, s, eN, eT))
        else:
            raise NotImplementedError(
                "intersection between Line and {}".format(type(other)))
        return result
Пример #5
0
    def center(self):
        """Return the arc center."""

        # middle of the chord
        Mm = (self.M1 + self.M2) * 0.5
        # normal to the chord
        Vch = Vector_M1M2(self.M1, self.M2).normal()
        # normal to the tangent
        Vtg = self.tangent.normal()
        # normally there should be only one intersection
        # there should be only one intersection
        intersection, = Line(Mm, Vch).intersection(Line(self.M1, Vtg))
        C = intersection.p
        return C
Пример #6
0
    def __contains__(self, M):
        """Return `True` if the point M belongs to the arc sector.
		
		Distances are not checked.
		"""
        theta_i = Vector_M1M2(self.C, M).theta_x()
        if self.theta2 < self.theta1:
            if self.theta2 < theta_i < self.theta1:
                return not self.ccw
            else:
                return self.ccw
        else:
            if self.theta1 < theta_i < self.theta2:
                return self.ccw
            else:
                return not self.ccw
Пример #7
0
 def _get_ccw(self):
     """Return true if the arc goes from M1 to M2 ccw."""
     CM1 = Vector_M1M2(self.C, self.M1)
     return ((CM1.x * self.tangent.y - CM1.y * self.tangent.x) > 0)
Пример #8
0
 def radius(self):
     """Return the arc radius of curvature."""
     return Vector_M1M2(self.M1, self.center()).norm()