## BTool is almost here!

(this version is outdated, click here to get the new BTool version)

This is, maybe, the most complex thing that I have never programmed, isn't finished yet..
Is dirty, has bugs and lacks, but will be improved in a future.

And that's all!

### How to use it:

At the moment all BTool functions are commands but when finished you will be able to place nice bearings without typing a word of code at all.

Inside the FreeCAD python console, import the libraries:

from BTool import *

### Automatic Placement

This is really what I wanted to achieve, although it works very rough at the moment,  select a circumference (cylinder edge) and then type at command line:

BTool()

The proper bearing should be placed automatically. This only works for shafts and the deep groove single row ball bearing type at the moment.

You can try to rotate and translate a cylinder and then repeat the above. The bearing will be placed on the desired position too!

...or should, if you try few positions, you will find that sometimes the bearing is not aligned with the shaft. I'm working to solve that, without success by now.

### Manual Input Placement

To place the most suitable bearing for a known dimension the command is:

BTool(dim,dimtype,btype,pos,normal)

The dim parameter equals to the magnitude you want to search.

The dimtype parameter sets which kind of dimension represents dim magnitude

A bearing has 3 main dimensions, inner radius, outer radius and width.

Possible values of dimtype and their meaning:

2 --> width

The dimtype conditions wich bearing will be selected from the list:

-If you select inner radius, the inner radius of the bearing will be equal or greater than the input magnitude, assuming you want to put a bearing in a shaft

-If you select outer radius, the outer radius of the bearing will be smaller or equal to the input magnitude, assuming you want to put a bearing in a hole.

-For the width there is no special function yet and will select the first bearing greater or equal.

The btype parameter means bearing type, at the moment 0 for the Deep Groove Single Row Ball Bearing and 1 for Deep Groove Double Row Ball Bearing.

The arguments pos and normal are optional. They contain vector coordinates, being pos the location of the bearing (x,y,z) and normal the axial direction of the bearing (x,y,z)

This way, the shortest command we need to manually create a bearing is, for example:

BTool(10)

That will find a Deep Groove Single Row Ball Bearing with inner radius greater or equal to 10 units and spawn it at (0,0,0)

### Adding more bearing dimensions and types:

I've developed this tool with the end user in mind. To add more dimensions of a existing type of bearing, just copy paste the inner diameter, outer diameter, width and description to their respective fields. That should be all.
Of course, the search method has to be improved and by the moment there is no way to add new types of bearings easily, this will be solved in a future.

And his is the current state of the project.

The dialog box is almost working, and will be out once I solve the placement problems.

## Sunday, 19 January 2014

### 3D Mechanism Animation with PyQtGraph

In a study break I have coded an animated 3d mechanism. Is very simple in order to get it working quickly, but shows the basics of 3d plots with pyqtgraph.

Screenshot:

Code:

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np

app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.opts['distance'] = 40
w.show()
w.setWindowTitle('3d wire crankshaft')

i=0
crankshaft=np.array(([0,0,0],[2,0,0],[2,np.cos(i),np.sin(i)],[2.5,np.cos(i),np.sin(i)],[2.5,-np.cos(i),-np.sin(i)],[3,-np.cos(i),-np.sin(i)],[3,0,0],[6,0,0]))
plt=gl.GLLinePlotItem(pos=crankshaft)

conrod1=np.array(([2.25,np.cos(i),np.sin(i)],[2.25,np.cos(i)+2.5,0]))
plt1=gl.GLLinePlotItem(pos=conrod1)

conrod2=np.array(([3.25,-np.cos(i),-np.sin(i)],[3.25,-np.cos(i)-2.5,0]))
plt2=gl.GLLinePlotItem(pos=conrod2)

def crankshaft():
global i
crankshaft=np.array(([0,0,0],[2,0,0],[2,np.cos(i),np.sin(i)],[2.5,np.cos(i),np.sin(i)],[2.5,-np.cos(i),-np.sin(i)],[3,-np.cos(i),-np.sin(i)],[3,0,0],[6,0,0]))
conrod1=np.array(([2.25,np.cos(i),np.sin(i)],[2.25,np.cos(i)+2.5,0]))
conrod2=np.array(([2.75,-np.cos(i),-np.sin(i)],[2.75,-np.cos(i)-2.5,0]))
plt.setData(pos=crankshaft)
plt1.setData(pos=conrod1)
plt2.setData(pos=conrod2)
i+=0.05

time=QtCore.QTimer()
time.timeout.connect(crankshaft)
time.start(0.1)

This time I'm not explaining line by line because I think is easy to see what is happening.
Any doubts, comment.

Bye!

## Monday, 13 January 2014

### Problem 3 formulation:

Given a line described by ax+by+c=0, create a function script with the values a,b,c as input that prints:

1-The affine transformation matrix obtained by creating a symmetry respect to the line

2-A plot of a circle with 1 unit radius centered on (0,0) and its reflection

### Solution:

##### Libraries #####

from numpy import *

import math as mt # Mistake corrected

import pyqtgraph as pg

pg.setConfigOption('background','w') # Changes plot window background to white

####################

def tafin(a,b,c):       # function declaration
window=pg.plot(title="Reflection") # Creates plot window called window
Ax=linspace(-5,5)    # Generates values from -5 to 5
Ay=-a*Ax/b-c/b       # Line equation
window.plot(Ax,Ay)       # Plots line
alpha=linspace(0,2*pi) # Generates alpha values
Bx=cos(alpha)          # X coordinates of the (0,0) centered circumference
By=sin(alpha)          # Y coordinates of the (0,0) centered circumference
window.plot(Bx,By,pen='r') # Plots (0,0) centered circumference in red colour
B1s=ones((1,size(Bx)))        # Line vector filled with 1's
F=vstack((Bx,By,B1s)) # Compounds an array from Bx,By and B1s
XA=0     # random point
YA=(-a/b)*XA-(c/b)     # Obtains one point of the symetry line
XB=1     # another random point
YB=(-a/b)*XB-(c/b)     # Obtains another point of the symetry line
# Symetry matrix
Ta1=array(([XA,XB,-a],[YA,YB,-b],[1,1,0])) # Mirrored points coincident with line
Ta2=linalg.inv(array(([XA,XB,a],[YA,YB,b],[1,1,0])))  # Original line coincident points
Ta=dot(Ta1,Ta2) # Symetry matrix
S=dot(Ta,F)     # Mirrors the circumference coordinates stored in F
window.plot(S[0,:],S[1,:],pen='b') # Plots mirrored circumference in blue
print "The affine transformation matix is"  #
print Ta   # prints affine transformation matrix

Open a terminal, paste the function and then type something like tafin(2.0,1.0,4.0)  the output should be very similar to the screenshot.

Solving this problem with python has allowed me to understand more things about this language, for example, I used to import math as * alongside with numpy as *, this should not be done. The first thing where you can see how that affects to coding is the absence of "for" bucles to operate within arrays and their elements.
This clearly makes the code easier, cleaner and more efficient and shorter than the matlab equivalent.

The new thing with the pyqtgraph module are the color plots, and plot background, easy to perform.

With this problem I finish this little section about algebra and python, hope that you got something good from it.

Bye!

## Sunday, 5 January 2014

### Problem 2 formulation:

Create a script that plots an n vertexes polygon inscribed in an ellipse with semi axis a=7, b=2. Solve for n=12

### Solution:

##### Libraries #####

from numpy import *

import pyqtgraph as pg

#####################

a=7 # Semi axis X value

b=2 # Semi axis Y value

n=12 # Polygon vertex number

window=pg.plot(title="Inscribed Polygon") #Creates plot window called window

alpha=linspace(0,2*pi) # Creates line matrix with values from 0 to 2*pi

SA=size(alpha) # Gets the size of alpha matrix

E=zeros([2,SA]) # Creates a 2xSA matrix filled with zeros

for i in range(SA): # Gets X,Y values of the ellipse and stores them in E[0,i]

E[0,i]=a*cos(alpha[i])
E[1,i]=b*sin(alpha[i])

window.plot(E[0,:],E[1,:]) # Plots the ellipse

V=zeros([2,n+1]) # Array filled with zeros that will contain polygon vertexes

alpha=0 # Variable reset

for i in range (n+1): # Bucle that obtains the coordinates of an n vertexes polygon

V[0,i]=cos(alpha)
V[1,i]=sin(alpha)
alpha+=2*pi/n

VSM=[[a,0],[0,b]] # Transformation matrix that will inscribe the polygon inside the ellipse

V=dot(VSM,V) # Transformation matrix * Polygon

window.plot(V[0,:],V[1,:]) # Plots the polygon

To see it working, open a terminal (ctrl+alt+t), type "python" and then copy-paste the code.(you need to have installed the pyqtgraph module in order to plot, see this post)

This problem is very similar to the Problem 1 and without the importing part it is almost equal to the matlab script.

Next post will be about mirroring an image with a line equation as a mirror line.

Stay tuned, bye!

### Typical degree problem & Python: Part 1

Recently I've been forced to use Matlab for solving some algebra exercises for my degree.
Matlab drives me mad in several ways and even before typing the first line of code, I've been thinking about solving the problems with python.

Let's start.

### Problem 1 formulation:

Draw an ellipse with its semi axes measuring a=5 and b=2, then create a script that plots a number n of ellipses equal in size with common center, solve for n=30. Each ellipse should be rotated an angle of pi/n radian from the previous one. The output of the script should look like this:

### Solution:

##### Libraries #####

from numpy import *

from math import *

import pyqtgraph as pg

#####################

##### Input Variables

a=7  # semi axis X value

b=2  # semi axis Y value

n=30 # number of ellipses

#####################

window=pg.plot(title="Concentric Ellipses") #Creates plot window called window

alpha=linspace(0,2*pi) # Creates line matrix with values from 0 to 2*pi

SA=size(alpha) # Gets the size of alpha matrix

E=zeros([2,SA]) # Creates a 2xSA matrix filled with zeros

for i in range(SA): # Gets X,Y values of the ellipse and stores them in E

E[0,i]=a*cos(alpha[i])
E[1,i]=b*sin(alpha[i])

beta=0 # Ellipse angle variable inicialization

for i in range(n): # Generates n concentric ellipses angled pi/n radians

TM=[[cos(beta),-sin(beta)],[sin(beta),cos(beta)]] # Transformation matrix

RE=dot(TM,E) # RE contains the coordinates of the rotated ellipse

REX=RE[0,:] # RE X values extraction
REY=RE[1,:] # RE Y values extraction

window.plot(REX,REY) # Plots the current rotated ellipse

beta+=pi/n # Increases beta by pi/n steps

To see it working, open a terminal (ctrl+alt+t), type "python" and then copy-paste the code.
(you need to have installed the pyqtgraph module in order to plot, see this post)

The main difference between python and matlab scripts for this exercise is the library import header, being the rest of them very mimetic.

Second exercise on the next post, bye!