Sunday, August 20, 2017

Digest for comp.lang.c++@googlegroups.com - 21 updates in 4 topics

David Melik <dchmelik@gmail.com>: Aug 19 09:57PM -0700

I'm interested learning how quaternions simplify three-dimensional (3D)
graphics programming, such as for a wireframe cube in C or C-style C++
(which I've programmed before, and is on my homepage for GCC C++ w/SDL,
maybe modifiable to C, and has a simple BSD-style license,) doing all
the details, i.e., not using libraries (except, perhaps put_pixel() and
line(), not even some matrix library, let alone graphics ones doing it
all for you.)
 
I.e., the only thing I'd want to use from C++ for this (since I'm trying
to learn more C and linear algebra) is in the case in C++ you can set
your matrix's values all at once, rather than I recall, in C, I had to
do one element at a time. So, I want to be able to comment out that
one-line assignment, and write C-style multiple lines, if I want to
save as a .C instead of .CC.
 
I combined the three standard 3x3 3D rotation matrices into one in which
I can input angles I want, then multiplied it by my 3x8 matrix of the
cube vertices (actually one by one, with a for-loop,) and after doing
perspective and displaying the cube, iterated through time (t) to move
the cube. But, I recall from a university math club lecture,
quaternions already have (x,y,z) defined for all t with respect to
whatever 3D rotation angles you use.
 
So, I'd like to know, how can quaternions simplify this process? I
recall they're something like a scalar on some (x,y,z) but forgot how
that would seem to simplify any multiplication or iteration.
 
Rather than in one suggestion I was given, saying break this down into
more objects such as vertex vectors and a rotation matrix with twice as
many angles than I need, I'd still prefer to use an object matrix
(defining my cube's vertices,) and rotation matrices (and saw at least a
couple different types, maybe still with several of each that could be
multiplied,) but if there's a way to do either fewer matrix
multiplications, or not so much iteration, that would be a benefit... is
that what one could do with quaternions? Or, is there some simpler way,
that will still reduce the amount of code you need to write, and amount
of variables/objects you need to use, as well as the calculations?
 
David (Darwin in USA code/math/graphics/art/music Demoscene)
http://www.cwu.edu/~melikd/
"Öö Tiib" <ootiib@hot.ee>: Aug 20 03:48AM -0700

On Sunday, 20 August 2017 07:58:21 UTC+3, David Melik wrote:
> the details, i.e., not using libraries (except, perhaps put_pixel() and
> line(), not even some matrix library, let alone graphics ones doing it
> all for you.)
 
So you are writing new linear algebra library in C for rotating wireframe
cubes? What is the alleged benefit?
 
> do one element at a time. So, I want to be able to comment out that
> one-line assignment, and write C-style multiple lines, if I want to
> save as a .C instead of .CC.
 
Are you sure that what you describe is not available in C? Sounds like
something that is doable with compound literals. Can you provide example?
 
> the cube. But, I recall from a university math club lecture,
> quaternions already have (x,y,z) defined for all t with respect to
> whatever 3D rotation angles you use.
 
It likely does not matter if to use matrices or quaternions to represent
rotation for one wireframe cube.
bartc <bc@freeuk.com>: Aug 20 12:21PM +0100

