Hi, On Tue, 17 Sep 2019, James Richters wrote:
> What I'm trying to do is much simpler than rendering a 3D object.. All > I'm trying to do is display a 3D line drawing or wireframe on the > screen. I don't need it to dynamically rotate or anything, and it > doesn't need to show any surfaces, textures, lighting, reflections, or > shadows, just give a representation of the XYZ points and lines > connecting 2 pair of XYZ coordinates on the screen. The purpose of this > is to show a 3D representation of a CNC tool path including the Z > movements. Well, it all boils down to the projection you want to make while you transform from your coordinates from 3D to 2D. For the most simple "isometric" projection with no perspective, you just throw away one of the XYZ coordinates, and use the other two - this will result in a simple "camera" which views at your object from either the front (XY), side (YZ) or from the top (XZ). (Actually, this also depends on wether in your coordinate system Y or Z represents depth, 3D editors/engines don't even agree on this one, the code below assumes "Z" is depth.) For a simple "perspective" projection, you can use a simplistic formula, something like: { untested pseudocode } procedure perspective_vertex(const v: T3DVertex; ZCenter: single; out X, Y: single); var rdist1: single; begin zdist1:=1.0 / (v.z - zcenter); X:=(v.x * zcenter) * zdist1; Y:=(v.y * zcenter) * zdist1; end; This will put some sort of "perspective" on your 3D vertex, depending on its Z coordinate. The ZCenter should be larger than the maximum dimension of your object facing the "camera". Note that this formula is massively simplified, but serves as the most simple perspective projection. After this, you can use x/y coordinates to feed the wireframe drawer using whatever drawing unit you see fit. You might need to do inc(x,width/2); and inc(y,height/2); and/or multiply your values with a certain scale-factor, depending on the size of your object, and how its coordinates map to your 2D resolution. All of the above methods assume that your object's 3D center resides at the origo (center of the coordinate system). Anything more complicated would require some proper matrices to be set up and calculate a full series of model, view, and projection matrices, as others have already mentioned, or would require pre-processing your 3D coordinates in a certain way, so this simplistic formula can work. Hope this helps, -- Charlie (Ps: actually, the FPC Packages contain two similar examples of a rotating 3D cube, for PalmOS and Atari, both written by me, to showcase the m68k code generator and the units for these retro/niche OSes. They're at (SVN trunk): - packages/tosunits/examples/gemcube.pas - packages/palmunits/examples/palmcube.pas Showcased here (with video): https://twitter.com/chainq/status/945010617672523777 https://twitter.com/chainq/status/948865605209387010 These show this most simplistic form of 3D calculation, and they also use fixed point math, as that fit the only a few mhz fast 68000 CPUs in these machines. But the basic algo and formula is the same with float and on faster platforms. Now I'm quite tempted to make a ptc-graph version. :) ) _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal