function [AJC_axes] = findankleaxes(fname,knee)
% read in trc file
mkr_data = dlmread(fname,'\t',6,2);
if knee == 'L'
% create xyz 3D column arrays for each marker
CAL = mkr_data(:,55:57);
TOE = mkr_data(:,58:60);
MT5 = mkr_data(:,61:63);
TB1 = mkr_data(:,46:48);
TB2 = mkr_data(:,49:51);
TB3 = mkr_data(:,52:54);
else
CAL = mkr_data(:,28:30);
TOE = mkr_data(:,31:33);
MT5 = mkr_data(:,34:36);
TB1 = mkr_data(:,19:21);
TB2 = mkr_data(:,22:24);
TB3 = mkr_data(:,25:27);
end
% define the tibia origin
originTibia=TB2;
%calculate unit vectors of Tibia segment relative to global
[e1Tibia,e2Tibia,e3Tibia]=segmentorientationV2V1(originTibia-TB1,TB3-originTibia);
%now transform the marker points into the Tibia coordinate system
for i=1:length(e1Tibia)
rotationmatrix=[e1Tibia(i,:);e2Tibia(i,:);e3Tibia(i,:)];
originTibiavector=originTibia(i,:)';
TB1Tibia(i,:)=(rotationmatrix*(TB1(i,:)')-rotationmatrix*originTibiavector)';
TH2Tibia(i,:)=(rotationmatrix*(TH2(i,:)')-rotationmatrix*originTibiavector)';
TB3Tibia(i,:)=(rotationmatrix*(TB3(i,:)')-rotationmatrix*originTibiavector)';
CALTibia(i,:)=(rotationmatrix*(CAL(i,:)')-rotationmatrix*originTibiavector)';
TOETibia(i,:)=(rotationmatrix*(TOE(i,:)')-rotationmatrix*originTibiavector)';
MT5Tibia(i,:)=(rotationmatrix*(MT5(i,:)')-rotationmatrix*originTibiavector)';
end
% decompose arrays to [x y z]
CALxTibia=CALTibia(:,1);
CALyTibia=CALTibia(:,2);
CALzTibia=CALTibia(:,3);
TOExTibia=TOETibia(:,1);
TOEyTibia=TOETibia(:,2);
TOEzTibia=TOETibia(:,3);
MT5xTibia=MT5Tibia(:,1);
MT5yTibia=MT5Tibia(:,2);
MT5zTibia=MT5Tibia(:,3);
TB1xTibia=TB1Tibia(:,1);
TB1yTibia=TB1Tibia(:,2);
TB1zTibia=TB1Tibia(:,3);
TB2xTibia=TB2Tibia(:,1);
TB2yTibia=TB2Tibia(:,2);
TB2zTibia=TB2Tibia(:,3);
TB3xTibia=TB3Tibia(:,1);
TB3yTibia=TB3Tibia(:,2);
TB3zTibia=TB3Tibia(:,3);
close;
scatter3(CALxTibia,CALyTibia,CALzTibia);
hold;
scatter3(TOExTibia,TOEyTibia,TOEzTibia);
scatter3(MT5xTibia,MT5yTibia,MT5zTibia);
scatter3(TB1xTibia,TB1yTibia,TB1zTibia,'r');
scatter3(TB3xTibia,TB3yTibia,TB3zTibia,'r');
scatter3(TB2xTibia,TB2yTibia,TB2zTibia,'r');
text(TB1xTibia(1),TB1yTibia(1),TB1zTibia(1),'TB1');
text(TB2xTibia(1),TB2yTibia(1),TB2zTibia(1),'TB2');
text(TB3xTibia(1),TB3yTibia(1),TB3zTibia(1),'TB3');
title('Left Knee Joint Instantaneous and Optimal Helical Axes. Enter to continue');
axis equal;
axis manual;
% create input matrix of tibia markers relative to Tibia segment for calculation of helical axis.
% Use soder.m and screw.m from Reinschmidt, Calgary (1996).
vectlength = size(TB1Tibia,1);
count = 0;
I=eye(3,3);
Q=zeros(3,3);
Qsum=zeros(3,3);
Qn=zeros(3,1);
Qnsum=zeros(3,1);
Qssum=zeros(3,1);
threshold = 2;
while count ==0
threshold = threshold-0.5;
for i=1:vectlength-4
input1= TB1Tibia(i:i+3,1:3);
input2= TB2Tibia(i:i+3,1:3);
input3= TB3Tibia(i:i+3,1:3);
input = [input1 input2 input3];
% create transformation matrix using singular value decomposition
[T,res]=soder(input);
% find helical axis using this transformation matrix
intersect = 1; % location of the screw axis where it intersects either the x=0 (intersect=1),
% the y=0 (intersect=2), or the z=0 (intersect=3) plane.
[n,point,phi,t]=screw(T,intersect);
% only use helical axes that are predicted with phi greater than 5 degrees
if phi>threshold
scatter3(point(1),point(2),point(3),'r')
% text(point(1),point(2),point(3),'point')
% create another 2 points along the helical axis approx the width of a knee (100 mm)
vect=(50/n(1))*n;
point2=point-vect;
point3=point+vect;
axisline=[point point2 point3];
plot3(axisline(1,:),axisline(2,:),axisline(3,:),'k')
s=point;
count=count+1;
Q=I-n*n';
Qn=Q*n;
Qs=Q*s;
Qsum=Q+Qsum;
Qnsum=Qn+Qnsum;
Qssum=Qs+Qssum;
end
end
end
Qnmean=Qnsum/count;
Qsmean=Qssum/count;
Qmean=Qsum/count;
Nopt=inv(Qmean)*Qnmean;
Sopt=inv(Qmean)*Qsmean;
half_knee_width = 50; %distance(LLFC,LMFC)/2;
% epicondylar_axis=LLFC-LMFC; % v
% knee_centre = (LLFC+LMFC)/2; %P
helical_axis_vector=(half_knee_width/Nopt(1))*Nopt;
HA1=Sopt-helical_axis_vector;
HA2=Sopt+helical_axis_vector;
axisline=[Sopt HA1 HA2];
HA1x=HA1(1);
HA1y=HA1(2);
HA1z=HA1(3);
HA2x=HA2(1);
HA2y=HA2(2);
HA2z=HA2(3);
plot3(axisline(1,:),axisline(2,:),axisline(3,:),'b','LineWidth',3)
pause;
close;
KJC_axes = [HA1 HA2];
% given that we have two axes defined, and the centre of the knee joint, we can define a plane perpendicular
% to the Epicondyle axis that intersects the centre of the knee joint. The point that this plane intersects onto
% the helical axis is defined as the new joint centre, and the helical axis can be redefined in body builder using
% two new virtual markers.
% The line of the optimal helical axis defined as:
% x = xo + at
% y = yo + bt Eq(1)
% z = zo + ct
% where xo,yo,zo describe a point along the line (such as Sopt) and describe the unit vector of the line (helical_axis_vector)
%
%The plane perpendicular to the epicondylar axis and running through the centre of the knee is defined by:
% a(x-xo)+b(y-yo)+c(z-zo)=0 Eq(2)
% where xo,yo,zo define a point on the plane (knee_centre) and define the unit vector of the perpendicular plane (epicondylar_axis)
%
% need to join Eq (1) and (2) to solve for t, then substitute this value back into eq (1)
% t = (dot(epicondylar_axis,knee_centre)-dot(epicondylar_axis,Sopt))/dot(epicondylar_axis,helical_axis_vector);
%
% new_knee_centre_x = Sopt(1)+helical_axis_vector(1)*t;
% new_knee_centre_y = Sopt(2)+helical_axis_vector(2)*t;
% new_knee_centre_z = Sopt(3)+helical_axis_vector(3)*t;
% new_knee_centre=[new_knee_centre_x;new_knee_centre_y;new_knee_centre_z];
% define new virtual markers on the helical axis (make them roughly the width of the knee).
% LHA1=new_knee_centre+helical_axis_vector;
% LHA2=new_knee_centre-helical_axis_vector;
%
% axisline=[LHA1 LHA2];
% plot3(axisline(1,:),axisline(2,:),axisline(3,:),'b','LineWidth',3)
% scatter3(new_knee_centre(1),new_knee_centre(2),new_knee_centre(3),'bo')
% text(new_knee_centre(1),new_knee_centre(2),new_knee_centre(3),'new knee centre')
% scatter3(LHA1(1),LHA1(2),LHA1(3),'ko')
% text(LHA2(1),LHA2(2),LHA2(3),'LHA 2')
% scatter3(LHA2(1),LHA2(2),LHA2(3),'ko')
% text(LHA1(1),LHA1(2),LHA1(3),'LHA 1')
%
% title('Left Knee Joint Instantaneous and Optimal Helical Axes')
% LeftKneeCentre=new_knee_centre;