On 20/08/2017 05:57, David Melik wrote:
> I'm interested learning how quaternions simplify three-dimensional (3D)
> graphics programming, such as for a wireframe cube in C or C-style C++
> (which I've programmed before, and is on my homepage for GCC C++ w/SDL,
 
(http://www.cwu.edu/~melikd/math/demosrc/demo.cpp)
 
> the details, i.e., not using libraries (except, perhaps put_pixel() and
> line(), not even some matrix library, let alone graphics ones doing it
> all for you.)
 
One comment:
 
//define polyhedra
int cube_100[3][8]={{-50, -50, 50, 50, -50, -50, 50, 50},
{-50, 50, 50, -50, -50, 50, 50, -50},
{-50, -50, -50, -50, 50, 50, 50, 50}};
int cube_a[3][8]={{-50, -50, 50, 50, -50, -50, 50, 50},
{-50, 50, 50, -50, -50, 50, 50, -50},
{-50, -50, -50, -50, 50, 50, 50, 50}};
 
This looks rather peculiar; is each (x,y,z) point represented as a
vertical column here?
 
It is more normal to store x, y and z together, for example (also using
floats rather than ints, but I don't know if the above is a requirement
of SDL):
 
typedef struct { float x,y,z;} Point;
 
Point cube[8] = {
{-50, -50, -50},
{-50, 50, -50},
etc
 
Then, if vertices of a cube are indexed 0 to 7, the Z component of
vertex 4 would be:
 
cube[4].z
 
(Your code which uses indices for both, and in a backwards order, gets
confusing later on.)
 
> So, I'd like to know, how can quaternions simplify this process? I
 
(Can't help there; don't know quaternions.)
 
> couple different types, maybe still with several of each that could be
> multiplied,) but if there's a way to do either fewer matrix
> multiplications,
 
How many were you thinking of? A cube has 8 corners, so would need 8
transformations (applying a transformation matrix to each point to yield
a new point).
 
You only need to multiply matrices to combine transformations. That's
done once then you can apply the same result to any number of points
(ie. vertices).
 
Not sure about all the things your code does; one part seems to rotate a
2D cube 360 degrees, 6 degrees at a time so 60 (or 61) rotations are
applied.
 
To do similar with a 3D cube, which has 8 corners, you might try this
for each iteration:
 
Set up a new rotation matrix for this new angle
Copy the 8 vertices into a new cube
Apply the matrix on the new cube
Draw it (presumably using 12 edges between 12 pairs of those 8 vertices)
 
This is compared with, for example, taking an edge at a time, and
transforming the two endpoints, as you will do 24 transformations rather
than 8.
 
A faster way of rotating such a cube is to set up a rotation matrix for
6 degrees. Take a copy of the original cube. Then:
 
Draw the cube
Apply the 6 degree rotation to each of the 8 vertices
Repeat 60 times
 
So this avoids copying vertices, or re-calculating the rotation matrix.
But incremental errors can build up.
 
--
bartc
fir <profesor.fir@gmail.com>: Aug 20 04:26AM -0700

W dniu niedziela, 20 sierpnia 2017 12:48:25 UTC+2 użytkownik Öö Tiib napisał:
> > whatever 3D rotation angles you use.
 
> It likely does not matter if to use matrices or quaternions to represent
> rotation for one wireframe cube.
 
it does not to be wireframe it may be filled ;c
 
i wrote something like this couple years ago
 
heres youtube video
 
https://www.youtube.com/watch?v=ha_epYAJoiI
 
here is win32 executable
 
minddetonator.htw.pl/some.zip
 
(no malware, at live it looks much better so i encourage to run and see)
 
it works as you see in 50Hz at 95k tris 3d model in lowres though
 
every pixel is counted on cpu by pure my code
 
purpose is i was qute happy with that
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 20 01:30PM +0200

On 8/20/2017 12:48 PM, Öö Tiib wrote:
>> whatever 3D rotation angles you use.
 
> It likely does not matter if to use matrices or quaternions to represent
> rotation for one wireframe cube.
 
I know next to nothing about quaternions (except they're not the end of
the road in the list of kinds of numbers), but I think it's very
relevant that the rotation is about a 3D angle.
 
A (3x3) matrix can describe a 2D rotation plus an affine transformation.
 
I guess using matrices could therefore be awkward. But disclaimer: I
know next to nothing about this stuff. Going by gut feeling. :)
 
 
Cheers!,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Aug 20 01:10PM -0700

On Sunday, 20 August 2017 14:30:26 UTC+3, Alf P. Steinbach wrote:
 
> A (3x3) matrix can describe a 2D rotation plus an affine transformation.
 
> I guess using matrices could therefore be awkward. But disclaimer: I
> know next to nothing about this stuff. Going by gut feeling. :)
 
