From: ozmikepittman Date: Sat, 3 May 2008 22:17:07 +0000 (+0000) Subject: Adding Triangle Extension - See LP#226001 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=f4f91c9752d845ba4e62f276ebf6e8e57eca70e8;p=inkscape.git Adding Triangle Extension - See LP#226001 --- diff --git a/po/POTFILES.in b/po/POTFILES.in index b47069392..5ea99dc81 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -396,6 +396,7 @@ src/winmain.cpp [type: gettext/xml] share/extensions/text_titlecase.inx [type: gettext/xml] share/extensions/text_uppercase.inx [type: gettext/xml] share/extensions/txt2svg.inx +[type: gettext/xml] share/extensions/triangle.inx [type: gettext/xml] share/extensions/whirl.inx [type: gettext/xml] share/extensions/wmf_input.inx [type: gettext/xml] share/extensions/xaml2svg.inx diff --git a/share/extensions/Makefile.am b/share/extensions/Makefile.am index b41b4a417..4544b0866 100644 --- a/share/extensions/Makefile.am +++ b/share/extensions/Makefile.am @@ -104,6 +104,7 @@ extensions = \ text_randomcase.py \ text_replace.py \ text_braille.py \ + triangle.py \ txt2svg.pl \ uniconv-ext.py \ whirl.py @@ -208,6 +209,7 @@ modules = \ text_randomcase.inx \ text_replace.inx \ text_braille.inx \ + triangle.inx \ txt2svg.inx \ whirl.inx \ wmf_input.inx \ diff --git a/share/extensions/triangle.inx b/share/extensions/triangle.inx new file mode 100644 index 000000000..3e5748e6e --- /dev/null +++ b/share/extensions/triangle.inx @@ -0,0 +1,28 @@ + + + <_name>Triangle + math.triangle + triangle.py + inkex.py + 100.0 + 100.0 + 100.0 + 60 + 30 + 90 + + <_option value="3_sides">From Three Sides + <_option value="s_ab_a_c">From Sides a, b and Angle c + <_option value="s_ab_a_a">From Sides a, b and Angle a + <_option value="s_a_a_ab">From Side a and Angles a, b + <_option value="s_c_a_ab">From Side c and Angles a, b + + all + + + + + + \ No newline at end of file diff --git a/share/extensions/triangle.py b/share/extensions/triangle.py new file mode 100644 index 000000000..22c8633f0 --- /dev/null +++ b/share/extensions/triangle.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +''' +Copyright (C) 2007 John Beard john.j.beard@gmail.com + +##This extension allows you to draw a triangle given certain information +## about side length or angles. + +##Measurements of the triangle + + C(x_c,y_c) + /`__ + / a_c``--__ + / ``--__ s_a + s_b / ``--__ + /a_a a_b`--__ + /--------------------------------``B(x_b, y_b) + A(x_a,y_a) s_b + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' + +import inkex +import simplestyle, sys +from math import * + +def draw_SVG_tri( (x1, y1), (x2, y2), (x3, y3), (ox,oy), width, name, parent): + style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' } + tri_attribs = {'style':simplestyle.formatStyle(style), + 'inkscape:label':name, + 'd':'M '+str(x1+ox)+','+str(y1+oy)+ + ' L '+str(x2+ox)+','+str(y2+oy)+ + ' L '+str(x3+ox)+','+str(y3+oy)+ + ' L '+str(x1+ox)+','+str(y1+oy)+' z'} + inkex.etree.SubElement(parent, inkex.addNS('path','svg'), tri_attribs ) + +def angle_from_3_sides(a, b, c): #return the angle opposite side c + cosx = (a*a + b*b - c*c)/(2*a*b) #use the cosine rule + return acos(cosx) + +def third_side_from_enclosed_angle(s_a,s_b,a_c): #return the side opposite a_c + c_squared = s_a*s_a + s_b*s_b -2*s_a*s_b*cos(a_c) + if c_squared > 0: + return sqrt(c_squared) + else: + return 0 #means we have an invalid or degenerate triangle (zero is caught at the drawing stage) + +def pt_on_circ(radius, angle): #return the x,y coordinate of the polar coordinate + x = radius * cos(angle) + y = radius * sin(angle) + return [x, y] + +def v_add( (x1,y1),(x2,y2) ):#add an offset to coordinates + return [x1+x2, y1+y2] + +def is_valid_tri_from_sides(a,b,c):#check whether triangle with sides a,b,c is valid + return (a+b)>c and (a+c)>b and (b+c)>a and a > 0 and b> 0 and c>0#two sides must always be greater than the third + #no zero-length sides, no degenerate case + +def draw_tri_from_3_sides(s_a, s_b, s_c, offset, parent): #draw a triangle from three sides (with a given offset + if is_valid_tri_from_sides(s_a,s_b,s_c): + a_b = angle_from_3_sides(s_a, s_c, s_b) + + a = (0,0) #a is the origin + b = v_add(a, (s_c, 0)) #point B is horizontal from the origin + c = v_add(b, pt_on_circ(s_a, pi-a_b) ) #get point c + c[1] = -c[1] + + offx = max(b[0],c[0])/2 #b or c could be the furthest right + offy = c[1]/2 #c is the highest point + offset = ( offset[0]-offx , offset[1]-offy ) #add the centre of the triangle to the offset + + draw_SVG_tri(a, b, c , offset, 2, 'Triangle', parent) + else: + sys.stderr.write('Error:Invalid Triangle Specifications.\n') + +class Grid_Polar(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("--s_a", + action="store", type="float", + dest="s_a", default=100.0, + help="Side Length a") + self.OptionParser.add_option("--s_b", + action="store", type="float", + dest="s_b", default=100.0, + help="Side Length b") + self.OptionParser.add_option("--s_c", + action="store", type="float", + dest="s_c", default=100.0, + help="Side Length c") + self.OptionParser.add_option("--a_a", + action="store", type="float", + dest="a_a", default=60.0, + help="Angle a") + self.OptionParser.add_option("--a_b", + action="store", type="float", + dest="a_b", default=30.0, + help="Angle b") + self.OptionParser.add_option("--a_c", + action="store", type="float", + dest="a_c", default=90.0, + help="Angle c") + self.OptionParser.add_option("--mode", + action="store", type="string", + dest="mode", default='3_sides', + help="Side Length c") + + def effect(self): + + tri = self.current_layer + offset = (self.view_center[0],self.view_center[1]) #the offset require to centre the triangle + + if self.options.mode == '3_sides': + s_a = self.options.s_a + s_b = self.options.s_b + s_c = self.options.s_c + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + + elif self.options.mode == 's_ab_a_c': + s_a = self.options.s_a + s_b = self.options.s_b + a_c = self.options.a_c*pi/180 #in rad + + s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + + elif self.options.mode == 's_ab_a_a': + s_a = self.options.s_a + s_b = self.options.s_b + a_a = self.options.a_a*pi/180 #in rad + + if (a_a < pi/2.0) and (s_a < s_b) and (s_a > s_b*sin(a_a) ): #this is an ambigous case + ambiguous=True#we will give both answers + else: + ambiguous=False + + sin_a_b = s_b*sin(a_a)/s_a + + if (sin_a_b <= 1) and (sin_a_b >= -1):#check the solution is possible + a_b = asin(sin_a_b) #acute solution + a_c = pi - a_a - a_b + error=False + else: + sys.stderr.write('Error:Invalid Triangle Specifications.\n')#signal an error + error=True + + if not(error) and (a_b < pi) and (a_c < pi): #check that the solution is valid, if so draw acute solution + s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + + if not(error) and ((a_b > pi) or (a_c > pi) or ambiguous):#we want the obtuse solution + a_b = pi - a_b + a_c = pi - a_a - a_b + s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + + elif self.options.mode == 's_a_a_ab': + s_a = self.options.s_a + a_a = self.options.a_a*pi/180 #in rad + a_b = self.options.a_b*pi/180 #in rad + + a_c = pi - a_a - a_b + s_b = s_a*sin(a_b)/sin(a_a) + s_c = s_a*sin(a_c)/sin(a_a) + + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + + elif self.options.mode == 's_c_a_ab': + s_c = self.options.s_c + a_a = self.options.a_a*pi/180 #in rad + a_b = self.options.a_b*pi/180 #in rad + + a_c = pi - a_a - a_b + s_a = s_c*sin(a_a)/sin(a_c) + s_b = s_c*sin(a_b)/sin(a_c) + + draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri) + +e = Grid_Polar() +e.affect() +