Thursday, December 30, 2010

30 December 2010

Finally, the pan gesture for translation is completed! The translation for all objects works very well now.

With regards to the problem that I mentioned yesterday, I actually found the cause to it. It has got to do with the object's scale in the scene! Objects with a smaller scale translate lesser while objects with a larger scale translate more, even though with the same translation value. I came to realize that when I went back to take a look at the scenes that I have created. The reason that the cylinders translated so much was because at the point of importing, the cylinders were very small in comparison to the heart model. Hence, I remembered that I actually scaled the cylinders up a lot.

Therefore, we would have to factor in the objects' scale in the scenes as well. Worked that out fairly quickly, and we are done! Hence, for translation, here are the few things that we have taken into consideration for the translation algorithm:
- Camera's Z position
- Object's Z position that is set by us when drawing (glTranslate)
- Object's default scene Z position
- Object's default scene scale

Some improvements have been made to how we pick the objects for translation as well. Previously, every time when the state of the pan gesture is being changed, we would do a check to see which object the user is touching on. Now, we have it changed to such that when the pan gesture has began, we would store the index of the object that the user has selected. This way, we have prevented some issues with collisions.

It is time to start work on labeling next week~

Wednesday, December 29, 2010

29 December 2010

Managed to get quite a few problems solved for the translation today.

I got the camera position factored into our translation algorithm, and scenes that only have objects drawn at the near plane can be translated properly. If there were to be multiple objects in the scene with different z-axes, the translation would not appear well.

What needed to be done was to factor in the translation vector of the different nodes for their individual translations, in particular, the z position. This can be easily obtained through a method that can be found in the library that we are using.

Hence, in order for the translation to work, there are 3 things that we have to take into consideration:
- Camera's z position
- Node's default scene z position
- Node's z position that is being set by us when drawing

Once that was done, I then moved on to look into another issue with the translation.

We have a scene where there is a heart model, and 4 identical cylinders. Somehow, the translation for the heart works very nicely. As for the cylinders, the translation value seemed to be too large, and the objects fly all over the view. We have another scene where there is only one cylinder in it, and it translates properly.

I am suspecting that this has got to do with the way the scene is being created. Tried working with 3DS Max to change the order in which the nodes are being drawn, and also to recreate the camera, but both did not seem to have any effect at all.

Got to do some research on this tomorrow to get an idea as to what is going on.

Tuesday, December 28, 2010

28 December 2010

Spent the day looking for the answer as to why the translations are not working as expected.

After some reading up on the OpenGL red book, I got to understand the viewing matrix better, and what the LookAtRH (by reading up on gluLookAt) method does. I realized that we would have to factor in the position of our camera this time. Reason being that the LookAtRH method actually moves our camera to another position, not at (0, 0, 0) anymore.

Monday, December 27, 2010

27 December 2010

Kevin's back today. Zac and I updated him on what we have done while he was away, and clarified some things along the way. Turns out that it would be tough for us to put in the dicom images right now at this stage. Hence, we were to put that on hold till our application is almost near the end.

Went back to 3DS Max today to create some 3D scenes for us to use in testing. Got that part up pretty quickly. All I had to do was to recall the necessary steps required to create the scene and export them into POD files. I was supposed to work on implementing labels to label the different nodes in the models for our application. However, I found out that the translation was not working for the iPad.

Hence, I went back to fix up the pan gesture for translation. Things were working well for the iPhone application, but on the iPad, the translation was a little off. Spent some more time studying the sample application, and I realized that there was this method to do the conversion view points to the eaglLayer points. The iPad view's size was larger than that of the eaglLayer that we created, hence, I figured that this would solve the problem.

- (CGPoint)convertPointFromViewToSurface:(CGPoint)point
{
CGRect rect = [self bounds];
return CGPointMake((point.x - rect.origin.x) / rect.size.width * _size.width, (point.y - rect.origin.y) / rect.size.height * _size.height);
}

- (CGRect)convertRectFromViewToSurface:(CGRect)rect
{
CGRect bounds = [self bounds];
return CGRectMake((rect.origin.x - bounds.origin.x) / bounds.size.width * _size.width, (rect.origin.y - bounds.origin.y) / bounds.size.height * _size.height, rect.size.width / bounds.size.width * _size.width, rect.size.height / bounds.size.height * _size.height);
}

Got this implemented and the translation became more accurate. There was no need for conversion in the iPhone application as the view's size is the same as the eaglLayer's size. It still was not perfect though. The translation for the heart models worked well, but not for the cylinders. I really wonder why...

Friday, December 24, 2010

24 December 2010

It's Christmas eve! Received an email few days ago from HR stating that today's a half-day.

Decided to look into the gluLookAt method in OpenGL. Though this method is not available in OpenGL ES, I figured that it would help me in one way or another in terms of figuring out the issues causing the translation to not work properly. There is a method in the c++ library that we are using to create a viewing matrix (the camera in other words) - LookAtRH. I presume that it works in a similar way as the gluLookAt method.