For transformations in 3D space we can use transformation
matrices or quaternions. Matrices support more transformation
operations (most of what are less frequently needed) but also take
more memory, composing two matrices takes more operations and
transformations by matrices are more expensive to interpolate.
 
So if one wants to use transformations like non-uniform scaling,
skewing or projection transformations then those can be done
with matrices but not quaternions. If such transformations are
not needed then for rotations and uniform scaling the quaternions
are likely cheaper and more convenient to use.

The popular game engines like Unity3D and Unreal Engine
accept quaternions, transformation matrices and Euler angles. :)
Joe Pfeiffer <pfeiffer@cs.nmsu.edu>: Aug 20 05:16PM -0600

> the calculations?
 
> David (Darwin in USA code/math/graphics/art/music Demoscene)
> http://www.cwu.edu/~melikd/
 
If you're looking for what I think you are, search on affine
transformation matrices. The wikipedia page
https://en.wikipedia.org/wiki/Transformation_matrix appears at first
glance to give a good introduction; it's also a chapter in just about
any computer graphics textbook.
Vir Campestris <vir.campestris@invalid.invalid>: Aug 20 09:25PM +0100

On 19/08/2017 13:12, fir wrote:
> W dniu sobota, 19 sierpnia 2017 14:02:57 UTC+2 użytkownik Alf P. Steinbach napisał:
<snip>
>> a Windows loader feature. Things can end up pretty much anywhere, in
>> order to foil hackers' attempts.
 
> i dlls - but i talk on exes here (need to know that as i write my own simple basic x86 assembler that wuld flush to disk only exes right now)
 
No, it applies to EXEs too.
 
You can link DLLs to fixed addresses; but that reduces their usefulness
as the address may not be available in all programs.
 
AIUI you don't _have_ to write the relocation records, but your program
will be less secure. Randomised load addresses defend against some kinds
of malware, especially buffer overflow attacks.
 
Andy
fir <profesor.fir@gmail.com>: Aug 20 01:47PM -0700

W dniu niedziela, 20 sierpnia 2017 22:25:26 UTC+2 użytkownik Vir Campestris napisał:
> will be less secure. Randomised load addresses defend against some kinds
> of malware, especially buffer overflow attacks.
 
> Andy
 
well i think if you would like to get
exe able to be realocated you would need to update a lot of internal references (all references reaching to .code .data .bss .consts and even .imports meybe even yet some)
 
im not sure hovewer if in present assembly such adressing is non-relitive it is like real 004X_XXXX
pointers or some amount is by reliative offsets pointing back or forward?
 
with all that relative adressing you could move all axe up and down virtual
ram sopace and that would work with no
any fixups (it is not needed however,
im not quite convinced that this movin
is really needed)
 
relative adressin btw would be usefull mostly probably when one would need to optimise code for size, in that case relative adressing would reduce code size but probably in todays x86 reality it is not practical
 
 
could someone remember me: as far as i remember calls are non-relative (fixed adress).. but what with loops, when code makes loop is this conditional jump rather to fixed adress or relative -N byted back? same with ifs, do they -+M bytes back/forward or are they rather to fixed code adress?
fir <profesor.fir@gmail.com>: Aug 20 02:14PM -0700

