def __init__(self, element, _pen_x, _pen_y, rX, rY, xRotation, largeArc, sweep, _end_x, _end_y ): """ 3 coordinate systems circular coordinates - in this coordinate system, the elipse is circular and unrotated elements coordinates - circular coordinates * elipse transformation (x*rX and y*Ry, then rotate to generate the elipse) global coordinates - elements coordinates * upper element transformations """ assert not ( _pen_x == _end_x and _pen_y == _end_y ) assert rX <> 0 assert rY <> 0 self._pen_x = _pen_x self._pen_y = _pen_y self._end_x = _end_x self._end_y = _end_y self.scaling = element.scaling2() #scaling between element and global coordinates self.rX = rX #in elements coordinates self.rY = rY #in elements coordinates self.xRotation = xRotation self.largeArc = largeArc self.sweep = sweep #finding center in circular coordinates # X = T_ellipse dot Y # where T_ellipse = [[c -s],[s, c]] dot [[ rX 0],[0 rY]], X is element coordinates, and Y is circular coordinates ##import FreeCAD ##FreeCAD.Console.PrintMessage( 'Xrotation %f\n' % (self.xRotation)) c = cos( xRotation*pi/180) s = sin( xRotation*pi/180) T_ellipse = dot( array([[c,-s] ,[s,c]]), array([[ rX, 0], [0, rY] ])) self.T_ellipse = T_ellipse #FreeCAD.Console.PrintMessage( 'T %s\n' % (T)) x1,y1 = numpy.linalg.solve(T_ellipse, [_pen_x, _pen_y]) x2,y2 = numpy.linalg.solve(T_ellipse, [_end_x, _end_y]) c_x_Y, c_y_Y = findCircularArcCentrePoint( 1, x1, y1, x2, y2, largeArc==1, sweep==1 ) self.center_circular = array([c_x_Y, c_y_Y]) #now determining dtheta in circular coordinates #a,b = 1,1 c = ( ( x2-x1 )**2 + ( y2-y1 )**2 ) ** 0.5 dtheta = arccos2( ( 1 + 1 - c**2 ) / ( 2 ) ) #cos rule #print(x2,x1,y2,y1,c) #print(dtheta) if not dtheta >= 0: raise SvgParseError, "dtheta not >= 0, dtheta %e. locals %s" % (dtheta, locals()) if largeArc: dtheta = 2*pi - dtheta if not sweep: # If sweep-flag is '1', then the arc will be drawn in a "positive-angle" direction dtheta = -dtheta self.dtheta = dtheta self.theta_start = atan2( y1 - c_y_Y, x1 - c_x_Y) self.T_element, self.c_element = element.Transforms() #print(self.valueAt(0), element.applyTransforms(_pen_x, _pen_y)) #print(self.valueAt(1), element.applyTransforms(_end_x, _end_y)) self.startPoint = self.valueAt(0) self.endPoint = self.valueAt(1) self.center = self.applyTransforms( self.center_circular ) self.circular = rX == rY if self.circular: self.r = rX
def t_of_position( self, pos ): pos_element = numpy.linalg.solve( self.T_element, pos - self.c_element ) A = numpy.linalg.solve(self.T_ellipse, pos_element) B = self.center_circular C = B + array([cos(self.theta_start), sin(self.theta_start)]) AB = (A - B) / norm(A-B) BC = C - B theta = arccos2(dot(AB,BC)) D = array([ A[0] - B[0], A[1] - B[1], 0.0 ]) E = array([ A[0] - C[0], A[1] - C[1], 0.0 ]) F = cross(D,E) if F[2] < 0: theta = -theta #print(theta, self.dtheta, theta / self.dtheta ) return theta / self.dtheta
def t_of_position(self, pos): pos_element = numpy.linalg.solve(self.T_element, pos - self.c_element) A = numpy.linalg.solve(self.T_ellipse, pos_element) B = self.center_circular C = B + array([cos(self.theta_start), sin(self.theta_start)]) AB = (A - B) / norm(A - B) BC = C - B theta = arccos2(dot(AB, BC)) D = array([A[0] - B[0], A[1] - B[1], 0.0]) E = array([A[0] - C[0], A[1] - C[1], 0.0]) F = cross(D, E) if F[2] < 0: theta = -theta #print(theta, self.dtheta, theta / self.dtheta ) return theta / self.dtheta
def __init__(self, element, _pen_x, _pen_y, rX, rY, xRotation, largeArc, sweep, _end_x, _end_y): """ 3 coordinate systems circular coordinates - in this coordinate system, the elipse is circular and unrotated elements coordinates - circular coordinates * elipse transformation (x*rX and y*Ry, then rotate to generate the elipse) global coordinates - elements coordinates * upper element transformations """ assert not (_pen_x == _end_x and _pen_y == _end_y) assert rX <> 0 assert rY <> 0 self._pen_x = _pen_x self._pen_y = _pen_y self._end_x = _end_x self._end_y = _end_y self.scaling = element.scaling2( ) #scaling between element and global coordinates self.rX = rX #in elements coordinates self.rY = rY #in elements coordinates self.xRotation = xRotation self.largeArc = largeArc self.sweep = sweep #finding center in circular coordinates # X = T_ellipse dot Y # where T_ellipse = [[c -s],[s, c]] dot [[ rX 0],[0 rY]], X is element coordinates, and Y is circular coordinates ##import FreeCAD ##FreeCAD.Console.PrintMessage( 'Xrotation %f\n' % (self.xRotation)) c = cos(xRotation * pi / 180) s = sin(xRotation * pi / 180) T_ellipse = dot(array([[c, -s], [s, c]]), array([[rX, 0], [0, rY]])) self.T_ellipse = T_ellipse #FreeCAD.Console.PrintMessage( 'T %s\n' % (T)) x1, y1 = numpy.linalg.solve(T_ellipse, [_pen_x, _pen_y]) x2, y2 = numpy.linalg.solve(T_ellipse, [_end_x, _end_y]) c_x_Y, c_y_Y = findCircularArcCentrePoint(1, x1, y1, x2, y2, largeArc == 1, sweep == 1) self.center_circular = array([c_x_Y, c_y_Y]) #now determining dtheta in circular coordinates #a,b = 1,1 c = ((x2 - x1)**2 + (y2 - y1)**2)**0.5 dtheta = arccos2((1 + 1 - c**2) / (2)) #cos rule #print(x2,x1,y2,y1,c) #print(dtheta) if not dtheta >= 0: raise SvgParseError, "dtheta not >= 0, dtheta %e. locals %s" % ( dtheta, locals()) if largeArc: dtheta = 2 * pi - dtheta if not sweep: # If sweep-flag is '1', then the arc will be drawn in a "positive-angle" direction dtheta = -dtheta self.dtheta = dtheta self.theta_start = arctan2(y1 - c_y_Y, x1 - c_x_Y) self.T_element, self.c_element = element.Transforms() #print(self.valueAt(0), element.applyTransforms(_pen_x, _pen_y)) #print(self.valueAt(1), element.applyTransforms(_end_x, _end_y)) self.startPoint = self.valueAt(0) self.endPoint = self.valueAt(1) self.center = self.applyTransforms(self.center_circular) self.circular = rX == rY if self.circular: self.r = rX