home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Inkscape / Inkscape-0.48.2-1-win32.exe / share / extensions / triangle.py < prev    next >
Text File  |  2011-07-08  |  8KB  |  198 lines

  1. #!/usr/bin/env python 
  2. '''
  3. Copyright (C) 2007 John Beard john.j.beard@gmail.com
  4.  
  5. ##This extension allows you to draw a triangle given certain information
  6. ## about side length or angles.
  7.  
  8. ##Measurements of the triangle
  9.  
  10.          C(x_c,y_c)                              
  11.         /`__                                     
  12.        / a_c``--__                               
  13.       /           ``--__ s_a                     
  14.  s_b /                  ``--__                   
  15.     /a_a                    a_b`--__             
  16.    /--------------------------------``B(x_b, y_b)
  17.   A(x_a,y_a)         s_b                         
  18.  
  19.  
  20. This program is free software; you can redistribute it and/or modify
  21. it under the terms of the GNU General Public License as published by
  22. the Free Software Foundation; either version 2 of the License, or
  23. (at your option) any later version.
  24.  
  25. This program is distributed in the hope that it will be useful,
  26. but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28. GNU General Public License for more details.
  29.  
  30. You should have received a copy of the GNU General Public License
  31. along with this program; if not, write to the Free Software
  32. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  33. '''
  34.  
  35. import inkex
  36. import simplestyle, sys
  37. from math import *
  38.  
  39. def draw_SVG_tri( (x1, y1), (x2, y2), (x3, y3), (ox,oy), width, name, parent):
  40.     style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' }
  41.     tri_attribs = {'style':simplestyle.formatStyle(style),
  42.                     inkex.addNS('label','inkscape'):name,
  43.                     'd':'M '+str(x1+ox)+','+str(y1+oy)+
  44.                        ' L '+str(x2+ox)+','+str(y2+oy)+
  45.                        ' L '+str(x3+ox)+','+str(y3+oy)+
  46.                        ' L '+str(x1+ox)+','+str(y1+oy)+' z'}
  47.     inkex.etree.SubElement(parent, inkex.addNS('path','svg'), tri_attribs )
  48.     
  49. def angle_from_3_sides(a, b, c): #return the angle opposite side c
  50.     cosx = (a*a + b*b - c*c)/(2*a*b)  #use the cosine rule
  51.     return acos(cosx)
  52.  
  53. def third_side_from_enclosed_angle(s_a,s_b,a_c): #return the side opposite a_c
  54.     c_squared = s_a*s_a + s_b*s_b -2*s_a*s_b*cos(a_c)
  55.     if c_squared > 0:
  56.         return sqrt(c_squared)
  57.     else:
  58.         return 0 #means we have an invalid or degenerate triangle (zero is caught at the drawing stage)
  59.  
  60. def pt_on_circ(radius, angle): #return the x,y coordinate of the polar coordinate
  61.     x = radius * cos(angle)
  62.     y = radius * sin(angle)
  63.     return [x, y]
  64.  
  65. def v_add( (x1,y1),(x2,y2) ):#add an offset to coordinates
  66.     return [x1+x2, y1+y2]
  67.  
  68. def is_valid_tri_from_sides(a,b,c):#check whether triangle with sides a,b,c is valid
  69.     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
  70.                 #no zero-length sides, no degenerate case
  71.  
  72. def draw_tri_from_3_sides(s_a, s_b, s_c, offset, parent): #draw a triangle from three sides (with a given offset
  73.     if is_valid_tri_from_sides(s_a,s_b,s_c):
  74.         a_b = angle_from_3_sides(s_a, s_c, s_b)
  75.                 
  76.         a = (0,0)    #a is the origin
  77.         b = v_add(a, (s_c, 0)) #point B is horizontal from the origin
  78.         c = v_add(b, pt_on_circ(s_a, pi-a_b) ) #get point c
  79.         c[1] = -c[1]
  80.         
  81.         offx = max(b[0],c[0])/2 #b or c could be the furthest right
  82.         offy = c[1]/2 #c is the highest point
  83.         offset = ( offset[0]-offx , offset[1]-offy ) #add the centre of the triangle to the offset
  84.                
  85.         draw_SVG_tri(a, b, c , offset, 2, 'Triangle', parent)
  86.     else:
  87.         sys.stderr.write('Error:Invalid Triangle Specifications.\n')
  88.  
  89. class Grid_Polar(inkex.Effect):
  90.     def __init__(self):
  91.         inkex.Effect.__init__(self)
  92.         self.OptionParser.add_option("--s_a",
  93.                         action="store", type="float", 
  94.                         dest="s_a", default=100.0,
  95.                         help="Side Length a")
  96.         self.OptionParser.add_option("--s_b",
  97.                         action="store", type="float", 
  98.                         dest="s_b", default=100.0,
  99.                         help="Side Length b")
  100.         self.OptionParser.add_option("--s_c",
  101.                         action="store", type="float", 
  102.                         dest="s_c", default=100.0,
  103.                         help="Side Length c")
  104.         self.OptionParser.add_option("--a_a",
  105.                         action="store", type="float", 
  106.                         dest="a_a", default=60.0,
  107.                         help="Angle a")
  108.         self.OptionParser.add_option("--a_b",
  109.                         action="store", type="float", 
  110.                         dest="a_b", default=30.0,
  111.                         help="Angle b")
  112.         self.OptionParser.add_option("--a_c",
  113.                         action="store", type="float", 
  114.                         dest="a_c", default=90.0,
  115.                         help="Angle c")
  116.         self.OptionParser.add_option("--mode",
  117.                         action="store", type="string", 
  118.                         dest="mode", default='3_sides',
  119.                         help="Side Length c")
  120.     
  121.     def effect(self):
  122.         
  123.         tri = self.current_layer
  124.         offset = (self.view_center[0],self.view_center[1]) #the offset require to centre the triangle
  125.         
  126.         if self.options.mode == '3_sides':
  127.             s_a = self.options.s_a
  128.             s_b = self.options.s_b
  129.             s_c = self.options.s_c
  130.             draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  131.         
  132.         elif self.options.mode == 's_ab_a_c':
  133.             s_a = self.options.s_a
  134.             s_b = self.options.s_b
  135.             a_c = self.options.a_c*pi/180 #in rad
  136.             
  137.             s_c = third_side_from_enclosed_angle(s_a,s_b,a_c)
  138.             draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  139.         
  140.         elif self.options.mode == 's_ab_a_a':
  141.             s_a = self.options.s_a
  142.             s_b = self.options.s_b
  143.             a_a = self.options.a_a*pi/180 #in rad
  144.             
  145.             if (a_a < pi/2.0) and (s_a < s_b) and (s_a > s_b*sin(a_a) ): #this is an ambigous case
  146.                 ambiguous=True#we will give both answers
  147.             else:
  148.                 ambiguous=False
  149.             
  150.             sin_a_b =  s_b*sin(a_a)/s_a
  151.             
  152.             if (sin_a_b <= 1) and (sin_a_b >= -1):#check the solution is possible
  153.                 a_b = asin(sin_a_b) #acute solution
  154.                 a_c = pi - a_a - a_b
  155.                 error=False
  156.             else:
  157.                 sys.stderr.write('Error:Invalid Triangle Specifications.\n')#signal an error
  158.                 error=True
  159.             
  160.             if not(error) and (a_b < pi) and (a_c < pi): #check that the solution is valid, if so draw acute solution
  161.                 s_c = third_side_from_enclosed_angle(s_a,s_b,a_c)
  162.                 draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  163.             
  164.             if not(error) and ((a_b > pi) or (a_c > pi) or ambiguous):#we want the obtuse solution
  165.                 a_b = pi - a_b
  166.                 a_c = pi - a_a - a_b
  167.                 s_c = third_side_from_enclosed_angle(s_a,s_b,a_c)
  168.                 draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  169.         
  170.         elif self.options.mode == 's_a_a_ab':
  171.             s_a = self.options.s_a
  172.             a_a = self.options.a_a*pi/180 #in rad
  173.             a_b = self.options.a_b*pi/180 #in rad
  174.             
  175.             a_c = pi - a_a - a_b
  176.             s_b = s_a*sin(a_b)/sin(a_a)
  177.             s_c = s_a*sin(a_c)/sin(a_a)
  178.             
  179.             draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  180.         
  181.         elif self.options.mode == 's_c_a_ab':
  182.             s_c = self.options.s_c
  183.             a_a = self.options.a_a*pi/180 #in rad
  184.             a_b = self.options.a_b*pi/180 #in rad
  185.             
  186.             a_c = pi - a_a - a_b
  187.             s_a = s_c*sin(a_a)/sin(a_c)
  188.             s_b = s_c*sin(a_b)/sin(a_c)
  189.             
  190.             draw_tri_from_3_sides(s_a, s_b, s_c, offset, tri)
  191.  
  192. if __name__ == '__main__':
  193.     e = Grid_Polar()
  194.     e.affect()
  195.  
  196.  
  197. # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
  198.