@@ -1243,3 +1243,144 @@ def show(m):
12431243 ax .set_ylabel ("Y" )
12441244 ax .set_zlabel ("Z" )
12451245 plt .show ()
1246+
1247+
1248+ def plot_reaction_forces (m , scale = 0.0 ):
1249+ """
1250+ Plot the reaction forces at the joints.
1251+
1252+ Parameters
1253+ ----------
1254+ m
1255+ Model dictionary.
1256+ scale
1257+ Optional: scale factor for the arrows. Forces are rendered with single
1258+ arrows. Default is 0.0, which means compute this internally.
1259+
1260+ """
1261+ ax = plt .gca ()
1262+ dim = m ["dim" ]
1263+ cd = characteristic_dimension (m )
1264+
1265+ def fun (j ):
1266+ if "reactions" in j and j ["reactions" ]:
1267+ return [v for (d , v ) in j ["reactions" ].items () if d < dim ]
1268+ else :
1269+ return [0 ]
1270+
1271+ if scale == 0.0 :
1272+ maxmag = _largest_mag_at_joints (m , fun )
1273+ if maxmag != 0 :
1274+ scale = cd / 2 / maxmag
1275+ for j in m ["joints" ].values ():
1276+ if "reactions" in j and j ["reactions" ]:
1277+ for d in j ["reactions" ].keys ():
1278+ F = zeros ((dim ,))
1279+ if d < dim :
1280+ F [d ] = j ["reactions" ][d ]
1281+ if norm (F ) > 0 :
1282+ if dim == 2 :
1283+ x , y = j ["coordinates" ]
1284+ u , v = F
1285+ ax .arrow (
1286+ x ,
1287+ y ,
1288+ scale * u ,
1289+ scale * v ,
1290+ head_width = cd / 20 ,
1291+ head_length = cd / 20 ,
1292+ color = "green" ,
1293+ )
1294+ else :
1295+ x , y , z = j ["coordinates" ]
1296+ u , v , w = F
1297+ ax .arrow3D (
1298+ x ,
1299+ y ,
1300+ z ,
1301+ scale * u ,
1302+ scale * v ,
1303+ scale * w ,
1304+ mutation_scale = 20 ,
1305+ arrowstyle = "-|>" ,
1306+ color = "green" ,
1307+ )
1308+ return ax
1309+
1310+
1311+ def plot_reaction_moments (m , scale = 0.0 , radius = 0.0 ):
1312+ """
1313+ Plot the reaction moments at the joints.
1314+
1315+ Parameters
1316+ ----------
1317+ m
1318+ Model dictionary.
1319+ scale
1320+ Optional: scale factor for the arrows. Moments are rendered with double
1321+ arrows. Default is 0.0, which means compute this internally.
1322+ radius
1323+ Radius of the circle to represent the moment (2D only). Default is 0.0,
1324+ which means compute this internally.
1325+ """
1326+ ax = plt .gca ()
1327+ dim = m ["dim" ]
1328+ ndpn = ndof_per_joint (m )
1329+ cd = characteristic_dimension (m )
1330+
1331+ def fun (j ):
1332+ if "reactions" in j and j ["reactions" ]:
1333+ return [v for (d , v ) in j ["reactions" ].items () if d >= dim ]
1334+ else :
1335+ return [0 ]
1336+
1337+ if scale == 0.0 :
1338+ maxmag = _largest_mag_at_joints (m , fun )
1339+ if maxmag != 0 :
1340+ scale = cd / 2 / maxmag
1341+ if radius <= 0.0 :
1342+ radius = cd / 10
1343+ for j in m ["joints" ].values ():
1344+ if "reactions" in j and j ["reactions" ]:
1345+ for d in j ["reactions" ].keys ():
1346+ M = zeros ((ndpn - dim ,))
1347+ if d >= dim :
1348+ M [d - dim ] = j ["reactions" ][d ]
1349+ if norm (M ) > 0 :
1350+ if dim == 2 :
1351+ x , y = j ["coordinates" ]
1352+ if M > 0 :
1353+ st = - 110
1354+ dl = 210
1355+ sense = + 1
1356+ else :
1357+ st = 80
1358+ dl = 210
1359+ sense = - 1
1360+ _drawcirc (ax , radius , x , y , st , dl , sense , color_ = "green" )
1361+ else :
1362+ x , y , z = j ["coordinates" ]
1363+ u , v , w = M
1364+ ax .arrow3D (
1365+ x ,
1366+ y ,
1367+ z ,
1368+ scale * u ,
1369+ scale * v ,
1370+ scale * w ,
1371+ mutation_scale = 20 ,
1372+ arrowstyle = "-|>" ,
1373+ color = "green" ,
1374+ )
1375+ ax .arrow3D (
1376+ x ,
1377+ y ,
1378+ z ,
1379+ scale * 0.9 * u ,
1380+ scale * 0.9 * v ,
1381+ scale * 0.9 * w ,
1382+ mutation_scale = 20 ,
1383+ arrowstyle = "-|>" ,
1384+ color = "green" ,
1385+ )
1386+ return ax
0 commit comments