|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Hey,
I know this will probably sound like a dumb question to all of the
programmers in here, but I'm completely new to C++ and I'm pretty
confused. I found a vector class online but I don't know quite how to
use it. Every time I try, I get more errors than there are lines of
text. How would I define a simple 3d vector like I would in POV so I
can do basic operations on it? Thanks in advance.
- Ricky
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Reusser wrote:
> Hey,
> I know this will probably sound like a dumb question to all of the
> programmers in here, but I'm completely new to C++ and I'm pretty
> confused. I found a vector class online but I don't know quite how to
> use it. Every time I try, I get more errors than there are lines of
> text. How would I define a simple 3d vector like I would in POV so I
> can do basic operations on it? Thanks in advance.
The vector class (or rather the vector *template*) that comes with the
standard library is useful for holding a dynamical number of entries. For a
simple 3d vector use an array as in C - or if you want to do it
object-orientated write a Vector class around it.
As example the class I have written for my raytracer for that purpose:
http://www.povworld.org/raytracer/api/raytracer___vector_h.html
--
objects.povworld.org - The POV-Ray Objects Collection
book.povworld.org - The POV-Ray Book Project
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Reusser <reu### [at] chorusnet> wrote:
> I know this will probably sound like a dumb question to all of the
> programmers in here, but I'm completely new to C++ and I'm pretty
> confused. I found a vector class online but I don't know quite how to
> use it. Every time I try, I get more errors than there are lines of
> text. How would I define a simple 3d vector like I would in POV so I
> can do basic operations on it? Thanks in advance.
There are more efficient way of using 3-component vectors in C++ than
using the standard vector class, but since you are a complete beginner,
it might be easier for you to use it for now.
If you want to make a vector containing three doubles, you simply do this:
std::vector<double> myVector(3);
The three doubles are automatically initialized to 0 (the reason behind
this is very complicated for a newbie so I will simply skip explaining why).
Now you can access the three components with the [] operator. The index
values you can use are 0, 1 and 2. Like this:
myVector[0] = 5.2; // sets the first component to 5.2
myVector[2] = myVector[0]; // sets the third component the same as the first
(Don't use index values greater than 2 or else your program will misbehave
(if you are lucky you will only get a segmentation fault error).)
Note that if you give such vector as a parameter to a function, the function
should take it as a const reference for efficiency (in which case a single
pointer is copied instead of the whole instance plus the allocated memory).
For example:
void myFunction(const std::vector<double>& parameter)
{
...
}
You can then call this function simply by giving your vector as parameter:
myFunction(myVector);
--
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
A few comments...
1) Why do you make the array public?
2) Why do you put "public" in so many times? Once will do...
3) Why do you use a for-loop in the constructor? Is this
a[0] = a[1] = a[2] = w;
not possible, and perhaps clearer?
4) Instead of "equals", "add", and "sub", wouldn't it make more sense to
overload ==, +, and -?
--
Anthony Bennett
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Just to confirm something, Warp. This
std::vector<double> myVector(3);
is instantiating a double vector, with an initial size of 3 elements, yes?
Also, do you prefer to always add "std::", or do you think it's ok to toss
in the respective "using"? (Say, as long as this file is not to be included
in another.) And on that topic, is there, or wouldn't it be neat if there
were, something like "stop using", so you could do things like this?
using namespace std;
/* do your thing */
stop using namespace std;
:)
--
Anthony Bennett
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Tony[B] wrote:
> A few comments...
>
> 1) Why do you make the array public?
The vector is a really basic class which needs to be manipulated
"low-level" by many other classes. To allow this I made the array public.
If I made it private I would have to add a public method to read and write
the elements of the vector anyways. But access could be made a bit more
elegant using the '[]' operator.
>
> 2) Why do you put "public" in so many times? Once will do...
I think it makes it more clear. Each 'public' comes with a comment to its
right and kinda defines a new section. This way the sections' comments can
easily be distinguished from other comments.
>
> 3) Why do you use a for-loop in the constructor? Is this
>
> a[0] = a[1] = a[2] = w;
>
> not possible, and perhaps clearer?
I think multiple assinments are rather counter-intuitive. But this was not
the reasons I chose for-loops. The thing is that an explizit loop tells the
compiler about the repeating structure while the other does not. The
compiler can easily unroll the loop when it thinks that this will help
performance or whatever. Furthermore the Intel compiler recoginzes it this
way and can 'vectorize' it, that is use SIMD instructions.
> 4) Instead of "equals", "add", and "sub", wouldn't it make more sense to
> overload ==, +, and -?
I am not really a friend of overloading of + and -. They hide what is
really going on when using them. Sometimes there is also an additional
temporary variable created.
I think
a += b + c;
will have to be tranlated by the compiler to
tmp = c;
tmp += b;
a += tmp;
as it cannot assume that (a+b)+c is the same as a+(b+c). On the other hand
a.add(b); a.add(c);
does not need a temporary variable.
Thanks for your comments!
- Micha
--
objects.povworld.org - The POV-Ray Objects Collection
book.povworld.org - The POV-Ray Book Project
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
In article <3dfe1e0d@news.povray.org>, Micha Riser <mri### [at] gmxnet>
wrote:
> They hide what is really going on when using them.
That is a good thing. It is no different from using a function or
abstract object, it hides information that is irrelevant.
> Sometimes there is also an additional temporary variable created.
You are micro-optimizing...though I am sometimes guilty of that too.
A good compiler can often figure out the most efficient way to compile
the code.
> will have to be tranlated by the compiler to
> tmp = c;
> tmp += b;
> a += tmp;
> as it cannot assume that (a+b)+c is the same as a+(b+c). On the other hand
> a.add(b); a.add(c);
> does not need a temporary variable.
a += b; a += c;
or:
(a += b) += c;
No temporaries.
The version using operator overloading is much easier to read, and the
compiler could probably optimize away any significant differences.
--
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Tony[B] <ben### [at] catholicorg> wrote:
> Just to confirm something, Warp. This
> std::vector<double> myVector(3);
> is instantiating a double vector, with an initial size of 3 elements, yes?
Yes.
You can also give the initial value of the three elements as a second
parameter, but as the default constructor for 'double' initializes them
to 0, it's probably not necessary.
> Also, do you prefer to always add "std::", or do you think it's ok to toss
> in the respective "using"? (Say, as long as this file is not to be included
> in another.)
It depends.
If the 'std::vector<double>' definition is used just a couple of times
in the file, then it's not too much trouble to write the 'std::' prefix.
If it's used tens of times, then I might write "using std::vector;" to
pop it out of the namespace.
> And on that topic, is there, or wouldn't it be neat if there
> were, something like "stop using", so you could do things like this?
> using namespace std;
> /* do your thing */
> stop using namespace std;
Well, this is actually possible indirectly.
If you write that inside a function (or any {}-block), its scope will end
at the end of the function (or {}-block) as well. That is:
void f()
{
using namespace std:
...(some code here)...
// using namespace std ends here
}
These are the programming guidelines about 'using' which I have learned:
1. As a general rule, don't use 'using'.
2. If it would be a lot of work to write all the 'std::' prefixes, put
a "using std::whatever;" inside the function where you are using the
specified type.
3. If there would be lots of "using std::whatever;" lines at the beginning
of the function (eg. more than five) then you might consider writing
"using namespace std;" instead in the function.
4. If there are lots of functions in the .cpp file and most of them would
have the same "using std::whatever;" lines, then you might want to
write them just once at the beginning of the file.
5. And again, if there would be lots of those lines (but in this case there
would be a lot more, eg. 10 or more), then you might consider writing
"using namespace std;" at the beginning of the file. However, if it's
not too much trouble, try avoiding this.
6. And the most important rule of all: Never ever ever use a 'using'
statement in a header file. Never. Period.
Note to rule 6: You might think that if you are implementing an inline
function in a header file, it may be ok to write 'using' inside that function.
However, this is still not the case: If the implementation of that function
is really so large that it contains lots and lots of 'std::' prefixes, then
it's probably too long to be a good inline function in the first place.
--
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Micha Riser <mri### [at] gmxnet> wrote:
>> 1) Why do you make the array public?
> The vector is a really basic class which needs to be manipulated
> "low-level" by many other classes. To allow this I made the array public.
> If I made it private I would have to add a public method to read and write
> the elements of the vector anyways. But access could be made a bit more
> elegant using the '[]' operator.
Sticking to modularity principles, even though it might feel sometimes
like useless, is usually a good thing.
By making the implementation of your vector public you are fixing this
implementation. This means that you will not be able to change the
implementation to something better later.
Granted, in this specific case it's improbable that the implementation
will ever change, but leaving the possibility open never hurts.
Just look at the std::vector class. It has mostly abstracted its internal
implementation, yet you still can use it largely as if it was a C array.
You can index it using the [] operator. Even though it's not the language's
internal [] operator but it's overloaded, with a current compiler it's
probably not any slower.
(The reason why I used the word "mostly" above is too long to explain
here...)
There are some programming guidelines which suggest that if you are
going to make a conglomeration of variables instead of an abstract type,
you should use 'struct' instead of 'class' for clarity. This is a kind
of "documentation" style of the source code.
> I am not really a friend of overloading of + and -. They hide what is
> really going on when using them.
There's no difference between "operator+(a,b)" and "function(a,b)".
Moreover, if you want to only make possible to add and assign at the
same time, use operator+=().
--
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Warp <war### [at] tagpovrayorg> wrote:
> If the 'std::vector<double>' definition is used just a couple of times
> in the file, then it's not too much trouble to write the 'std::' prefix.
> If it's used tens of times, then I might write "using std::vector;" to
> pop it out of the namespace.
By the way, there's another alternative to this. If 'std::vector<double>'
is used a lot, then you could write this at the beginning of the cpp file:
typedef std::vector<double> DVec;
Then you can use 'DVec' instead.
--
#macro N(D)#if(D>99)cylinder{M()#local D=div(D,104);M().5,2pigment{rgb M()}}
N(D)#end#end#macro M()<mod(D,13)-6mod(div(D,13)8)-3,10>#end blob{
N(11117333955)N(4254934330)N(3900569407)N(7382340)N(3358)N(970)}// - Warp -
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|