Though I got to read through some sources, I am still kind of puzzled. Gonna have to spend some more time next week to do this.

Thursday, December 23, 2010

23 December 2010

Resumed work on getting the pan gesture for translation up. Tried out another method of translation after studying a similar application. This method does not apply the calculation of the frustum's length at a particular z-axis, which at first made me wonder why it worked so well on that application.

- (void)panGestureCaptured:(UIGestureRecognizer *)gesture
{
...
...
...

static CGPoint currentLocation;
static CGPoint previousLocation;
ModelTransformation *obj = [[ModelTransformation alloc] init];
int objIndex = [eaglView retrieveObjectWithUniqueColors:gesture];
Vertex3D tempCurrentPosition = [eaglView getNodePositionWithIndex:objIndex];
if(gesture.state == UIGestureRecognizerStateBegan)
{
currentLocation = [gesture locationInView:[gesture view]];
currentLocation = [self convertToGL:currentLocation];
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
previousLocation = CGPointMake(currentLocation.x, currentLocation.y);
currentLocation = [gesture locationInView:[gesture view]];
currentLocation = [self convertToGL:currentLocation];
CGPoint diff = CGPointMake(currentLocation.x - previousLocation.x, currentLocation.y - previousLocation.y);
obj.xTranslation = tempCurrentPosition.x + diff.x;
obj.yTranslation = tempCurrentPosition.y + diff.y;
obj.ifTranslate = YES;
obj.node = objIndex;
[eaglView setTransformation:obj];
[obj release];
}
}

- (CGPoint)convertToGL:(CGPoint)uiPoint
{
float newY = eaglView.frame.size.height - uiPoint.y;
float newX = eaglView.frame.size.width - uiPoint.x;
CGPoint ret;
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationPortrait:
ret = CGPointMake(uiPoint.x, newY);
break;
case UIDeviceOrientationPortraitUpsideDown:
ret = CGPointMake(newX, uiPoint.y);
break;
case UIDeviceOrientationLandscapeLeft:
ret.x = uiPoint.y;
ret.y = uiPoint.x;
break;
case UIDeviceOrientationLandscapeRight:
ret.x = newY;
ret.y = newX;
break;
}
return ret;
}

This seems to work really nicely with some of the models that we have. Some of them just do not seem to work well at all.

Wednesday, December 22, 2010

22 December 2010

Seems like I have missed out something critical too. There is also this Patient Position (0018, 5100) tag that we have to factor in as well. The axes of the patient based coordinate system varies at different patient positions. The following images should illustrate this well enough:

Fig. 1 - Head First-Supine (HFS)

Fig. 2 - Feet First-Supine (FFS)

Fig. 3 - Head First-Prone (HFP)

Fig. 4 - Feet First-Prone (FFP)


Fig. 5 - Imaging Equipment

The figures above can be found from here as well, and there are also some comprehensive explanations:
http://xmedcon.sourceforge.net/Docs/OrientationXMedConPatientBased


When facing the front of the imaging equipment (refer to Fig. 5),
- Head First is defined as the patient’s head being positioned toward the front of the imaging equipment.
- Feet First is defined as the patient’s feet being positioned toward the front of the imaging equipment.
- Prone is defined as the patient’s face being positioned in a downward (gravity) direction.
- Supine is defined as the patient’s face being in an upward direction.
- Decubitus Right is defined as the patient’s right side being in a downward direction.
- Decubitus Left is defined as the patient’s left side being in a downward direction.

Here are the following terms that can be found in the Patient Position (0018, 5100) tag:
- HFP (Head First-Prone)
- HFS (Head First-Supine)
- HFDR (Head First-Decubitus Right)
- HFDL (Head First-Decubitus Left)
- FFP (Feet First-Prone)
- FFS (Feet First-Supine)
- FFDR (Feet First-Decubitus Right)
- FFDL (Feet First-Decubitus Left)


After a short discussion with Zac yesterday, I decided to look a little more into the patient-based coordinate system, in particular, to find out where the origin is. Since the position and orientation of the dicom images are provided to us with respect to the patient-based coordinate system, we would have to know where the origin is in order to map it into our models in our application. Looked around for quite some time but I cannot seem to find any sources that talks about the origin of the patient-based coordinate system.

Zac and I then had a short discussion again, and somehow we realized that we do not have a need to know the origin of the patient-based coordinate system at all. We were only loading the specific object models, not the whole human body. Hence, we would only need to know where the images should face, and at which orientation using the following 3 tags in the dicom images:
- Patient Position
- Image Position
- Image Orientation

The newly renamed images now look like this:
IM-0001-0001_x-74.798828125y-268.798828125z-82.5r100c010pFFS.png

In the case above,
x = -74.798828125
y = -268.798828125
z = -82.5
r (row vector) = (1, 0, 0)
c (column vector) = (0, 1, 0)
p (Patient Position) = FFS (Feet First-Supine)

Finally, it is time for me to move on back to work on the pan gesture to translate feature.