Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #815 > unrolled thread

ping luser- -droog: SVG or PS project for you?

Started bytlvp <mPiOsUcB.EtLlLvEp@att.net>
First post2012-07-17 04:48 -0400
Last post2012-09-24 09:30 -0500
Articles 16 on this page of 36 — 5 participants

Back to article view | Back to comp.lang.postscript


Contents

  ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-07-17 04:48 -0400
    Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-07-17 08:16 -0700
      Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-07-17 19:25 -0400
    Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-08-17 23:40 -0700
      Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-08-18 00:14 -0700
        Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-08-18 22:44 -0400
          Moire Madness! Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-08-23 13:00 -0700
            Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-08-24 01:45 -0400
              Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-08-24 01:49 -0400
              Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-08-23 23:11 -0700
                Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? luser- -droog <mijoryx@yahoo.com> - 2012-08-23 23:58 -0700
                  Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-08-25 02:17 -0400
                    Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? Luser droog <mijoryx@yahoo.com> - 2012-08-29 18:25 -0500
                    Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? Luser droog <mijoryx@yahoo.com> - 2012-08-29 21:32 -0500
                      Re: Moire Madness! Re: ping luser- -droog: SVG or PS project for you? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-08-30 05:26 -0400
                        Hula-Hoop Hullaballoo! Re: ping luser- -droog: SVG or PS project for you? Luser droog <mijoryx@yahoo.com> - 2012-09-02 16:04 -0500
                          Re: Hula-Hoop Hullaballoo! Re: ping luser- -droog: SVG or PS project for you? Luser droog <mijoryx@yahoo.com> - 2012-09-03 12:29 -0500
                            Re: Hula-Hoop Hullaballoo! Re: ping luser- -droog: SVG or PS project for you? Luser droog <mijoryx@yahoo.com> - 2012-09-04 12:04 -0500
                              Re: Hula-Hoop Hullaballoo! Re: ping luser- -droog: SVG or PS project for you? "M. Joshua Ryan" <mijoryx@yahoo.com> - 2012-09-04 12:49 -0500
                                A shaded cylinder luser- -droog <mijoryx@yahoo.com> - 2012-09-04 18:11 -0700
                                  Re: A shaded cylinder luser- -droog <mijoryx@yahoo.com> - 2012-09-11 13:03 -0700
                                    Spinning Steinmertz Solid (approx.) luser- -droog <mijoryx@yahoo.com> - 2012-09-11 21:29 -0700
                                      Mulligan (again) luser- -droog <mijoryx@yahoo.com> - 2012-09-13 19:07 -0700
                                        Re: Mulligan (again) tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-09-14 05:05 -0400
                                          Heineken time "luser.droog" <luser.droog@gmail.com> - 2012-09-15 16:50 -0500
                                            Bigger and Badderer "luser.droog" <luser.droog@gmail.com> - 2012-09-16 23:33 -0500
                                              Re: Bigger and Badderer "luser.droog" <luser.droog@gmail.com> - 2012-09-16 23:37 -0500
                                                QapplaH! "luser.droog" <luser.droog@gmail.com> - 2012-09-17 11:34 -0500
                                                  Re: QapplaH! (appendix: updated mat.ps) "luser.droog" <luser.droog@gmail.com> - 2012-09-17 13:05 -0500
                                                    one more cup of coffee for the road. "luser.droog" <luser.droog@gmail.com> - 2012-09-18 02:51 -0500
                                                Re: Bigger and Badderer tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-09-18 21:52 -0400
                                                  Re: Bigger and Badderer "luser.droog" <luser.droog@gmail.com> - 2012-09-18 22:30 -0500
                                                    Re: Bigger and Badderer tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2012-09-19 00:59 -0400
                                                      Re: Bigger and Badderer "luser.droog" <luser.droog@gmail.com> - 2012-09-19 00:48 -0500
                                                        Revolving Camera prototype "luser.droog" <luser.droog@gmail.com> - 2012-09-23 22:30 -0500
                                                          Steinmetz with Revolving Camera "luser.droog" <luser.droog@gmail.com> - 2012-09-24 09:30 -0500

Page 2 of 2 — ← Prev page 1 [2]


#956 — Re: A shaded cylinder

Fromluser- -droog <mijoryx@yahoo.com>
Date2012-09-11 13:03 -0700
SubjectRe: A shaded cylinder
Message-ID<8185ea95-cd36-462d-8a3b-d0109b7a970d@googlegroups.com>
In reply to#929
Here's a small improvement over the previous.
Three cylinders each chopped by the other two.
Color selected by (hue,sat,bright) = 
(model-theta, model-z, that-light-model-I-found)
One unfortunate effect is changing the resolution
really messes up your lighting.

I've got it set-up to grow "out of nowhere"
dramatically by setting the depth of the approximation
by the fibonacci sequence. dep=8 is curiously invisible.
And it starts to take shape around 89.


534(1)02:56 PM:ps 0> cat 3d4.ps
%!
%Steinmertz solid (?)

%(mat.ps) run
%!
%mat.ps
%Matrix and Vector math routines

/.error where { pop /signalerror { .error } def } if

/dot { % u v
    2 copy length exch length ne {
        /dot cvx /undefinedresult signalerror
    } if
    % u v
    0 % u v sum
    0 1 3 index length 1 sub { % u v sum i
        3 index 1 index get exch % u v sum u_i i
        3 index exch get % u v sum u_i v_i
        mul add % u v sum
    } for % u v sum

    3 1 roll pop pop % sum
} bind def

