-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.rb
More file actions
207 lines (162 loc) · 6.89 KB
/
Copy pathexample.rb
File metadata and controls
207 lines (162 loc) · 6.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# Copyright 2013 - 2014 by Bas de Bruijn, bdebruijn@luminize.nl
#
# This file is part of FreeBodyDiagram.
#
# FreeBodyDiagram 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 3 of the License, or
# (at your option) any later version.
#
# FreeBodyDiagram 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 FreeBodyDiagram. If not, see <http://www.gnu.org/licenses/>.
#
require "./freebodydiagram.rb"
require "./vector.rb"
require "./point.rb"
require "./equation.rb"
require "./constraint.rb"
#set this option to true if you wish to see feedback from the calculations
$global_debug = true
#clear console
system "clear"
#STDOUT.flush
print "\033[0m"
print "\033[34mtekst\r\n"
#print "\033[1mtekst\r\n"
#print "\033[0m"
# each (free) body (diagram) must have an array of points
# resulting forces and moments are calctuated w.r.t. the interface
# each point in this array is defined with respect to the interface
# other resulting interfaces from other bodies are represented as
# points with corresponfing (force/moment) vector
#todo: make an array with lines (consisting of points) in space.
#todo: make an array with planes (consisting of lines) in space.
#todo: make an array with bodies (consisting of planes) in space.
#todo: all other lines,planes and bodies are for visualising purposes
#todo: define "interface" as the result of all calculations
#todo: make method for calculating dXdYdZ out of two points
#todo: think about defining 2 vector types, Force or Moment --> Force x lenght = Moment
#todo: think about possibility to do calculations based on taking position as a function
# meaning that i want to have results from a to b in interval of c mm
#declare vectors
#todo: fill array with all vectors for easy manipulations
Fa = Vector.new('Fa','F')
Fb = Vector.new('Fb','F')
Ma = Vector.new('Ma','M')
#set vector information to get unit vector with scalar
Fa.to_vector([10,10,10])
Fb.to_vector([30,56,87])
Ma.to_vector([0,300,0])
#display info
#p Fa, Fb, Ma
#is the check on type vector working? yes!
#puts "is Fa a F vector? #{Fa.is_F_vector?}"
#puts "is Fb a M vector? #{Fb.is_M_vector?}"
#puts "is Ma a M vector? #{Ma.is_M_vector?}"
#done: get easy info on vector and scalar
puts "Fa scalar (magnitude of force) = #{Fa.scalar?}"
puts "Fa unit vector (i-j-k direction)= #{Fa.unit_vector?}"
#to find the Moment of a Force Vector with a distance there should
#be at least 1 interface. The interface is the "answer" as in
#an equation. All forces, mass, moments and other results from other
#interfaces will be calculated to this interface point.
#first check points collection and vectors collection
Points = Pointcollection.new('FBS-01-points')
PA = Point.new('P1', [1,2,3])
PB = Point.new('P2', [4,5,6])
PC = Point.new('P3', [7,8,9])
Points.add(PA)
#todo: add point as relative to origin of free body system, or add with thanslation from absolute
# for now just see the behavior of 1 body system to check the code
#todo: add multiple points together
Points.add(PB)
Points.add(PC)
#add points for using constraints
Points.add(PC1 = Point.new('PC1', [0,-5,-5]))
Points.add(PC2 = Point.new('PC2', [0,5,-5]))
Points.add(PC3 = Point.new('PC3', [0,-5,5]))
Points.add(PC4 = Point.new('PC4', [0,5,5]))
Points.add(PC5 = Point.new('PC5', [0,0,5]))
Points.show!
Loads = Vectorcollection.new('FBS-01-loads')
Loads.add(Fa, PA)
Loads.add(Fb, PB)
Loads.add(Ma, PA)
Loads.show!
#done: make constraints collection
Constraints = Constraintcollection.new('FBS-01-constraints')
Constraints.add(C1 = Constraint.new('C1', [0,0,0,0,0,0]), PC1) #wrong, needs to be [1,0,0,0,0,0]
Constraints.add(C2 = Constraint.new('C2', [0,1,0,0,0,0]), PC2)
Constraints.add(C3 = Constraint.new('C3', [1,1,0,0,0,0]), PC3)
Constraints.add(C4 = Constraint.new('C4', [1,0,0,0,0,0]), PC4)
Constraints.add(C5 = Constraint.new('C5', [0,0,1,0,0,0]), PC5)
#now make free body part "Module1"
FBDModule1 = Free_body.new('Module1', Points, Loads, Constraints)
Points.add(PD = Point.new('P4', [4,8,6]))
FBDModule1.points?.show!
eq1 = Equation.new('eq1')
eq2 = Equation.new('eq2')
eq1.arr_terms_l.each { |part| puts "factor = #{part[0]} x #{part[1]}"} #output each part of the equation in console
eq1.add_term_l([4,'Fa_x'])
eq1.add_term_l([-3, 'Fby'])
eq2.add_term_l([-6,'Fa_x'])
eq2.add_term_l([-8, 'Fbz'])
#eq1.getEQ_leftside.each { |part| puts "factor = #{part[0]} x #{part[1]}"}
Points.find('P2')
Points.find('P5')
#FBDModule1.destill_equations
#correct constrainttype
C1.setvector([1,0,0,0,0,0])
FBDModule1.destill_equations
#method to check if variable exists in the equation
#puts eq1.var_exists?("Fa_x")
#puts eq1.var_exists?("Fa_y")
#development of solver
Equation_solver = Variable_eliminator.new()
puts Equation_solver.solve(eq1, eq2, 'Fa_x') #should yield an equation
puts "#{eq1.arr_terms_l} #{eq1.flt_constant_l}"
puts "#{eq2.arr_terms_l} #{eq2.flt_constant_l}"
puts "#{Equation_solver.solve(eq1, eq2, 'Fa_x').arr_terms_l} #{Equation_solver.solve(eq1, eq2, 'Fa_x').flt_constant_l}" #should yield an equation
#make small equation matrix of 2 for testing
eq3, eq4 = Equation.new('eq3'), Equation.new('eq4')
eq3.add_term_l([4,'a'])
eq3.add_term_l([2,'b'])
eq4.add_term_l([6,'a'])
eq4.add_term_l([-1,'b'])
eq3.set_cons_l(7)
eq4.set_cons_l(-2)
puts "test for equation matrix of 2 with array of 2 variables should return resulting single equation"
puts Gauss_Jordan_matrix_solver.new([eq3, eq4], ['a', 'b']).solve
eq3.add_term_l([0,'c'])
puts Gauss_Jordan_matrix_solver.new([eq3, eq4], ['a', 'b']).solve
#below 3 test work
#puts Equation_solver.solve(eq1, eq2, 'Fa_y') #message not able to solve (Fa_y not in both)
#puts Equation_solver.solve(eq1, eq2, 'Fby') #message not able to solve (Fa_y not in both)
#puts Equation_solver.solve(eq1, eq2, 'Fbz') #message not able to solve (Fa_y not in both)
#todo: rename GaussJordanMatrix2EQsolver to equation_var_eliminator or something
# make matrix of >2 be solved with equation_var_eliminator
# add to equation_var_eliminator the output (bool?) to give the results if only 1 variables remains
# the one remaining variable should be named and given it's value.
# after this the loop can be reversed to fill all other variables
#test zero equation method
eq5 = Equation.new('eq5')
eq5.add_term_l([0, 'p'])
eq5.add_term_r([0, 'q'])
#puts eq3.is_zero_equation?
#puts eq5.is_zero_equation?
eq5.add_term_l([4, 'r'])
#puts eq5.has_only_one_term?
#puts eq4.has_only_one_term?
eq5.add_term_r([7, 't'])
#puts eq5.var_exists?('r')
#puts eq5.var_exists?('s')
eq5.set_cons_l(6)
eq5.set_cons_r(8)
puts eq5.show_summary
eq5.cleanup_to_left
puts eq5.show_summary