|
Stephen Hewitt wrote: For example a "p" to name a pointer is usefull and will not pose any problems in the future. And if you do, say, change the pointer to a reference, you would have to visit every use of it anyway so no problem.
I agree absolutely on the p designation of pointer and require it in my work (or ptr prefix). But the primary problem with hungarian notation is that it forces you to define two separate rules for naming conventions, one based on C/C++ types and one for your own types.
if I make a variable for x as an integer it is iX, but if I make a vector matrix for multidimensional matrix definitions is it vX? usually no. You then start defining a set of rules exceptions if you will when you will use type designation and when you will not, two separate rules rather than one consistant one. Is mX a map X or a multimap X? is hX a hex string of X or a hash table? Thus you get into enlarging your naming convention to cover all things.
myClass myClassUsageVariable;
myClass *p_myClassUsageVariable;
// or
myClass mcUsageVariable;
myClass *p_mcUsageVariable;
// matches this?
int iIterator;
int *p_iIterator;
// or
int intIterator;
int *p_intIterator;
generally type conventions do not ask hungarian for user classes so then you have:
myClass UsageVariable;
int iIterator;
and start drawing out a long line of rules on what should be combined into hungarian and what should not, two completely different naming conventions. Or worse you decide that everything should be listed in hungarian including class, namespace, orignator of the class, as well as type. Now your variable name is taking the place of documentation. (I have had someone try to request this)
using namespace boost; // 3rd party library from boost
shared_ptr boost_boost_sharedptr_pEarthProjection;
Since boost has shared_ptr and scoped_ptr sp is not enough, so either you start enlarging your type definitions or removing them for all 3rd party and user defined work. Again, making two sets of naming conventions, which I consider worse. It also doesn't provide you with any more information that a proper IDE will. A professional tool will tell you the type, good documentation will tell you the type, auto documentation will tell you the type. But hungarian notation just makes life more difficult.
I did say the subject opens up a religion war of types. I agree with the idea that hungarian notation actually reduces object oriented design and creates redundant overhead and restricts future growth so significantly as to actually damage every product cycle it is used in. You find yourself saying "I don't want to make that change, because it requires me to change all the variable names in 100 source files to upgrade quantity from integer to double" so we will continue selling our software to DVD end-sales and not warehouses so that we do not have to deal with crate SKU quantities (including partials) as well as whole. Now you are redefining your companies goals based on the choice of a variable.
I do not ask everyone to give up hungarian, but I will fight it on my team-projects because the rules are inconsistant, or so redundant as to make it unusable and restrictive.
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
I totally agree that some people go overboard with Hungarian notation, presumably in the belief that it will make their code easier to understand.
Me, I have four rules: a pointer variable always starts with p, and a class member variable always starts with m_ and boolean variables always start with b (unless they are called ok or failed). Finally all (of the very few) global variables start with a g_ to highlight that they are global. (I once came across some code, perhaps 200 lines, where the 'programmer' (or idiot, more likely) had defined a global variable called i presumably to save having to define it in every function!)
The first rule certainly helps save confusion, like, Is what I am passing to this function a pointer or a reference? The second rule's benefit comes largely from the fact that with complicated code it is easy to run out of variable names. By sticking a tag in front of a load of the variables, I create room for more. The g_ and m_ prefixes certainly help me stop worrying how the variable got its value.
As for putting an i in front to show that the value is an integer, this is a waste of time at best. And I don't see the point in adding a prefix to strings to indicate that they are null terminated. How many strings are NOT null terminated? Besides, suppose I decide to define
CString Name;
and later in the interests of speed decide to redefine as
char Name[100];
Should I rename Name as psName to show that it is now a pointer to a string? Or call it sName to show that it is an array which works as a string? No, just call it Name, capitalised here because it is an important variable, as distinct from name which is just some temporary name used very locally, a throw-away version.
A name should describe the purpose or algorithmic behavior, not the implementation. The IDE will tell me about implementation. As a programmer looking at ancient code I wrote last month, I want to get an idea of what the code is meant to be doing, what its purpose is, and I do not want to be distracted by irrelevant low level details.
Shraddhan
If you want my advice, contact my secretary for a quotation first.
|
|
|
|
|
hi all, this is more of a design question than a code question, but:
i have a class in my code which represents a file. often i have a member specifying the current filename, and code within the class which loads a file and saves a file.
i was wondering what the generally accepted technique is (if there is one), to store the filename and file code within the class, to store just the file code in the class and the filename outside, or to store all of those outside.
example pseudo-code:
class myfile {<br />
public:<br />
LPTSTR filename;
BOOL dirty;
int data;<br />
<br />
static myfile *LoadFile(LPTSTR fn);<br />
void SaveFile();<br />
};
thanx in advance
|
|
|
|
|
generally you do not want to store just a pointer to a string, you will want to store a string. Also unless you want to expose all that to the all the programmers, make filename, dirty, data all private. Expose a couple of functions to request a copy of or set the filename. That gets into personal preference.
I will give my reasoning for not storing a pointer only as the filename.
A) it is pointing to data outside the class (where ever the string storage was for the original call). This means you will have bugs when ever that data storage is not persistant, or force you to use global variables. In either case you find the class design controlling behavior outside of itself, which is bad news.
B) local storage just makes easier control. copy, verify, error control, manipulation of the name (filename.backup) when you want to make backup copies or working versions. It actually increases your useability of the class for future design changes/features.
C) it fits with the whole idea of object oriented, keep all your data in respect to the class inside the class, or in a friendly class. Too much interconnection/dependancy increases difficulty in understanding.
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
I've inherited an image processing task which I didn't initially write, but which I need to modify - I need to change an input parameter according to the position within the input image. Naturally, the code works by iterating over the destination image, but now I need to change it to iterate over the source image, so I can work out this parameter as I go. The parameter is called sourceFOVRads ( for reference in the code ). The trouble is, I can't work out how to reverse the code so that it iterates over the source instead of destination image. Of course, I know how to iterate over an image using polar co-ordinates, but I think the transform needs to be completely rewritten, I don't see how to reverse the Atan2 calls to get the input parameters.
for(int j=0;j<output.height;j++)
{
for(int="" i="0;i<output.Width;i++)
" {
="" double="" x="2" *="" (double)output.width="" -="" 1;="" -1="" to="" 1
="" y="2" j="" (double)output.height="" calculate="" phi="" and="" theta=""
="" latitude="y*Math.PI/2;" -pi="" 2="" <="y" pi="" longitude="x*Math.PI;"
="" p="" is="" the="" vector="" from="" camera="" position="" into="" scene="" p.x="Math.Cos(latitude)*" math.sin(longitude);
="" p.y="Math.Cos(latitude)*" math.cos(longitude);
="" p.z="Math.Sin(latitude);
" fisheye="" polar="" coordinates
="" r="pixelRadius*phi" sourcefovrads;
="" determine="" coordinate="" in="" source="" image
="" u="Convert.ToInt32(fishCentre.X" +="" r*math.cos(theta));
="" if(u="" 0="" ||="">=source.Width)
continue;
v=Convert.ToInt32(fishCentre.Y - r*Math.Sin(theta));
if(v < 0 || v>=source.Height)
continue;
pOut[(outputStride*j)+(i*3)]=(Byte)(int)pSrc[(sourceStride*v)+(u*3)];
pOut[(outputStride*j)+(i*3)+ 1]=(Byte)(int)pSrc[(sourceStride*v)+(u*3)+ 1];
pOut[(outputStride*j)+(i*3)+ 2]=(Byte)(int)pSrc[(sourceStride*v)+(u*3)+ 2];
As I said, I can do the basic stuff, like so:
for (double t = 0; t < 2 * Math.PI; t += .01)
{
for (int radius = 0; radius < pixelRadius; ++radius)
{
int xSrc = (int)(radius * Math.Cos(t)) + fishCentre.X;
int x = 2 * (xSrc/source.Width) - 1;
int ySrc = (int)(radius * Math.Sin(t)) + fishCentre.Y;
int y = 2 * (xSrc/source.Height) - 1;
pOut[(int)(x*3 + y * sourceStride)] = pSrc[(int)(x*3 + y * sourceStride)];
pOut[(int)(x*3 + 1 + y * sourceStride)] = pSrc[(int)(x*3 + 1 + y * sourceStride)];
pOut[(int)(x*3 + 2 + y * sourceStride)] = pSrc[(int)(x*3 + 2 + y * sourceStride)];
}
}
This code uses polar co-ordinates to copy just the circle of the image that we're interested in, without any transform. It steps over the theta far too quickly mostly so I can quickly see the results of my code
However, in this block:
theta=Math.Atan2(p.z,p.x);
phi=Math.Atan2(Math.Sqrt(p.x*p.x+p.z*p.z),p.y);
r=pixelRadius*phi / sourceFOVRads;
I don't know where to start. I have the pixel radius and r, and as I have my source radius, I can calculate which sourceFOVRads value to use, so I can work out phi, easily. But, I obviously cannot derive the values for p.x, p.y and p.z from this value, and I'm not sure how else to go about it. Any help on this will be greatly appreciated, because I am really stuck.
BTW, the code is C#, I posted it here for visibility.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Christian,
What do r, pixelRadius and sourceFOVRads represent?
-Sean
----
Shag a Lizard
|
|
|
|
|
r is the radius of the current postion in the source image, in polar co-ords. pixelRadius is the radius of the circle we're working with. sourceFOVRads is the parameter I need to change based on radius in the source image. I've done some code to try and do this with the current transform, but it doesn't work 100%.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
In general there is a good reason why such algoriths iterate over the destination image - It ensures that the destination image is fully covered (no gaps) and that we don't get multiple writes to a single pixel.
Steve
|
|
|
|
|
That's why I said 'naturally'. However, that won't do in this case, I need to change how the destination pixel is calculated based somewhat arbitrarily on how the position in the source changes.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Not sure if this will help or just add confusion. The following is from some finite element modeling in cartesian coordiantes. It applies to any geometric view however. Think of a stage with props and cameras on it. As you move the props or the camera dolly around you change the view the camera has of the props. To calculate the view the camera sees, you need the inverse direction cosines of the cosines that position the camera on the stage. To do so: you need to find a point on two of the inverted axis, which just happen to be definable by the cosines that define that axis's direction.
void CFemEditView::invertdc()
{
// CALCULATE A POINT ON THE INVERTED Z-AXIS.
dciz.x=dcx.z;
dciz.y=dcy.z;
dciz.z=dcz.z;
// CALCULATE A POINT IN THE INVERTED X-Z PLANE.
dcix.x=dcx.x;
dcix.y=dcy.x;
dcix.z=dcz.x;
// FIND NEW Y AXIS COSINES.
dciy=cross(dciz,dcix);
}
Beyond this it is far to late on a Saturday night for me to think clearly. Good luck.
"Simplicity is more complicated than you think. But it’s well worth it” (Ron Jeffries)
|
|
|
|
|
This may help: http://www.euclideanspace.com/maths/geometry/coordinatesystems/polar/[^]
I deal with 3D image projections, so you will have to forgive me if I walk through this step by step (it is as much for me as you). I promise I am definately not being condescending by stepping through it.
atan gets the angle of a rise over run angle (y/x), atan2 simply separates the y,x values in order to guarentee you a correct quandrant result since -y/-x is equivalent to y/x atan must be verified for quandrant based on the incoming values. atan2 does that for you.
theta= atan2(z,x) is the angle from z/x where normally y would be in the place of z.
This means that z=r sin(theta) and x=r cos(theta)
now reversing phi to y, you already know x,z so you can easily get the known distance to x,z which is what the sqrt(x*x+z*z) is getting you. so y is the only unknown
well, y is in the x position of the atan result so you don't even have to worry about the distance portion.
y=r cos(phi) though you might want to verify that dist(x,z)=r sin(phi) just as a double check.
(I learned a long time ago when you deal with 3D surface projections, double checking your work by finding the redundant parameters is a good thing -- just remove them if you need the speed after doing your initial tests)
[edit: hopefully that is all correct, I didn't check it, just walked through it from your code]
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
-- modified at 21:04 Saturday 14th January, 2006
|
|
|
|
|
Thanks - I'll try this and see how I go. I really, really appeciate it.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
hi,
any body has a tic tac toe source in vc (3D mode)
please guide me ,peyman13618@yahoo.com
thanks
-- modified at 16:24 Saturday 14th January, 2006
|
|
|
|
|
You're thinking of rentacoder.com
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
A long time ago now I wrote some code to access the individual frames/bitmaps that make up a video file. I used the Video For Windows API and this code works great on WinXP. However I would like to rewrite it, as I understand it Microsoft aren’t pusing VFW anymore. Can anyone tell me which technology I should focus on? It is important that it doesn’t require any redistributables and will run on out of the box XP.
Anyone any thoughts? Now of any resources?
|
|
|
|
|
DirectShow is what you want.
MS has a free SDK with a bunch of sample programs. i think the frame extraction one is called "SampleGrabber".
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Hi..
I m working on image processing...i m beginner of VC++ 6.0..i dont know how to load and display image meanz if i open any image through file dialoug it will display in non client area of window in SDI..
|
|
|
|
|
try this ,you will just have to pass the device context to the class,
http://www.codeproject.com/bitmap/cpicture.asp
Z.A
|
|
|
|
|
i m making Paint..i need memory device context
i did it but it doesnt work
did like daT
static int i=0;
if(i==0)
{
memDC.CreateCompatibleDC(pDC);
i++;
}
pDC->BitBlt(20,10,436,364,&memDC,0,0,SRCCOPY);
if i draw line i call invalidate it repaints so wht i draw in my device context i also draw in mem dc
but it doesnt work???
|
|
|
|
|
you need to select the bitmap into your mem DC by SelectObject(...) function.
A nice tool for optimizing your Microsoft html-help contents.
Includeh10
|
|
|
|
|
i tried but it gives assertion failure
|
|
|
|
|
there are million of samples in VC disk.
try to search the function you used inside these samples.
VC samples are first place to go for learning something new.
when you test your functions (calling process), be careful to find which function doesn't work.
A nice tool for optimizing your Microsoft html-help contents.
Includeh10
|
|
|
|
|
|
I'm doing some subclassing to allow only digits and one only of three allowable alpha characters at the end of the edit string. I'm overriding OnChar and find a need to modify the existing string before passing the allowable characters on. However, when I pass any character other than the character trapped by MyCEdit::OnChar to CEdit::OnChar it still results in passing the trapped character.
I assume this is the way the system behaves but I don't understand why. Could someone enlighten me? The way I'm getting the job accomplished feels rather kudgy to me and I'd rather avoid it if I can.
Thanks,
Lilith
|
|
|
|
|
try to override WM_KEYDOWN (OnKeyDown?) also.
if you control both OnChar and OnKeyDown, it should work.
A nice tool for optimizing your Microsoft html-help contents.
Includeh10
|
|
|
|
|