% [ x1 x2 x3 ] [ y1 y2 y3 ]  cross  [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1 ]
/cross { % u v
    dup length 3 ne
    2 index length 3 ne or {
        /cross cvx /undefinedresult signalerror
    } if
    % u v
    exch aload pop 4 3 roll aload pop % x1 x2 x3 y1 y2 y3
    [
        5 index 2 index mul % ... [ x2*y3
        3 index 6 index mul sub % ... [ x2*y3-y2*x3
        5 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1
        8 index 4 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3
        8 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2
        8 index 7 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1
    ]
    7 1 roll 6 { pop } repeat
} bind def

/transpose { STATICDICT begin
    /A exch def
    /M A length def
    /N A 0 get length def
    [
    0 1 N 1 sub { /n exch def
        [
        0 1 M 1 sub { /m exch def
            A m get n get
        } for
        ]
    } for
    ]
end } dup 0 6 dict put def

/matmul { STATICDICT begin
    /B exch def
    B 0 get type /arraytype ne { /B [B] def } if
    /A exch def
    A 0 get type /arraytype ne { /A [A] def } if
    /Q B length def
    /R B 0 get length def
    /P A length def
    Q A 0 get length ne {
        /A A transpose def
        /P A length def
        Q A 0 get length ne {
            A B end /matmul cvx /undefinedresult signalerror
        } if
    } if

    [
        0 1 P 1 sub { /p exch def
        [
    0 1 R 1 sub { /r exch def
            0
            0 1 Q 1 sub { /q exch def
                A p get q get
                B q get r get mul
                add
            } for
        } for
        ]
    } for
    ]

end } dup 0 10 dict put def

%u v {operator}  vop  u(op)v
%apply a binary operator to corresponding elements
%in two vectors producing a third vector as result
/vop { 1 dict begin
    /op exch def
    2 copy length exch length ne {
        /vop cvx end /undefinedresult signalerror
    } if

    [ 3 1 roll % [ u v
    0 1 2 index length 1 sub { % [ ... u v i
        3 copy exch pop get % u v i u_i
        3 copy pop get      % u v i u_i v_i
        op exch pop         % u v u_i(op)v_i
        3 1 roll            % u_i(op)v_i u v
    } for % [ ... u v
    pop pop ]

end } def

%length of a vector
/mag { 0 exch { dup mul add } forall } def


/prep {
    transform
    2 {
        exch
        %floor
        round
        %ceiling
        %2 mul cvi 2 div %round
    } repeat
    itransform
} def

% x y z ang -> x y' z'
/rotx { 3 dict begin
    /theta exch def
    /z exch def
    /y exch def
    y theta cos mul
    z theta sin mul sub
    y theta sin mul
    z theta cos mul add
end } def

% x y z ang -> x' y z'
/roty { 4 dict begin
    /theta exch def
    /z exch def
    /y exch def
    /x exch def
    x theta cos mul
    z theta sin mul add
    y
    x theta sin mul neg
    z theta cos mul add
end } def

% x y z ang -> x' y' z
/rotz { 4 dict begin
    /theta exch def
    /z exch def
    /y exch def
    /x exch def
    x theta cos mul
    y theta sin mul sub
    x theta sin mul
    y theta cos mul add
    z
end } def

% x y z -> x' y' z'
/model {
%ang roty
%ang .25 mul rotx
%alpha rotz
beta roty
gamma rotx
} def

% Eye coords
/ex 3 def
/ey 3 def
/ez 10 def
/eyedir [ex ey ez]
    dup mag [ exch dup dup ]{div} vop
def

% x y z -> X Y
/project {
3 dict begin
    /z exch def
    /y exch def
    /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } def

/light
    [ 3 -7 -4 1 ]
    %dup mag [ exch dup dup dup ]{div} vop
def
/Ia .4 def % Incident Ambient Intensity
/Ka .5 def % Ambient Diffuse reflection constant
/Il .3 def % Incident intensity of Lightsource
/Kd .4 def % Diffuse reflection constant

/front { 0 gt } def
/wirecolor
{ .5 .5 .5 sethsbcolor } def %medium-green wirecolor
%{} def %use fill-color as wirecolor
/wire? true def
/fill? true def
%/fudge 1.0 def
/fudge 1.03 def
%/fudge 1.06 def
%h R N
/cylinder { 20 dict begin
    %/facen 0 def
    /N exch def
    /R exch def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /fdt dt fudge mul def
    /hdz h dz mul def
    /fhdz hdz fudge mul def

    0 dz 1 dz sub {
        h mul h 2 div sub /z exch def

        0 dt 360 { /t exch def
            % Generate a small face on x^2+y^2=R^2
            % by x = cos, y = sin, z = z
            % w = dz, h ~= k*dt
            %/facen facen 1 add def
            /v1 [ t cos R mul
                t sin R mul
                z ] def
            /v4 [ v1 aload pop pop
                z fhdz add ] def
            /t t fdt add def
            /v2 [ t cos R mul
                t sin R mul
                z ] def
            /v3 [ v2 aload pop pop
                z fhdz add ] def

            % Check if face is inside
            % x^2+z^2=R^2 and y^2+z^2=R^2
            true [ v1 v2 v3 v4 ] {
                aload pop
                3 { 3 1 roll dup mul } repeat % x^2 y^2 z^2
                dup 4 1 roll % z x y z
                R dup mul dup 6 1 roll % r z x y z r
                3 1 roll add exch lt % r z x yz<r
                4 1 roll add exch lt % yz<r zx<r
                and and
            } forall % bool %within bounds of the other 2 cylinders

            { %if

            % Perform model->world transform
            [ v1 v2 v3 v4 ] {
                aload 4 1 roll model 4 3 roll astore pop
            } forall

            % Calculate normal vector in World coords
            /normal v4 v1 {sub} vop
                    v2 v1 {sub} vop
                    cross def
            /nlen normal mag def
            /normal normal [nlen nlen nlen] {div} vop def

            % Check visibility of a point on the face
            %/front { 0 gt } def
            normal v1 [ex ey ez] {sub} vop dot
            front % bool %facing the eye?

            % Draw the face
            { %if
        %[ v1 v2 v3 v4 ] ==
                % Draw the projected path
                /action { moveto /action { lineto } def } def
                %facen 2 mod 0 eq {
                [ v1 v2 v3 v4 ]
                %} {[ v1 v4 v3 v2 ]} ifelse
                { aload pop project
        %2 copy 2 array astore ==
                    prep
                    action }
                forall
                closepath
        %()= flush


                % Calculate illumination
                t 360 div  % hue
                z h 2 div add h div % sat

                [normal aload pop 1]
                light
                %[ex ey ez neg 1] %"radiant"
                dot
                Il
                1 light 0 3 getinterval
                v1 { sub } vop mag div mul
                Kd mul mul
                Ia Ka mul add
                %.2 add
                dup 1 gt { pop 1 } if
                %setgray % bright
                sethsbcolor

                % Draw according to control bools
                wire? { gsave wirecolor stroke grestore } if
                fill? { gsave
                    fill
                    %/flushpage where{pop flushpage}if
                grestore } if
                newpath

            } if % visible

            } if % inside other two cylinders

        } for % dt 0..360
    } for % dz
end } def % cylinder

/depp 0 def
/dep 1 def
{
    %/dep 1 add
    /dep dep depp add /depp dep def def %fibonacci
    (dep = )print dep =

300 400 translate
280 dup dup moveto
dup neg dup neg lineto
dup neg dup lineto
dup neg lineto closepath
.6 setgray
fill
1 70 dup dup scale div setlinewidth

%/front { 0 lt } def
/beta 0 def
/gamma 0 def
4 2 dep cylinder

%/front { 0 gt } def
/beta 90 def
/gamma 0 def
4 2 dep cylinder

/beta 0 def
/gamma 90 def
4 2 dep cylinder

showpage

} loop

[toc] | [prev] | [next] | [standalone]


#957 — Spinning Steinmertz Solid (approx.)

Fromluser- -droog <mijoryx@yahoo.com>
Date2012-09-11 21:29 -0700
SubjectSpinning Steinmertz Solid (approx.)
Message-ID<eed0f57a-1a9c-4528-9259-e7525dccb1af@googlegroups.com>
In reply to#956
Next step is clipping the faces more closely.

%!
%Spinning Steimertz Solid (approx.)

%(mat.ps) run
%!
%mat.ps
%Matrix and Vector math routines

/.error where { pop /signalerror { .error } def } if

/dot { % u v
    2 copy length exch length ne {
        /dot cvx /undefinedresult signalerror
    } if
    % u v
    0 % u v sum
    0 1 3 index length 1 sub { % u v sum i
        3 index 1 index get exch % u v sum u_i i
        3 index exch get % u v sum u_i v_i
        mul add % u v sum
    } for % u v sum

    3 1 roll pop pop % sum
} bind def

% [ x1 x2 x3 ] [ y1 y2 y3 ]  cross  [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1 ]
/cross { % u v
    dup length 3 ne
    2 index length 3 ne or {
        /cross cvx /undefinedresult signalerror
    } if
    % u v
    exch aload pop 4 3 roll aload pop % x1 x2 x3 y1 y2 y3
    [
        5 index 2 index mul % ... [ x2*y3
        3 index 6 index mul sub % ... [ x2*y3-y2*x3
        5 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1
        8 index 4 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3
        8 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2
        8 index 7 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1
    ]
    7 1 roll 6 { pop } repeat
} bind def

/transpose { STATICDICT begin
    /A exch def
    /M A length def
    /N A 0 get length def
    [
    0 1 N 1 sub { /n exch def
        [
        0 1 M 1 sub { /m exch def
            A m get n get
        } for
        ]
    } for
    ]
end } dup 0 6 dict put def

/matmul { STATICDICT begin
    /B exch def
    B 0 get type /arraytype ne { /B [B] def } if
    /A exch def
    A 0 get type /arraytype ne { /A [A] def } if
    /Q B length def
    /R B 0 get length def
    /P A length def
    Q A 0 get length ne {
        /A A transpose def
        /P A length def
        Q A 0 get length ne {
            A B end /matmul cvx /undefinedresult signalerror
        } if
    } if

    [
        0 1 P 1 sub { /p exch def
        [
    0 1 R 1 sub { /r exch def
            0
            0 1 Q 1 sub { /q exch def
                A p get q get
                B q get r get mul
                add
            } for
        } for
        ]
    } for
    ]

end } dup 0 10 dict put def

%u v {operator}  vop  u(op)v
%apply a binary operator to corresponding elements
%in two vectors producing a third vector as result
/vop { 1 dict begin
    /op exch def
    2 copy length exch length ne {
        /vop cvx end /undefinedresult signalerror
    } if

    [ 3 1 roll % [ u v
    0 1 2 index length 1 sub { % [ ... u v i
        3 copy exch pop get % u v i u_i
        3 copy pop get      % u v i u_i v_i
        op exch pop         % u v u_i(op)v_i
        3 1 roll            % u_i(op)v_i u v
    } for % [ ... u v
    pop pop ]

end } def

%length of a vector
/mag { 0 exch { dup mul add } forall } def


/prep {
    transform
    2 {
        exch
        %floor
        round
        %ceiling
        %2 mul cvi 2 div %round
    } repeat
    itransform
} def

% x y z ang -> x y' z'
/rotx { 3 dict begin
    /theta exch def
    /z exch def
    /y exch def
    y theta cos mul
    z theta sin mul sub
    y theta sin mul
    z theta cos mul add
end } def

% x y z ang -> x' y z'
/roty { 4 dict begin
    /theta exch def
    /z exch def
    /y exch def
    /x exch def
    x theta cos mul
    z theta sin mul add
    y
    x theta sin mul neg
    z theta cos mul add
end } def

% x y z ang -> x' y' z
/rotz { 4 dict begin
    /theta exch def
    /z exch def
    /y exch def
    /x exch def
    x theta cos mul
    y theta sin mul sub
    x theta sin mul
    y theta cos mul add
    z
end } def

% x y z -> x' y' z'
/model {
%ang roty
%ang .25 mul rotx
%alpha rotz
beta roty
gamma rotx
} def

% Eye coords
/ex 3 def
/ey 3 def
/ez 10 def
/eyedir [ex ey ez]
    dup mag [ exch dup dup ]{div} vop
def

% x y z -> X Y
/project {
3 dict begin
    /z exch def
    /y exch def
    /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } def

/light
    [ 3 -7 -4 1 ]
    %dup mag [ exch dup dup dup ]{div} vop
def
/Ia .4 def % Incident Ambient Intensity
/Ka .5 def % Ambient Diffuse reflection constant
/Il .3 def % Incident intensity of Lightsource
/Kd .4 def % Diffuse reflection constant

/omega 0 def
/makespinmat {
    /spinmat
        [[ omega cos 0 omega sin ]
         [ 0         1 0         ]
         [ omega sin neg 0 omega cos ]]
    def
} def
/spin { spinmat matmul } def
/front { 0 gt } def
/wirecolor
{ .5 .5 .5 sethsbcolor } def %medium-green wirecolor
%{} def %use fill-color as wirecolor
/wire? true def
/fill? true def
%/fudge 1.0 def
/fudge 1.03 def
%/fudge 1.06 def
%h R N
/cylinder { 20 dict begin
    %/facen 0 def
    /N exch def
    /R exch def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /fdt dt fudge mul def
    /hdz h dz mul def
    /fhdz hdz fudge mul def

    0 dz 1 dz sub {
        h mul h 2 div sub /z exch def

        0 dt 360 { /t exch def
            % Generate a small face on x^2+y^2=R^2
            % by x = cos, y = sin, z = z
            % w = dz, h ~= k*dt
            %/facen facen 1 add def
            /v1 [ t cos R mul
                t sin R mul
                z ] def
            /v4 [ v1 aload pop pop
                z fhdz add ] def
            /t t fdt add def
            /v2 [ t cos R mul
                t sin R mul
                z ] def
            /v3 [ v2 aload pop pop
                z fhdz add ] def

            % Check if face is inside
            % x^2+z^2=R^2 and y^2+z^2=R^2
            [ v1 v2 v3 v4 ] {
                aload pop
                3 { 3 1 roll dup mul } repeat % x^2 y^2 z^2
                dup 4 1 roll % z x y z
                R dup mul dup 6 1 roll % r z x y z r
                3 1 roll add exch lt % r z x yz<r
                4 1 roll add exch lt % yz<r zx<r
                and
            } forall
            4 copy
            or or or %true if any inside
            5 1 roll
            and and and %false if any outside
            exch %use any-outside
            pop
            % bool %within bounds of the other 2 cylinders

            { %if

            % Perform model->object transform
            [ v1 v2 v3 v4 ] {
                aload 4 1 roll model 4 3 roll astore pop
            } forall

            % Perform object->world transform
            [ v1 v2 v3 v4 ] {
                dup spin 0 get exch copy pop
            } forall

            % Calculate normal vector in World coords
            /normal v4 v1 {sub} vop
                    v2 v1 {sub} vop
                    cross def
            /nlen normal mag def
            /normal normal [nlen nlen nlen] {div} vop def

            % Check visibility of a point on the face
            %/front { 0 gt } def
            normal v1 [ex ey ez] {sub} vop dot
            front % bool %facing the eye?

            % Draw the face
            { %if
        %[ v1 v2 v3 v4 ] ==
                % Draw the projected path
                /action { moveto /action { lineto } def } def
                %facen 2 mod 0 eq {
                [ v1 v2 v3 v4 ]
                %} {[ v1 v4 v3 v2 ]} ifelse
                { aload pop project
        %2 copy 2 array astore ==
                    prep
                    action }
                forall
                closepath
        %()= flush


                % Calculate illumination
                t 360 div  % hue
                z h 2 div add h div % sat

                [normal aload pop 1]
                light
                %[ex ey ez neg 1] %"radiant"
                dot
                Il
                1 light 0 3 getinterval
                v1 { sub } vop mag div mul %scale light by dist
                Kd mul mul
                Ia Ka mul add
                %.2 add
                dup 1 gt { pop 1 } if
                %setgray % bright
                sethsbcolor

                % Draw according to control bools
                wire? { gsave wirecolor stroke grestore } if
                fill? { gsave
                    fill
                    %/flushpage where{pop flushpage}if
                grestore } if
                newpath

            } if % visible

            } if % inside other two cylinders

        } for % dt 0..360
    } for % dz
end } def % cylinder

%/depp 0 def
%/dep 1 def
/dep 77 def
{
    %/dep 1 add
    %/dep dep depp add /depp dep def def %fibonacci
    %(dep = )print dep =
    /omega omega 10 add def
    makespinmat

300 400 translate
280 dup dup moveto
dup neg dup neg lineto
dup neg dup lineto
dup neg lineto closepath
.6 setgray
fill
1 70 dup dup scale div setlinewidth

%/front { 0 lt } def
/beta 0 def
/gamma 0 def
4 2 dep cylinder

%/front { 0 gt } def
/beta 90 def
/gamma 0 def
4 2 dep cylinder

/beta 0 def
/gamma 90 def
4 2 dep cylinder

showpage
pstack

} loop                  

[toc] | [prev] | [next] | [standalone]


#958 — Mulligan (again)

Fromluser- -droog <mijoryx@yahoo.com>
Date2012-09-13 19:07 -0700
SubjectMulligan (again)
Message-ID<ee2cb1c5-cd26-49ad-b070-a86e35b5be4f@googlegroups.com>
In reply to#957
Trying to add clipping turned out to be a real mess.
So this is a step backwards, but up as well.
Just the wireframe for now, but a much better
separation of functions, and simpler coding overall, I think.

And it caches the faces in a file (self-executing, so it's a
"sprite" as well) that it executes three times for the three
cylinders.

And since I'm assuming file-access, I'm not inlining  mat.ps 
anymore. It's available in other messages to the group 
(and a buggy one on SO).

[PS. I know I've gone back to google, but as long as don't 
quote anybody, it's inoffensive, right? I've got to go 
newsserver shopping again...]


593(1)09:02 PM:ps 0> cat 3d5.ps
%!
%Steinmertz, take 5: NEEDFORSPEED
(mat.ps)run

/cylxz <<
    /inside { % x y z . bool
        exch pop
        dup mul exch dup mul add R^2 le } bind
>> def

/cylyz <<
    /inside { % x y z . bool
        dup mul exch dup mul add R^2 le
        exch pop } bind
>> def

/checkface { % [ v1 v2 v3 v4 ] dict
    begin
    { aload pop inside } forall
    4 copy eq eq eq { % all-eq
        pop pop pop
    }{ % uneq in>=1 out>=1
        pop pop pop %TODO: clipface
    } ifelse
end } bind def

/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/steinmertz-gen { 20 dict begin
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dz 1 dz sub {
        h mul h 2 div sub /z exch def

        0 dt 360 dt sub { /t exch def
            /v1 [ t cos R mul
                  t sin R mul
                  z ] def
            /v4 [ t cos R mul
                  t sin R mul
                  z hdz add ] def
            /t t dt add def
            /v2 [ t cos R mul
                  t sin R mul
                  z ] def
            /v3 [ t cos R mul
                  t sin R mul
                  z hdz add ] def

            [ v1 v2 v3 v4 ] cylxz checkface {
                [ v1 v2 v3 v4 ] cylyz checkface {
                    writeface
                } if
            } if
        } for
    } for
end } bind def


% Generate Data File to cache the faces

/data (stein.fac) def
{
    /in data (r) file def
} stopped {
    clear
    /out data (w) file def
    /outbuf 128 string def

   % Generate the faces
   %h R N
    4 2 21 steinmertz-gen

    flush
    out closefile
    /out null def

    /in data (r) file def
} if
/reopen { in closefile
    /in data (r) file def } def




/drawface { DICT begin % [[ v1 v2 v3 v4 ]]
    /action { moveto /action { lineto } def } def
    { % [ x y z ]
        MO matmul %[[x' y' z']]
        0 get aload pop %x' y' z'
        proj %X Y
        action
    } forall
    closepath stroke
end } dup 0 2 dict put bind def

/I3 [[1 0 0]
     [0 1 0]
     [0 0 1]] def
/MO I3 def %default model-object transform

/E [ 0 0 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def

300 400 translate
1 90 dup dup scale div setlinewidth

in cvx exec reopen
/MO [[1 0 0]
     [0 0 1]
     [0 1 0]] def % 90 rotx
in cvx exec reopen
/MO [[0 0 1]
     [0 1 0]
     [1 0 0]] def % 90 roty
in cvx exec

showpage

[toc] | [prev] | [next] | [standalone]


#960 — Re: Mulligan (again)

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2012-09-14 05:05 -0400
SubjectRe: Mulligan (again)
Message-ID<szi9moh828nm.199hpmrhszz6l$.dlg@40tude.net>
In reply to#958
On Thu, 13 Sep 2012 19:07:37 -0700 (PDT), luser- -droog wrote:

> ... I've got to go 
> newsserver shopping again ...

http://aioe.org/ ... news.eternal-september.org ... freenews.netfront.net

There are others, too. HTH. Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#961 — Heineken time

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-15 16:50 -0500
SubjectHeineken time
Message-ID<k32t79$bmo$1@dont-email.me>
In reply to#960
tlvp wrote:

> On Thu, 13 Sep 2012 19:07:37 -0700 (PDT), luser- -droog wrote:
> 
>> ... I've got to go
>> newsserver shopping again ...
> 
> http://aioe.org/ ... news.eternal-september.org ... freenews.netfront.net
> 
> There are others, too. HTH. Cheers, -- tlvp

Awesome! thnx. And eternal-september has its own calendrical system!

So I did some further reorganizing and added normal-visibility and
simplified the model->object transform. Even without lighting and color,
I think it looks pretty cool now.

625(1)04:49 PM:ps 1> cat 3d5.ps
%!
%Steinmertz, take 5: NEEDFORSPEED
(mat.ps)run

%/forall { pstack()= forall } bind def

%The horizontal chopping cylinder
/cylxz <<
    /inside { % x y z . bool
        exch pop
        dup mul exch dup mul add R^2 le } bind
>> def

%The vertical chopping cylinder
/cylyz <<
    /inside { % x y z . bool
        dup mul exch dup mul add R^2 le
        exch pop } bind
>> def

%Check that the vertices of a face
%are inside a specified chopping cylinder
/checkface { % [ v1 v2 v3 v4 ] dict
    begin
    { aload pop inside } forall
    4 copy eq 3 1 roll eq eq { % all-eq
        pop pop pop
    }{ % uneq in>=1 out>=1
        pop pop pop %TODO: clipface
        %pop false
    } ifelse
end } bind def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmertz-gen { 20 dict begin
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dz 1 dz sub {
        h mul h 2 div sub /z exch def

        0 dt dup N 3 add mul { /t exch def
            /v1 [ t cos R mul
                  t sin R mul
                  z ] def
            /v4 [ t cos R mul
                  t sin R mul
                  z hdz add ] def
            /t t dt add def
            /v2 [ t cos R mul
                  t sin R mul
                  z ] def
            /v3 [ t cos R mul
                  t sin R mul
                  z hdz add ] def
            /face [ v1 v2 v3 v4 ] def

            face cylxz checkface {
                face cylyz checkface {
                    doface
                } if
            } if
        } for
    } for
end } bind def

%Action performed by steinmertz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N
    4 2 89 steinmertz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/wire? true def
/wirecolor
%{} def
{1 setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        %set color
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 0 0 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup 0 get 1 index 1 get 2 index 3 get % [] v1 v2 v4
    2 index { sub } vop % [] v1 v2 v14
    3 1 roll exch { sub } vop % [] v14 v12
    cross /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get E { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 gt % [] bool
    exch pop
} def

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def


/setuppage {
    300 400 translate
    1 90 dup dup scale div setlinewidth
} def

/usecache? true def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/ang 0 def
{
    /OW ang roty def
    /ang ang 10 add def

    setuppage

    /model {} def % x y z -> x y z
    %/MO I3 def
    drawshape
    /model { exch neg } def % x y z -> x z -y
    %/MO up def
    drawshape
    /model { 3 1 roll exch neg } def % x y z -> z y -x
    %/MO left def
    drawshape

    showpage
} loop
                     

[toc] | [prev] | [next] | [standalone]


#962 — Bigger and Badderer

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-16 23:33 -0500
SubjectBigger and Badderer
Message-ID<k36961$u0a$1@dont-email.me>
In reply to#961
luser.droog wrote:

> tlvp wrote:
> 
>> On Thu, 13 Sep 2012 19:07:37 -0700 (PDT), luser- -droog wrote:
>> 
>>> ... I've got to go
>>> newsserver shopping again ...
>> 
>> http://aioe.org/ ... news.eternal-september.org ... freenews.netfront.net
>> 
>> There are others, too. HTH. Cheers, -- tlvp
> 
> Awesome! thnx. And eternal-september has its own calendrical system!
> 
> So I did some further reorganizing and added normal-visibility and
> simplified the model->object transform. Even without lighting and color,
> I think it looks pretty cool now.
> 
> 625(1)04:49 PM:ps 1> cat 3d5.ps

Back to the drawing board, I realized that nothing really changes along
the "z" axis of a cylinder. So there's really no need to iterate over it.
So I tried one big face per theta but then there's no known "inside"
point to seed the clip. So I tried two faces per theta with vertices like 
6 on a domino. Then I realized that I could avoid clipping against one
of the cylinders by simply setting the outer z coords on the face by 
solving for z using x or y of one of the cylinders, the x or y already
calculated for the face. After further playing, I realized I could take
both and use the max for the upper z and min for the lower z. Thus the
faces of the cylinder being drawn are bounded by the other two.
No need to clip. But I leave it here anyway so you all can see how
heinous doing vector clipping is (assuming a demonstration of this fact
is at all necessary to anyone).

But while most of the shape is simple and beautiful, there are distracting
artifacts at the 4-face joins that look like little swastikas a higher
resolutions. And that just sucks. Maybe I should ask for help with that
on SO... (???)

Anyway, I snagged a simpler light calculation from Casselman than the
one from Rogers, and set the hue to the x/y angle of v1 of the face,
const .5 saturation. And wow! If you can overlook (or remove! ?) 
the swastikas, this is quite pretty to look at. Maybe a dark background
would help...

522(1)11:30 PM:ps 0> cat 3d5.ps
%!
%Steinmertz, take 5: NEEDFORSPEED
% O(N) generator makes caching largely irrelevant!
% Bounded faces makes clipping unnecessary
% (which wasn't quite working somehow)
% Improved visibility now shows the Front of the object!
% TODO: eliminate those ugly swastika artifacts
(mat.ps)run

%/forall { pstack()= forall } bind def
%/if { pstack()= if } bind def

/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

%The vertical chopping cylinder
/cylyz <<
    /inside { % x y z . bool
        dup mul exch dup mul add R^2 le
        exch pop } bind
    /doparams {
        /D edge 1 get edge 0 get { sub } vop
           [ 1 index mag dup dup ] { div } vop def
        /a D 1 get dup mul D 2 get dup mul add def
        /b 2 edge 0 get 1 get D 1 get mul mul
            2 edge 0 get 2 get D 2 get mul mul add def
        /c edge 0 get 1 get dup mul
            edge 0 get 2 get dup mul add 1 sub def
        /t [ b dup mul 4 a c mul mul sub dup 0 lt { neg } if
            sqrt 2 a mul div dup neg
            b neg 2 a mul div add exch
            b neg 2 a mul div add ] def }
>> def

%The horizontal chopping cylinder
/cylxz <<
    /inside { % x y z . bool
        exch pop
        dup mul exch dup mul add R^2 le } bind
    /doparams {
        /D edge 1 get edge 0 get { sub } vop
           %[ 1 index mag dup dup ] { div } vop
           def
        /a D 0 get dup mul D 2 get dup mul add def
        /b 2 edge 0 get 0 get D 0 get mul mul
            2 edge 0 get 2 get D 2 get mul mul add def
        /c edge 0 get 0 get dup mul
            edge 0 get 2 get dup mul add 1 sub def
        /t [ b dup mul 4 a c mul mul sub dup 0 lt { neg } if
            sqrt 2 a mul div dup neg
            b neg 2 a mul div add exch
            b neg 2 a mul div add ] def }
>> def

%cd:chopping-cylinder
/clipface { /i exch def
    /v1 face 0 get def
    /v2 face 1 get def
    /v3 face 2 get def
    /v4 face 3 get def
    [ [v1 v2] [v4 v3] [v1 v2] [v4 v3] [v1 v2] [v2 v1] [v3 v4] ]
    i 2 getinterval { /edge exch def
        edge 1 get aload pop inside not {
            doparams
            t aload pop
            2 copy 0 lt exch 0 lt xor { dup 0 ge { exch } if pop }{
                2 copy lt { exch } if pop
            } ifelse
            dup 1 gt { pop 1.01 } if
            [ exch dup dup ] D { mul } vop
            edge 0 get { add } vop
            edge 1 get copy pop
        } if
    } forall
    true
} def

%Check that the vertices of a face
%are inside a specified chopping cylinder
/checkface { % [ v1 v2 v3 v4 ] dict
    begin
    { aload pop inside } forall
    %pop true false false true
    %4 copy eq 3 1 roll eq eq { % all-eq
    %    pop pop pop
    %}{ % uneq in>=1 out>=1
        true { %don't clip
            pop pop pop pop true
        }{
           { %if v4true
               pop pop pop
               3 clipface
            }{ %else
                { %if v3true
                    pop pop
                    2 clipface
                }{ %else
                    { %if v2true
                        pop
                        1 clipface
                    }{ %else
                        { %if v1true
                            0 clipface
                        }{ %else none true
                            false
                        } ifelse
                    } ifelse
                } ifelse
            } ifelse % i(v_i inside)
        } ifelse
    %} ifelse
end } bind def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/fudge 1.03 def
%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmertz-gen {
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dt 360 { /t exch def
        %0 dt 180 { /u exch def

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
        ] def
        /t t dt fudge mul add def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        face cylyz checkface { doface } if

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
        ] def
        /t t dt fudge mul sub def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        face cylyz checkface { doface } if

        %} for
    } for
} def

%Action performed by steinmertz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N
    4 2 300 steinmertz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/wire? false def
/wirecolor
%{} def
{1 setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        colorface
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        /flushpage where { pop flushpage } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 3 3 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup 0 get 1 index 1 get 2 index 3 get % [] v1 v2 v4
    2 index { sub } vop % [] v1 v2 v14
    3 1 roll exch { sub } vop % [] v14 v12
    cross /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get E { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 lt % [] bool
    exch pop
} def

/light [ -5 10 20 ] def

/colorface {
    %normal light dot 1 add 3 div setgray
    face 0 get aload pop pop exch atan 360 div
    .5
    normal light dot 1 add 3 div sethsbcolor
} def

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def


/setuppage {
    300 400 translate
    1 90 dup dup scale div 2 div setlinewidth
} def

/usecache? false def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        pop pop pop%clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/ang 0 def
{
    /OW ang roty def
    /ang ang 10 add def

    setuppage

    /model {} def % x y z -> x y z
    %/MO I3 def
    drawshape
    /model { neg exch } def % x y z -> x -z y
    %/MO up def
    drawshape
    /model { neg 3 1 roll exch } def % x y z -> -z y x
    %/MO left def
    drawshape

    pstack flush
    showpage
} loop

[toc] | [prev] | [next] | [standalone]


#963 — Re: Bigger and Badderer

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-16 23:37 -0500
SubjectRe: Bigger and Badderer
Message-ID<k369dh$u0a$2@dont-email.me>
In reply to#962
luser.droog wrote:

> 522(1)11:30 PM:ps 0> cat 3d5.ps
> %!
> %Steinmertz, take 5: NEEDFORSPEED
> % O(N) generator makes caching largely irrelevant!
> % Bounded faces makes clipping unnecessary
> % (which wasn't quite working somehow)
> % Improved visibility now shows the Front of the object!
> % TODO: eliminate those ugly swastika artifacts

TODO: Start spelling Steinmetz correctly.

[toc] | [prev] | [next] | [standalone]


#964 — QapplaH!

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-17 11:34 -0500
SubjectQapplaH!
Message-ID<k37jeg$95s$1@dont-email.me>
In reply to#963
luser.droog wrote:

> luser.droog wrote:
> 
>> 522(1)11:30 PM:ps 0> cat 3d5.ps
>> %!
>> %Steinmertz, take 5: NEEDFORSPEED
>> % O(N) generator makes caching largely irrelevant!
>> % Bounded faces makes clipping unnecessary
>> % (which wasn't quite working somehow)
>> % Improved visibility now shows the Front of the object!
>> % TODO: eliminate those ugly swastika artifacts
> 
> TODO: Start spelling Steinmetz correctly.

Done and Done.

The little swastikas were happening at the corners
where the quadrilateral faces degenerated to triangles.
That meant that one or the other of the edges being
used to calculate the normal vector was of length 0.
Thus the normal vector was 0, which produces a zero
dot product against any vector (like the vector from
the eye).

I fixed it by checking for degenerate edges and 
selecting a different vertex if it is. There's still
a missing triangle at each of the 3-point joins.
But that doesn't bother me so much.


533(1)11:30 AM:ps 0> cat 3d5.ps
%!
%Steinmetz, take 5: NEEDFORSPEED
% O(N) generator makes caching largely irrelevant!
% Bounded faces makes clipping unnecessary
% (which wasn't quite working somehow)
% Improved visibility now shows the Front of the object!
% Eliminated those ugly swastika artifacts
(mat.ps)run

/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/fudge 1.03 def
%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmetz-gen {
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dt 360 { /t exch def
        %0 dt 180 { /u exch def

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
        ] def
        /t t dt fudge mul add def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if
        %face ==

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
        ] def
        /t t dt fudge mul sub def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if

        %} for
    } for
} def

%Action performed by steinmetz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N
    4 2 500 steinmetz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/wire? true def
/wirecolor
%{} def
%{1 setgray} def
{normal light dot 1 add 4 div setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        colorface
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        /flushpage where { pop flushpage } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 3 3 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup
    aload pop /v4 exch def /v3 exch def /v2 exch def /v1 exch def
    %dup 0 get 1 index 2 get 2 index 3 get % [] v1 v2 v4
    %2 index { sub } vop % [] v1 v2 v14
    %3 1 roll exch { sub } vop % [] v14 v12
    %cross
    v1 v4{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    v1 v2{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    cross
    /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get E { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 lt % [] bool
    exch pop
} def

/light [ -5 10 20 ] def

/colorface {
    %normal light dot 1 add 3 div setgray
    face 0 get 45 rotz matmul 0 get
    aload pop pop %exch
    dup 0 eq { pop .001 } if
    atan 360 div 3 div fn .33 mul add
    %.5
    face 0 get 60 rotz matmul 0 get
    aload pop pop exch
    dup 0 eq { pop .001 } if
    atan 360 div 2 div .25 add
    normal light dot 1 add 3 div
    3 { 3 1 roll dup 1 gt { pop 1 } if dup 0 lt { pop 0 } if } repeat
    sethsbcolor
} def

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def


/setuppage {
    300 400 translate
    1 90 dup dup scale div 2 div setlinewidth
} def

/usecache? false def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        pop pop pop%clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/ang 0 def
{
    /OW ang roty def
    /ang ang 10 add def

    setuppage

    /fn 0 def
    /model {} def % x y z -> x y z
    %/MO I3 def
    drawshape
    /fn 1 def
    /model { neg exch } def % x y z -> x -z y
    %/MO up def
    drawshape
    /fn 2 def
    /model { neg 3 1 roll exch } def % x y z -> -z y x
    %/MO left def
    drawshape

    pstack flush
    showpage
} loop

[toc] | [prev] | [next] | [standalone]


#965 — Re: QapplaH! (appendix: updated mat.ps)

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-17 13:05 -0500
SubjectRe: QapplaH! (appendix: updated mat.ps)
Message-ID<k37oq0$eb0$1@dont-email.me>
In reply to#964
Added identity and rotation(3D) matrices.


%!
%mat.ps
%Matrix and Vector math routines

/ident { 1 dict begin /n exch def
    [
    1 1 n { % [ i
        [ exch % [ [ i
        1 1 n { % [ [ i j
            1 index eq { 1 }{ 0 } ifelse % [ [ i b
            exch % [ [ b i
        } for % [ [ b+ i
        pop ] % [ [ b+ ]
    } for % [ [b+]+ ]
    ]
end } def

/rotx { 1 dict begin /t exch def
    [ [ 1  0      0         ]
      [ 0  t cos  t sin neg ]
      [ 0  t sin  t cos     ] ]
end } def

/roty { 1 dict begin /t exch def
    [ [ t cos      0  t sin ]
      [ 0          1  0     ]
      [ t sin neg  0  t cos ] ]
end } def

/rotz { 1 dict begin /t exch def
    [ [ t cos  t sin neg  0 ]
      [ t sin  t cos      0 ]
      [ 0      0          1 ] ]
end } def

/.error where { pop /signalerror { .error } def } if

/dot { % u v
    2 copy length exch length ne {
        /dot cvx /undefinedresult signalerror } if
    % u v
    0 % u v sum
    0 1 3 index length 1 sub { % u v sum i
        3 index 1 index get exch % u v sum u_i i
        3 index exch get % u v sum u_i v_i
        mul add % u v sum
    } for % u v sum
    3 1 roll pop pop % sum
} bind def

% [ x1 x2 x3 ] [ y1 y2 y3 ]  cross  [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1 ]
/cross { % u v
    dup length 3 ne 2 index length 3 ne or {
        /cross cvx /undefinedresult signalerror } if
    % u v
    exch aload pop 4 3 roll aload pop % x1 x2 x3 y1 y2 y3
    [
        5 index 2 index mul % ... [ x2*y3
        3 index 6 index mul sub % ... [ x2*y3-y2*x3
        5 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1
        8 index 4 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3
        8 index 5 index mul % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2
        8 index 7 index mul sub % ... [ x2*y3-y2*x3 x3*y1-x1*y3 x1*y2-x2*y1
    ]
    7 1 roll 6 { pop } repeat
} bind def

/transpose { STATICDICT begin
    /A exch def
    /M A length def
    /N A 0 get length def
    [
    0 1 N 1 sub { /n exch def
        [
        0 1 M 1 sub { /m exch def
            A m get n get
        } for
        ]
    } for
    ]
end } dup 0 6 dict put def

/matmul { STATICDICT begin
    /B exch def
    B 0 get type /arraytype ne { /B [B] def } if
    /A exch def
    A 0 get type /arraytype ne { /A [A] def } if
    /Q B length def
    /R B 0 get length def
    /P A length def
    Q A 0 get length ne {
        /A A transpose def
        /P A length def
        Q A 0 get length ne {
            A B end /matmul cvx /undefinedresult signalerror
        } if
    } if

    [
    0 1 P 1 sub { /p exch def % rows of A
        [
        0 1 R 1 sub { /r exch def % cols of B
            0
            0 1 Q 1 sub { /q exch def % terms of sum
                A p get q get
                B q get r get mul
                add
            } for
        } for
        ]
    } for
    ]

end } dup 0 10 dict put def

%u v {operator}  vop  u(op)v
%apply a binary operator to corresponding elements
%in two vectors producing a third vector as result
/vop { 1 dict begin
    /op exch def
    2 copy length exch length ne {
        /vop cvx end /undefinedresult signalerror
    } if

    [ 3 1 roll % [ u v
    0 1 2 index length 1 sub { % [ ... u v i
        3 copy exch pop get % u v i u_i
        3 copy pop get      % u v i u_i v_i
        op exch pop         % u v u_i(op)v_i
        3 1 roll            % u_i(op)v_i u v
    } for % [ ... u v
    pop pop ]

end } def

%length of a vector
/mag { 0 exch { dup mul add } forall } def

[toc] | [prev] | [next] | [standalone]


#966 — one more cup of coffee for the road.

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-18 02:51 -0500
Subjectone more cup of coffee for the road.
Message-ID<k3996n$e0j$1@dont-email.me>
In reply to#965
Pretty much done with this, I think. Still, I kept playing with it.
Since the colors were set by the position of the face and the thing has
4x radial symmetry, it didn't take a full rotation to "see the whole thing".

So I jazzed it up!

I've got it set up now to change the settings to a random configuration
for each cylinder. And it draws the back first and then the front.

So run it with 'gs -dNOGC -dNOPAUSE 3d5a.ps' and you'll visualize the 
solid and the circles and the squares in no time flat.

So, hold onto yer socks.

%!
%Steinmetz, take 5: NEEDFORSPEED
% O(N) generator makes caching largely irrelevant!
% Bounded faces makes clipping unnecessary
% (which wasn't quite working somehow)
% Improved visibility now shows the Front of the object!
% Eliminated those ugly artifacts
% Random Configurations (with optional "less-random" mode)
(mat.ps)run

/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/fudge
1 def
%1.03 def
%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmetz-gen {
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dt 360 { /t exch def
        %0 dt 180 { /u exch def

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
        ] def
        /t t dt fudge mul add def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def 
        %face cylyz checkface {
            doface
        %} if
        %face ==

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
        ] def
        /t t dt fudge mul sub def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def 
        %face cylyz checkface {
            doface
        %} if

        %} for 
    } for 
} def

%Action performed by steinmetz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N 
    4 2 300 steinmetz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/fillcolor {} def
/wire? false def
/wirecolor
%{} def
%{0 setgray} def
%{1 setgray} def
{normal light dot 1 add 4 div
    %1 exch sub
    setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        colorface fillcolor
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        /flushpage where { pop flushpage } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 3 3 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

/vistest { lt } def
%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup
    aload pop /v4 exch def /v3 exch def /v2 exch def /v1 exch def
    %dup 0 get 1 index 2 get 2 index 3 get % [] v1 v2 v4
    %2 index { sub } vop % [] v1 v2 v14
    %3 1 roll exch { sub } vop % [] v14 v12
    %cross
    v1 v4{sub}vop 
    dup mag 0 eq { pop v1 v3{sub}vop } if
    v1 v2{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    cross
    /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get E { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 vistest % [] bool
    exch pop
} def

/light [ -7 12 30 ] def

/colorface {
    %normal light dot 1 add 3 div setgray
    %face 0 get 90 rotz matmul 0 get
    %aload pop pop %exch
    %dup 0 eq { pop .001 } if
    %atan 360 div 3 div
    fn .33 mul %add
    %.5
    face 0 get -90 rotz matmul 0 get
    aload pop pop exch
    dup 0 eq { pop .001 } if
    atan 360 div 2 div .25 add
    normal light dot 1 add 3 div
    3 { 3 1 roll dup 1 gt { pop 1 } if dup 0 lt { pop 0 } if } repeat
    sethsbcolor
} def

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def


/setuppage {
    310 440 translate
    1 120 dup dup scale div 2 div setlinewidth
} def

/usecache? false def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        pop pop pop%clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/front { /vistest { lt } def } def
/back { /vistest { gt } def } def

/drawsolid {
    /fn 0 def
    /model {} def % x y z -> x y z
    drawshape

    /fn 1 def
    /model { neg exch } def % x y z -> x -z y
    morerandom? { randconfig } if
    drawshape

    /fn 2 def
    /model { neg 3 1 roll exch } def % x y z -> -z y x
    morerandom? { randconfig } if
    drawshape
} def

/rbool { rand 2 mod 0 eq } def

/randconfig {
    true rbool
    rbool { exch } if /fill? exch def /wire? exch def
    [{} {} {} {} {} {0 setgray} {0 setgray}
    {1 setgray} {1 setgray} {1 setgray}
    {normal light dot 1 add 4 div setgray}
    {normal light dot 1 add 4 div 1 exch sub setgray}
    { 1 currentgray sub setgray }
    { currenthsbcolor exch pop .5 exch sethsbcolor }
    { currenthsbcolor 3 2 roll .33 add dup 1 gt {1 sub} if
        3 1 roll exch pop .5 exch sethsbcolor }
    { currenthsbcolor 1 exch sub sethsbcolor }
    { currentrgbcolor exch 1 exch sub exch setrgbcolor }
    { currenthsbcolor setrgbcolor }
    { currentrgbcolor sethsbcolor }
    { currentrgbcolor 3 1 roll exch setrgbcolor }
    //colorface //colorface //colorface //colorface //colorface
    ] dup
        dup length rand exch mod get /wirecolor exch def
        dup length rand exch mod get /fillcolor exch def
    currentlinewidth 1 rand 2 mod 2 div add mul setlinewidth
    /fudge 1 rand 10 mod 100 div add def
} def

/morerandom? true def

/ang 0 def
{
    /OW ang roty def
    /ang ang 3 add def

    setuppage

    %/fill? true def
    %/wire? true def
    %/wirecolor { 1 currentgray sub setgray } def
    back
    randconfig
    drawsolid

    %/fill? false def
    %/wire? true def
    %/wirecolor {} def
    %2 setlinewidth
    %currentlinewidth 2 mul setlinewidth
    front
    randconfig
    drawsolid

    pstack flush %cya

    %pause for applause
    500000 { 100 dup cos exch sin exch atan pop } repeat
    showpage
} loop

[toc] | [prev] | [next] | [standalone]


#967 — Re: Bigger and Badderer

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2012-09-18 21:52 -0400
SubjectRe: Bigger and Badderer
Message-ID<19l2060m89rf3.qhkwlr9njofj.dlg@40tude.net>
In reply to#963
On Sun, 16 Sep 2012 23:37:05 -0500, luser.droog wrote:

> luser.droog wrote:
> 
>> 522(1)11:30 PM:ps 0> cat 3d5.ps
>> %!
>> %Steinmertz, take 5: NEEDFORSPEED
>> % O(N) generator makes caching largely irrelevant!
>> % Bounded faces makes clipping unnecessary
>> % (which wasn't quite working somehow)
>> % Improved visibility now shows the Front of the object!
>> % TODO: eliminate those ugly swastika artifacts
> 
> TODO: Start spelling Steinmetz correctly.

 (LOL)! . Suppress that "r", though, and the Smithsonian's Uta C. Merzbach
(she without the "t" before the "z") might take offense at its loss :-) .

Cheers, -- tlvp

PS: I've let the takes through and beyond Take 5 go without comment  so far
because you seem to be guiding yourself pretty well on your own, w/o
benefit of my misguided and digressionary kibitzing :-) . -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#968 — Re: Bigger and Badderer

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-18 22:30 -0500
SubjectRe: Bigger and Badderer
Message-ID<k3be7v$cna$1@dont-email.me>
In reply to#967
tlvp wrote:

> On Sun, 16 Sep 2012 23:37:05 -0500, luser.droog wrote:
> 
>> luser.droog wrote:
>> 
>>> 522(1)11:30 PM:ps 0> cat 3d5.ps
>>> %!
>>> %Steinmertz, take 5: NEEDFORSPEED
>>> % O(N) generator makes caching largely irrelevant!
>>> % Bounded faces makes clipping unnecessary
>>> % (which wasn't quite working somehow)
>>> % Improved visibility now shows the Front of the object!
>>> % TODO: eliminate those ugly swastika artifacts
>> 
>> TODO: Start spelling Steinmetz correctly.
> 
>  (LOL)! . Suppress that "r", though, and the Smithsonian's Uta C. Merzbach
> (she without the "t" before the "z") might take offense at its loss :-) .
> 
> Cheers, -- tlvp
> 
> PS: I've let the takes through and beyond Take 5 go without comment  so
> far because you seem to be guiding yourself pretty well on your own, w/o
> benefit of my misguided and digressionary kibitzing :-) . -- tlvp

No problem there. But if there is anything else you want to see it do,
let me know. If I can figure out more about the projection math,
enough to rotate the projection plane, then I could move that little
tear in the coloring right at the front where the z-axis pokes through.
It doesn't look terrible to me, but it is an infelicity not being able
to control it. As it is, no matter how I rotate the points to select the
hue, there's always that tear at the front.

[toc] | [prev] | [next] | [standalone]


#969 — Re: Bigger and Badderer

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2012-09-19 00:59 -0400
SubjectRe: Bigger and Badderer
Message-ID<14ft6rfdwakqg.wjjegxgk9adf$.dlg@40tude.net>
In reply to#968
On Tue, 18 Sep 2012 22:30:03 -0500, luser.droog wrote:

> tlvp wrote:
> 
>> On Sun, 16 Sep 2012 23:37:05 -0500, luser.droog wrote:
>> 
>>> luser.droog wrote:
>>> 
>>>> 522(1)11:30 PM:ps 0> cat 3d5.ps
>>>> %!
>>>> %Steinmertz, take 5: NEEDFORSPEED
>>>> % O(N) generator makes caching largely irrelevant!
>>>> % Bounded faces makes clipping unnecessary
>>>> % (which wasn't quite working somehow)
>>>> % Improved visibility now shows the Front of the object!
>>>> % TODO: eliminate those ugly swastika artifacts
>>> 
>>> TODO: Start spelling Steinmetz correctly.
>> 
>>  (LOL)! . Suppress that "r", though, and the Smithsonian's Uta C. Merzbach
>> (she without the "t" before the "z") might take offense at its loss :-) .
>> 
>> Cheers, -- tlvp
>> 
>> PS: I've let the takes through and beyond Take 5 go without comment  so
>> far because you seem to be guiding yourself pretty well on your own, w/o
>> benefit of my misguided and digressionary kibitzing :-) . -- tlvp
> 
> No problem there. But if there is anything else you want to see it do,
> let me know. If I can figure out more about the projection math,
> enough to rotate the projection plane, then I could move that little
> tear in the coloring right at the front where the z-axis pokes through.
> It doesn't look terrible to me, but it is an infelicity not being able
> to control it. As it is, no matter how I rotate the points to select the
> hue, there's always that tear at the front.

That tear at the front is probably another indication of the validity of
what's called the "index theorem (aka Hairy Ball Theorem) for non-vanishing
vector fields on a 2-sphere", sometimes paraphrased as: "Ya can't comb the
hair on a coconut without leaving a swirl" :-) . Your "tear" = the index
theorem's "swirl". (Yeah -- go ahead, Google it, you'll find it :-) !)

Best you can try to do is hide it in back somewhere, where it can't show.

Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#970 — Re: Bigger and Badderer

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-19 00:48 -0500
SubjectRe: Bigger and Badderer
Message-ID<k3bmam$dfd$1@dont-email.me>
In reply to#969
tlvp wrote:

> On Tue, 18 Sep 2012 22:30:03 -0500, luser.droog wrote:
> 
>> tlvp wrote:
>> 
>>> On Sun, 16 Sep 2012 23:37:05 -0500, luser.droog wrote:
>>> 
>>>> luser.droog wrote:
>>>> 
>>>>> 522(1)11:30 PM:ps 0> cat 3d5.ps
>>>>> %!
>>>>> %Steinmertz, take 5: NEEDFORSPEED
>>>>> % O(N) generator makes caching largely irrelevant!
>>>>> % Bounded faces makes clipping unnecessary
>>>>> % (which wasn't quite working somehow)
>>>>> % Improved visibility now shows the Front of the object!
>>>>> % TODO: eliminate those ugly swastika artifacts
>>>> 
>>>> TODO: Start spelling Steinmetz correctly.
>>> 
>>>  (LOL)! . Suppress that "r", though, and the Smithsonian's Uta C.
>>>  Merzbach
>>> (she without the "t" before the "z") might take offense at its loss :-)
>>> .
>>> 
>>> Cheers, -- tlvp
>>> 
>>> PS: I've let the takes through and beyond Take 5 go without comment  so
>>> far because you seem to be guiding yourself pretty well on your own, w/o
>>> benefit of my misguided and digressionary kibitzing :-) . -- tlvp
>> 
>> No problem there. But if there is anything else you want to see it do,
>> let me know. If I can figure out more about the projection math,
>> enough to rotate the projection plane, then I could move that little
>> tear in the coloring right at the front where the z-axis pokes through.
>> It doesn't look terrible to me, but it is an infelicity not being able
>> to control it. As it is, no matter how I rotate the points to select the
>> hue, there's always that tear at the front.
> 
> That tear at the front is probably another indication of the validity of
> what's called the "index theorem (aka Hairy Ball Theorem) for
> non-vanishing vector fields on a 2-sphere", sometimes paraphrased as: "Ya
> can't comb the hair on a coconut without leaving a swirl" :-) . Your
> "tear" = the index theorem's "swirl". (Yeah -- go ahead, Google it, you'll
> find it :-) !)
> 
> Best you can try to do is hide it in back somewhere, where it can't show.
> 
> Cheers, -- tlvp

I decided to go the other way and make it appear bold and "justified".
This one has a new "cage" mode where the back always has a fill and the
front is only wires. And it draws coordinate axes in the middle.
The linewidth varies so sometimes the interior is more revealed, sometimes
more obscured.

557(1)12:41 AM:ps 0> cat 3d5b.ps
%!
%Steinmetz, take 5: NEEDFORSPEED
% O(N) generator makes caching largely irrelevant!
% Bounded faces makes clipping unnecessary
% (which wasn't quite working somehow)
% Improved visibility now shows the Front of the object!
% Eliminated those ugly artifacts
% Random Configurations (with optional "less-random" mode)
(mat.ps)run

/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/fudge
1 def
%1.03 def
%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmetz-gen {
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dt 360 { /t exch def
        %0 dt 180 { /u exch def

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
        ] def
        /t t dt fudge mul add def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if
        %face ==

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
        ] def
        /t t dt fudge mul sub def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if

        %} for
    } for
} def

%Action performed by steinmetz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N
    4 2 300 steinmetz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/fillcolor {} def
/wire? false def
/wirecolor
%{} def
%{0 setgray} def
%{1 setgray} def
{normal light dot 1 add 4 div
    %1 exch sub
    setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        colorface fillcolor
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        /flushpage where { pop flushpage } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 3 3 10 ] def %eye point
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

/vistest { lt } def
%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup
    aload pop /v4 exch def /v3 exch def /v2 exch def /v1 exch def
    %dup 0 get 1 index 2 get 2 index 3 get % [] v1 v2 v4
    %2 index { sub } vop % [] v1 v2 v14
    %3 1 roll exch { sub } vop % [] v14 v12
    %cross
    v1 v4{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    v1 v2{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    cross
    /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get E { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 vistest % [] bool
    exch pop
} def

/light [ -7 12 30 ] def

/colorface {
    %normal light dot 1 add 3 div setgray
    %face 0 get 90 rotz matmul 0 get
    %aload pop pop %exch
    %dup 0 eq { pop .001 } if
    %atan 360 div 3 div
    fn .33 mul %add
    %.5
    face 0 get -90 rotz matmul 0 get
    aload pop pop exch
    dup 0 eq { pop .001 } if
    atan 360 div 2 div .25 add
    normal light dot 1 add 3 div
    3 { 3 1 roll dup 1 gt { pop 1 } if dup 0 lt { pop 0 } if } repeat
    sethsbcolor
} def

/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def


/setuppage {
    310 440 translate
    1 120 dup dup scale div 2 div setlinewidth
    2 setlinejoin
} def

/usecache? false def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        pop pop pop%clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/front { /vistest { lt } def } def
/back { /vistest { gt } def } def

/drawsolid {
    /fn 0 def
    /model {} def % x y z -> x y z
    drawshape

    /fn 1 def
    /model { neg exch } def % x y z -> x -z y
    morerandom? { randconfig } if
    drawshape

    /fn 2 def
    /model { neg 3 1 roll exch } def % x y z -> -z y x
    morerandom? { randconfig } if
    drawshape
} def

/rbool { rand 2 mod 0 eq } def

/randconfig {
    cage? {
        /vistest load 0 get /gt eq { %back
            /fill? true def
            /wire? rbool def
        }{ %front
            /fill? false def
            /wire? true def
        } ifelse
    }{ %at least one of wire?,fill?
        true rbool
        rbool { exch } if /fill? exch def /wire? exch def
    } ifelse
    [{} {} {} {} {} {0 setgray} {0 setgray}
    {1 setgray} {1 setgray} {1 setgray}
    {normal light dot 1 add 4 div setgray}
    {normal light dot 1 add 4 div 1 exch sub setgray}
    { 1 currentgray sub setgray }
    { currenthsbcolor exch pop .5 exch sethsbcolor }
    { currenthsbcolor 3 2 roll .33 add dup 1 gt {1 sub} if
        3 1 roll exch pop .5 exch sethsbcolor }
    { currenthsbcolor 1 exch sub sethsbcolor }
    { currentrgbcolor exch 1 exch sub exch setrgbcolor }
    { currenthsbcolor setrgbcolor }
    { currentrgbcolor sethsbcolor }
    { currentrgbcolor 3 1 roll exch setrgbcolor }
    //colorface //colorface //colorface //colorface //colorface
    ] dup
        dup length rand exch mod get /wirecolor exch def
        dup length rand exch mod get /fillcolor exch def
    currentlinewidth .2 rand 6 mod 3 div add mul setlinewidth
    /fudge 1 rand 10 mod 100 div add def
} def

/morerandom? true def
/cage? true def

/axes { %neg:black/white  pos:white/black
    gsave currentlinewidth 2 mul setlinewidth
    -2 0 0 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    2 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke

    0 -2 0 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    0 2 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke

    0 0 -2 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    0 0 2 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke
    grestore
} def

/ang 0 def
{
    /OW ang roty def
    /ang ang 3 add def

    setuppage

    %/fill? true def
    %/wire? true def
    %/wirecolor { 1 currentgray sub setgray } def
    back
    randconfig
    drawsolid

    axes

    %/fill? false def
    %/wire? true def
    %/wirecolor {} def
    %2 setlinewidth
    %currentlinewidth 2 mul setlinewidth
    front
    randconfig
    drawsolid

    pstack flush %cya

    %pause for applause
    500000 { 100 dup cos exch sin exch atan pop } repeat
    showpage
} loop

[toc] | [prev] | [next] | [standalone]


#972 — Revolving Camera prototype

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-23 22:30 -0500
SubjectRevolving Camera prototype
Message-ID<k3ok5b$4e0$1@dont-email.me>
In reply to#970
Here's a silly little scene with a cube, a tetrahedron, and axis lines.
But now, the object stays still and the camera moves around it.

I suppose next I should try to learn how to do Z-buffering.

%!
/olddiv /div load def
/div { dup 0 eq { pop pop 100000 }{ olddiv } ifelse } def
(mat.ps)run

/I3 3 ident def

/disp <<
    /cam [ 0 0 10 ] % Camera position
    /theta [ 0 0 0 ] % Rotation sequence
    /eye [ 0 0 20 ] % Eye relative to image surface
    /Rot I3
>> def

/makerot {
    theta 0 get roty
    theta 1 get rotx matmul
    theta 2 get rotz matmul
} def

% Ax Ay Az
/proj { DICT begin
    %3 array astore
    %dup == flush
    cam {sub}vop %Camera translation
    %pstack()=
    Rot matmul %Camera rotation
    0 get aload pop % Dx Dy Dz
    eye aload pop % Dx Dy Dz Ex Ey Ez
    %pstack()=
    4 3 roll div % Dx Dy Ex Ey Ez/Dz
    exch neg % Dx Dy Ex Ez/Dz -Ey
    4 3 roll add % Dx Ex Ez/Dz Dy-Ey
    1 index mul % Dx Ex Ez/Dz Ez(Dy-Ey)/Dz 
    4 1 roll 3 1 roll % Ez(Dy-Ey)/Dz Ez/Dz Dx Ex 
    sub mul exch % Ez(Dx-Ex)/Dz Ez(Dy-Ey)/Dz  
    %pstack ()=
end } dup 0 disp put def

/L 10 def
/axes {
    [
        [ [ 0 0 L neg ] [ 0 0 L ] ]
        [ [ 0 L neg 0 ] [ 0 L 0 ] ]
        [ [ L neg 0 0 ] [ L 0 0 ] ]
    ] { aload pop proj moveto proj lineto } forall
} def

/v [[  1  1  -1 ] %cube vertices
    [ -1  1  -1 ]
    [ -1 -1  -1 ]
    [  1 -1  -1 ]
    [  1  1   1 ]
    [ -1  1   1 ]
    [ -1 -1   1 ]
    [  1 -1   1 ]] def
/fv [[ 0 1 2 3 ] %cube faces out of vertices
     [ 0 4 5 1 ]
     [ 1 5 6 2 ]
     [ 2 6 7 3 ]
     [ 3 7 4 0 ]
     [ 4 7 6 5 ]
     ] def
/ev [[0 1][1 2][2 3][3 0] %cube edges
     [0 4][1 5][2 6][3 7]
     [4 5][5 6][6 7][7 4]] def
/tv [[ 0 5 7 ] %tetrahedron faces
     [ 0 5 2 ]
     [ 2 5 7 ]
     [ 0 2 7 ]] def

/R 20 def
/H -3 def
/ang 0 def
%stepon
{
    %300 400 translate
    300 700 translate
    1 70 dup dup scale div setlinewidth
    %(1)=

    {
    disp begin
        /cam [
            ang sin R mul
            H 
            ang cos R mul %neg
        ] def
        /theta [
            ang %neg
            %180 add
            H R atan %neg
            0
        ] def
        %2 copy get ang add put
        /Rot makerot def
    end
    } exec%pop

    tv {
        { v exch get proj } forall
        moveto lineto lineto closepath
        1 0 0 setrgbcolor fill 
    } forall

    tv {
        { v exch get proj } forall
        moveto lineto lineto closepath
        0 setgray stroke
    } forall

    {
    ev {
        { v exch get proj } forall
        moveto lineto %lineto lineto closepath
    } forall
        0 1 0 setrgbcolor stroke
    } exec%pop

    axes 0 0 1 setrgbcolor stroke
    /flushpage where { pop flushpage 
        80000 { .2 sin .2 cos atan pop } repeat
    } if
    showpage
    /ang ang 3 add def
} loop

currentfile flushfile
{
[ [1 1 1] [2 2 2] [3 3 3] ]
dup { {add}vop } vop % yay! vop composes!
pstack 
%:r!gsnd -q %
[[2 2 2] [4 4 4] [6 6 6]]
    0 0 0 proj moveto
    1 0 0 proj lineto
    1 1 0 proj lineto
    0 1 0 proj lineto
    closepath
    0 0 1 proj lineto
    1 0 1 proj lineto
    1 0 0 proj lineto
    1 0 1 proj moveto
    1 1 1 proj lineto
    1 1 0 proj lineto
    1 1 1 proj moveto
    0 1 1 proj lineto
    0 1 0 proj lineto
    0 1 1 proj moveto
    0 0 1 proj lineto
} pop

[toc] | [prev] | [next] | [standalone]


#975 — Steinmetz with Revolving Camera

From"luser.droog" <luser.droog@gmail.com>
Date2012-09-24 09:30 -0500
SubjectSteinmetz with Revolving Camera
Message-ID<k3pqqp$f62$1@dont-email.me>
In reply to#972
Finally, a rotating view from a little above without skew distortions.
It's less "imposing", but more accurate.

For some reason I had to reverse the visibility test again (gt <=> lt).


549(0)09:27 AM:ps 0> cat 3d5c.ps
%!
%Steinmetz, take 5: NEEDFORSPEED
% O(N) generator makes caching largely irrelevant!
% Bounded faces makes clipping unnecessary
% (which wasn't quite working somehow)
% Improved visibility now shows the Front of the object!
% Eliminated those ugly artifacts
% Random Configurations (with optional "less-random" mode)
% Revolving Camera removes skew distortions
(mat.ps)run

/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

%Write the vertex array [v1 v2 v3 v4]
%to outfile with embedded drawing command
/writeface {
    out ([) writestring
    [ v1 v2 v3 v4 ]{ % forall vertices
        out ([) writestring
        { % forall coords of vertex
            out exch outbuf cvs writestring
            out ( ) writestring
        } forall
        out ( ) writestring
        out (]) writestring
    } forall
    out (] drawface\n) writestring
    out flushfile
} def

/fudge
1 def
%1.03 def
%Generate the faces of the Forward cylinder
%and eliminate faces outside the chopping cylinders
/steinmetz-gen {
    /N exch def
    /R exch def
    /R^2 R dup mul def
    /h exch def
    /dz 1 N div def
    /dt 360 dz mul def
    /hdz h dz mul def

    0 dt 360 { /t exch def
        %0 dt 180 { /u exch def

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
        ] def
        /t t dt fudge mul add def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt
              R^2 2 index dup mul sub sqrt min
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if
        %face ==

        /v1 [
              R t cos mul %u cos mul
              R t sin mul %u cos mul
              0
              %R^2 2 index dup mul sub sqrt neg
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v2 [ %v1 aload pop neg
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
        ] def
        /t t dt fudge mul sub def
        /v3 [
              R t cos mul
              R t sin mul
              R^2 2 index dup mul sub sqrt neg
              R^2 2 index dup mul sub sqrt neg max
              %R^2 2 index dup mul sub sqrt neg max
              ] def
        /v4 [ %v3 aload pop neg
              R t cos mul
              R t sin mul
              0
        ] def
        /face [ v1 v2 v3 v4 ] def
        %face cylyz checkface {
            doface
        %} if

        %} for
    } for
} def

%Action performed by steinmetz-gen
%on each face that survives the chopping
/doface {
    usecache? {
        writeface
    }{
        face drawface
    } ifelse
} def


%This controls the parameters of the
%wireframe approximation of the cylinder
/genfaces {
   % Generate the faces
   %h R N
    4 2 90 steinmetz-gen
} def



%Default modeling transform
/I3 3 ident def
/MO I3 def % model->object
/model {} def
/OW I3 def % object->world

/fill? true def
/fillcolor {} def
/wire? false def
/wirecolor
%{} def
%{0 setgray} def
%{1 setgray} def
{normal light dot 1 add 4 div
    %1 exch sub
    setgray} def
%Perform modeling transform
%Perform object->world transform
%Perform perspective projection
%Check visibility
    %Fill if fill?
    %Draw Outline if wire?
/drawface { DICT begin % [ v1 v2 v3 v4 ]
    /face exch def
    /action { moveto /action { lineto } def } def

    face { % [ x y z ]
        aload 4 1 roll model 4 3 roll astore
        %MO matmul
        dup OW matmul 0 get exch copy pop
    } forall

    { %exitloop
        face visible not { exit } if
        face {
            aload pop
            proj %X Y
            action
        } forall
        closepath
        colorface fillcolor
        fill? { gsave fill grestore } if
        wire? { gsave wirecolor stroke grestore } if
        /flushpage where { pop flushpage } if
        newpath
    exit } loop
end } dup 0 2 dict put bind def

/E [ 3 3 10 ] def %eye point %Replaced by disp/cam get
/crackE { % set pointers into E
    /ex E 0 1 getinterval cvx def
    /ey E 1 1 getinterval cvx def
    /ez E 2 1 getinterval cvx def
} def crackE
/E^ E dup [ exch mag neg dup dup ] { div } vop def %eye center vec

/vistest { lt } def
%Check visibility from the eye
/visible { % [ v1 v2 v3 v4 ] . bool
    dup
    aload pop /v4 exch def /v3 exch def /v2 exch def /v1 exch def
    %dup 0 get 1 index 2 get 2 index 3 get % [] v1 v2 v4
    %2 index { sub } vop % [] v1 v2 v14
    %3 1 roll exch { sub } vop % [] v14 v12
    %cross
    v1 v4{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    v1 v2{sub}vop
    dup mag 0 eq { pop v1 v3{sub}vop } if
    cross
    /normal exch def %normal ==
    %/normal [ normal mag dup dup ] { div } vop def
    dup 0 get
    %E
    disp /cam get
    { sub } vop % [] ve1
    /ev exch def %ev ==
    ev normal dot %dup =
    0 vistest % [] bool
    exch pop
} def

/light
%[ -7 12 30 ] def
[ 3 2 7 ] def

/colorface {
    %normal light dot 1 add 3 div setgray
    %face 0 get 90 rotz matmul 0 get
    %aload pop pop %exch
    %dup 0 eq { pop .001 } if
    %atan 360 div 3 div
    fn .33 mul %add
    %.5
    face 0 get -90 rotz matmul 0 get
    aload pop pop exch
    dup 0 eq { pop .001 } if
    atan 360 div 2 div .25 add
    normal light dot 1 add 3 div
    3 { 3 1 roll dup 1 gt { pop 1 } if dup 0 lt { pop 0 } if } repeat
    sethsbcolor
} def

{
/proj { DICT begin /z exch def /y exch def /x exch def
    1 ez z sub div
    x ez mul z ex mul sub
    1 index mul
    y ez mul z ey mul sub
    3 2 roll mul
end } dup 0 10 dict put bind def
} pop

/disp <<
    /cam [ 0 0 10 ] % Camera position
    /theta [ 0 0 0 ] % Rotation sequence
    /eye [ 0 0 20 ] % Eye relative to image surface
    /Rot I3
    /Rad 50 def
    /Ht 5 def
>> def

/makerot {
    theta 0 get roty
    theta 1 get rotx matmul
    theta 2 get rotz matmul
} def

% Ax Ay Az
/proj { DICT begin
    3 array astore
    %dup == flush
    cam {sub}vop %Camera translation
    %pstack()=
    Rot matmul %Camera rotation
    0 get aload pop % Dx Dy Dz
    eye aload pop % Dx Dy Dz Ex Ey Ez
    %pstack()=
    4 3 roll div % Dx Dy Ex Ey Ez/Dz
    exch neg % Dx Dy Ex Ez/Dz -Ey
    4 3 roll add % Dx Ex Ez/Dz Dy-Ey
    1 index mul % Dx Ex Ez/Dz Ez(Dy-Ey)/Dz
    4 1 roll 3 1 roll % Ez(Dy-Ey)/Dz Ez/Dz Dx Ex
    sub mul exch % Ez(Dx-Ex)/Dz Ez(Dy-Ey)/Dz
    %pstack ()=
end } dup 0 disp put bind def


/revcam {
    disp begin
        /ang exch def
        /cam [
            ang neg sin Rad mul
            Ht
            ang neg cos Rad mul %neg
        ] def
        /theta [
            ang neg
            %180 add
            Ht Rad atan %neg
            0
        ] def
        %2 copy get ang add put
        /Rot makerot def
    end
} def


/setuppage {
    310 -600 translate
    1 250 dup dup scale div 2 div setlinewidth
    2 setlinejoin
} def

/usecache? false def
usecache? { % Generate Data File to cache the faces
    /data (stein.fac) def
    {
        /in data (r) file def
    } stopped {
        pop pop pop%clear
        /out data (w) file def
        /outbuf 128 string def
        genfaces
        flush out closefile
        /out null def
        /in data (r) file def
    } if
    /reopen { in closefile /in data (r) file def } def
    /drawshape { in cvx exec reopen } def
}{ % Generate fresh data for each shape
    /drawshape { genfaces } def
} ifelse

/up 90 rotx def
/left 90 roty def

/front { /vistest { gt } def } def
/back { /vistest { lt } def } def

/drawsolid {
    /fn 0 def
    /model {} def % x y z -> x y z
    drawshape

    /fn 1 def
    /model { neg exch } def % x y z -> x -z y
    morerandom? { randconfig } if
    drawshape

    /fn 2 def
    /model { neg 3 1 roll exch } def % x y z -> -z y x
    morerandom? { randconfig } if
    drawshape
} def

/rbool { rand 2 mod 0 eq } def

/randconfig {
    cage? {
        /vistest load 0 get /lt eq { %back
            /fill? true def
            /wire? rbool def
        }{ %front
            /fill? false def
            /wire? true def
        } ifelse
    }{ %at least one of wire?,fill?
        true rbool
        rbool { exch } if /fill? exch def /wire? exch def
    } ifelse
    [{} {} {} {} {} %{0 setgray} {0 setgray}
    %{1 setgray} {1 setgray} {1 setgray}
    {normal light dot 1 add 4 div setgray}
    {normal light dot 1 add 4 div 1 exch sub setgray}
    { 1 currentgray sub setgray }
    { currenthsbcolor exch pop .5 exch sethsbcolor }
    { currenthsbcolor 3 2 roll .33 add dup 1 gt {1 sub} if
        3 1 roll exch pop .5 exch sethsbcolor }
    { currenthsbcolor 1 exch sub sethsbcolor }
    { currentrgbcolor exch 1 exch sub exch setrgbcolor }
    { currenthsbcolor setrgbcolor }
    { currentrgbcolor sethsbcolor }
    { currentrgbcolor 3 1 roll exch setrgbcolor }
    //colorface //colorface //colorface //colorface //colorface
    ] dup
        dup length rand exch mod get /wirecolor exch def
        dup length rand exch mod get /fillcolor exch def
    currentlinewidth .2 rand 6 mod 3 div add mul setlinewidth
    /fudge 1 rand 10 mod 100 div add def
} def

/morerandom? false def
/cage? true def

/axes { %neg:black/white  pos:white/black
    gsave currentlinewidth 2 mul setlinewidth
    -2 0 0 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    2 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke

    0 -2 0 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    0 2 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke

    0 0 -2 proj moveto
    0 0 0 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    0 setgray currentpoint stroke moveto
    0 0 2 proj lineto
    gsave currentlinewidth 2 mul setlinewidth stroke grestore
    1 setgray stroke
    grestore
} def

%/randconfig {} /rndcfg /randconfig load def def
%rndcfg
%1536830211 srand
1887638 srand
/ang 0 def
{
    %/OW ang roty def
    ang revcam
    /ang ang 3 add def
    rrand =

    setuppage

    %/fill? true def
    %/wire? true def
    %/wirecolor { 1 currentgray sub setgray } def
    back
    randconfig
    drawsolid

    axes

    %/fill? false def
    %/wire? true def
    %/wirecolor {} def
    %2 setlinewidth
    %currentlinewidth 2 mul setlinewidth
    front
    randconfig
    drawsolid

    pstack flush %cya
    %disp === [ v1 dup == aload pop proj ] ==

    %pause for applause
    500000 { 100 dup cos exch sin exch atan pop } repeat
    showpage
    %exit
} loop

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.postscript


csiph-web