X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f X-Recipient: geda-user AT delorie DOT com Date: Fri, 8 Mar 2019 19:19:51 +0100 (CET) From: Roland Lutz To: "(mail AT crcomp DOT net) [via geda-user AT delorie DOT com]" Subject: Re: [geda-user] Re: Is FreeRotateBuffer implemented in gschem? In-Reply-To: <201903081710.x28HAAUG016981@delorie.com> Message-ID: References: <201903081710 DOT x28HAAUG016981 AT delorie DOT com> User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset=US-ASCII Reply-To: geda-user AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: geda-user AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On Fri, 8 Mar 2019, (mail AT crcomp DOT net) [via geda-user AT delorie DOT com] wrote: > FreeRotateBuffer allows any degree of rotation, which is more versatile > than "E R"'s fixed 90?? rotation. gschem does not support rotation by an arbitrary angle. > My goal to rotate a zenier diode by 45?? in gschem seems unobtainable > at present. You can achieve this using the new Xorn-based libraries. This isn't integrated with gschem yet, but you can create and run a stand-alone script: #!/usr/bin/env python import math, sys import xorn.storage import gaf.read import gaf.write def rotate(rev, angle): for ob in rev.all_objects(): if isinstance(ob.data(), xorn.storage.Arc): ob.x, ob.y = (math.cos(angle) * ob.x - math.sin(angle) * ob.y, math.cos(angle) * ob.y + math.sin(angle) * ob.x) ob.startangle += angle * 180. / math.pi ob.sweepangle += angle * 180. / math.pi elif isinstance(ob.data(), xorn.storage.Circle) or \ isinstance(ob.data(), xorn.storage.Component) or \ isinstance(ob.data(), xorn.storage.Text): ob.x, ob.y = (math.cos(angle) * ob.x - math.sin(angle) * ob.y, math.cos(angle) * ob.y + math.sin(angle) * ob.x) elif isinstance(ob.data(), xorn.storage.Line) or \ isinstance(ob.data(), xorn.storage.Net): x0, y0 = ob.x, ob.y x1, y1 = ob.x + ob.width, ob.y + ob.height x0, y0 = (math.cos(angle) * x0 - math.sin(angle) * y0, math.cos(angle) * y0 + math.sin(angle) * x0) x1, y1 = (math.cos(angle) * x1 - math.sin(angle) * y1, math.cos(angle) * y1 + math.sin(angle) * x1) ob.x, ob.y = x0, y0 ob.width, ob.height = x1 - x0, y1 - y0 else: sys.stderr.write("Rotating %s object is not supported!\n" % ob.data().__class__.__name__) def main(): if len(sys.argv) != 3: sys.stderr.write("Usage: %s SYMBOL ANGLE\n" % sys.argv[0]) sys.exit(1) path = sys.argv[1] try: angle = float(sys.argv[2]) * math.pi / 180. except ValueError: sys.stderr.write("'%s' is not a valid angle\n") sys.exit(1) try: rev = gaf.read.read(path) except IOError as e: sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], path, e.strerror)) sys.exit(1) except UnicodeDecodeError as e: sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], path, str(e))) sys.exit(1) except gaf.read.ParseError: sys.exit(1) rotate(rev, angle) try: gaf.write.write(rev, path) except IOError as e: sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], path, e.strerror)) sys.exit(1) if __name__ == '__main__': main()