note some curiosity - as far as i know
from that above (i mean i know that
pe file is loaded and mapped under
0x0040_0000 in memory (where exe header
is alos mapped afaik
 
by something like
 
int * p = 0x00400077; //check real adres in PE docs
printf("stack size %d", *p);
 
you could acces to quite usable though hacky information on your program without usage of no api at all
 
im not sure as to this but probably, for example you could be able to dump
binary of teh code by starting from
0x00401000 and so on
 
ps. without checking the pe heder and found at which offset what info is i quickly tested if i will find 'MZ' at
0x00400000
 
int main()
{
 
char* a = (char*) 0x00400000;
printf("%c%c", *a, *(a+1));
 
retirn 0;
}
output: MZ , there is
Bo Persson <bop@gmb.dk>: Aug 21 12:33AM +0200

On 2017-08-20 23:14, fir wrote:
 
> int * p = 0x00400077; //check real adres in PE docs
> printf("stack size %d", *p);
 
> you could acces to quite usable though hacky information on your program without usage of no api at all
 
But why?
 
You can get stack info by calling GetCurrentThreadStackLimits and see
exactly where the stack is allocated.
 
 
 
Bo Persson
fir <profesor.fir@gmail.com>: Aug 20 04:03PM -0700

W dniu poniedziałek, 21 sierpnia 2017 00:33:41 UTC+2 użytkownik Bo Persson napisał:
 
> You can get stack info by calling GetCurrentThreadStackLimits and see
> exactly where the stack is allocated.
 
> Bo Persson
 
to undestand internals - whot is very good..
those people denying this are - like i probably could say - like those all homofobs and racists who deny other kind of truth (that being racist or homofobe has big elements of being nonsense).. thus should i call em 'internalfobs' or what?
fir <profesor.fir@gmail.com>: Aug 20 04:11PM -0700

W dniu poniedziałek, 21 sierpnia 2017 01:04:15 UTC+2 użytkownik fir napisał:
 
> > Bo Persson
 
> to undestand internals - whot is very good..
> those people denying this are - like i probably could say - like those all homofobs and racists who deny other kind of truth (that being racist or homofobe has big elements of being nonsense).. thus should i call em 'internalfobs' or what?
 
to quote Kurt Cobain ->
 
'living with internalfobs, oh no'
fir <profesor.fir@gmail.com>: Aug 20 02:38PM -0700

if you will run such code (on windows)
 
int main()
{
int sum = 0;
 
for(unsigned i=0x00400000; i<0x00401000; i++)
{
char* x = (char*) i;
sum+= *x;
}
 
printf("sum = %d", sum);
 
return 0;
}
then depending on readed ram area it will work or crash ("there is a trouble with that aplication, aplication will be closed")
 
i think you get crash when you will read a ram area where ram is just not pinned
(im not sure if on windows pages are just guarded from read, i understand write, execute, but read? is this the case?)
 
that was one question second is
 
how to catch and recover from this crash (i just want to write a tiny ram scanner who will try read all 32 bit ram area and will give me info back which areas i can read and which i cant)
 
(same possibly with write though im not sure if i will try read any byte vale then write say 0x55 to any byte then write back oryginal value it will calmly stand such crash test ;c will it?
fir <profesor.fir@gmail.com>: Aug 20 01:48AM -0700

if ya got some memory bandwidth power on given physical core (say it is 7 GB/s) when you got 2 physical cores you got it on each core separately (i mean you got 2 x 7GB/s)
if you have 6 physical you will get 6 x 7 GB/s - this is as far as i know, but as far as i know it is true - and it is very important
 
 
my question is - is this the same with logical cores? i mean do having 2 logical cores in one physical doubles this 7 GB/s memory bandwidth? (i expect probably no and it is shared on two logical but im not sure) if someone have such info tell me know
Marcel Mueller <news.5.maazl@spamgourmet.org>: Aug 20 11:36AM +0200

On 20.08.17 10.48, fir wrote:
> if you have 6 physical you will get 6 x 7 GB/s - this is as far as i know, but as far as i know it is true - and it is very important
 
> my question is - is this the same with logical cores? i mean do having 2 logical cores in one physical doubles this 7 GB/s memory bandwidth?
> (i expect probably no and it is shared on two logical but im not sure) if someone have such info tell me know
 
There is no such rule at all, not even for physical cores. And it has
nothing to do with C++ programming at all.
 
So you should ask in a group matching your particular hardware.
 
 
Marcel
fir <profesor.fir@gmail.com>: Aug 20 02:58AM -0700

W dniu niedziela, 20 sierpnia 2017 11:36:24 UTC+2 użytkownik Marcel Mueller napisał:
 
> There is no such rule at all, not even for physical cores. And it has
> nothing to do with C++ programming at all.
 
> So you should ask in a group matching your particular hardware.
 
there is such rule an it has very much to do with c++ programming
 
(it is silly thinking that knowledge how MB is populated on hysical/logical cores has nothing to do with c++ programming, its basicaly fundamental)
Paavo Helde <myfirstname@osa.pri.ee>: Aug 20 06:38PM +0300

On 20.08.2017 11:48, fir wrote:
> if ya got some memory bandwidth power on given physical core (say it is 7 GB/s) when you got 2 physical cores you got it on each core separately (i mean you got 2 x 7GB/s)
> if you have 6 physical you will get 6 x 7 GB/s - this is as far as i know, but as far as i know it is true - and it is very important
 
It depends on the memory access pattern. If the program accesses
limited amounts of memory, fitting in the L1 cache, then indeed each
physical core can operate fully parallel to others (modulo false
sharing), as each physical core has its own L1 cache.
 
However, if the program is memory-bound and accesses large amounts of
memory not fitting in the L3 cache, then physical cores begin to
interfere with each other because the L3 cache is typically shared
between physical cores. If the L3 cache gets filled up the cores start
to fight over it and the program performance does not scale up with the
number of used threads any more.
 
 
> my question is - is this the same with logical cores? i mean do having 2 logical cores in one physical doubles this 7 GB/s memory bandwidth? (i expect probably no and it is shared on two logical but im not sure) if someone have such info tell me know
 
I think the L1 cache is typically shared by the logical cores, so the
memory bandwidth does not really double for logical cpus.
 
hth
Paavo
fir <profesor.fir@gmail.com>: Aug 20 10:19AM -0700

W dniu niedziela, 20 sierpnia 2017 17:38:59 UTC+2 użytkownik Paavo Helde napisał:
> memory bandwidth does not really double for logical cpus.
 
> hth
> Paavo
 
it ise easy to measure pgysically say do a big memset in 1 core, in 2 cores (half size by core A half by core B) and two logical cores - by 2 physical cores it will be just twice faster, do it in logical and you will see (probably there is like you said and on ligical it will not be twice faster and it will be exactly as slow as on one)
 
(i mostly belive in such kind of tests personally, but working only on 2 physical cores machine.. theoretically im not fully sure that machina with 6 physical cores will have 'memstets' 6 times faster but i think though probably it will)
Vir Campestris <vir.campestris@invalid.invalid>: Aug 20 09:27PM +0100

On 20/08/2017 10:58, fir wrote:
 
>> So you should ask in a group matching your particular hardware.
 
> there is such rule an it has very much to do with c++ programming
 
> (it is silly thinking that knowledge how MB is populated on hysical/logical cores has nothing to do with c++ programming, its basicaly fundamental)
 
It's a general programming question, and this forum is for specific C++
problems.
 
The answer depends entirely on the hardware. Read about NUMA.
 
Andy
fir <profesor.fir@gmail.com>: Aug 20 01:53PM -0700

W dniu niedziela, 20 sierpnia 2017 22:27:18 UTC+2 użytkownik Vir Campestris napisał:
> problems.
 
> The answer depends entirely on the hardware. Read about NUMA.
 
> Andy
 
it is impossible to talk about specific things without general fundaments imo.. note that also this group is not only c++ language but also about a "programming in c++" (otherwise there should be 2 groups and i dont see the 2), and this
topic fits to programming in c++
(though it also fits to programming in pascal or jave, in c++ more people tent to know bandwidth details)
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: