POV-Ray : Newsgroups : povray.binaries.images : Playing with CSG (44 KB) : Re: Playing with CSG (44 KB) Server Time
19 Apr 2024 06:29:31 EDT (-0400)
  Re: Playing with CSG (44 KB)  
From: Tor Olav Kristensen
Date: 17 Apr 2000 20:12:43
Message: <38FBA73C.2E5AD31D@online.no>
Geoffrey Potvin wrote:

> Do you have some part of this macro posted on your website etc. ...

This is "Work in progress" so I have not published it yet.

But I have enclosed the macro that I have made so far below in case you
are really interested. (All the other macros below are used by this one.)
It's named "BetweenToruses"


> or does
> it  have to be written specifically and exclusively for each CSG generated
> object that your are trying to create?

I'm not trying to make a macro that solves this problem for every possible
complex CSG operation! And I am sorry if I mislead anyone to belive this.

My macro(s) will provide the extra "material" to be taken away or added
in a CSG operation between two primitives to make the transistion smoother.

But before the macro can do this it needs some numerical information about
the chosen primitives.

I have chosen a subset of POV-Rays shape primitives.
And then I'm trying to make macros to make smooth transitions between
these primitives with cylinders and toruses.

But even with this subset I have to restrict the number of possible ways
the primitives can "meet" each other.

This is partly because there are some other primitives "missing" in POV-Ray.
(Maybe I will look into the possibility to generate these primitives with
Quartics later.)

My goal is to end up with 1, 3 or 4 macros that the end users needs to make
calls to. (Of coarse there are other macros below that the end user doesn't
"see".)


> I don't know if you've seen it, but I
> ran into such problems with my "old typewriter" model (recently posted
> image) ...I cheated by leaving a lot of objects with sharp edges ...or tried
> to fake it with a few bezier patches and super quadrics here and there.

I noticed your nice paper feed handle and the screw heads.

But as you mentioned the image is rendered without antialiasing and
therefore I found it hard to see all the other details.


> Obviously, your macro would eliminate all these issues. I would be very
> interested  to know how you have achieved this!

I'm afraid I have not eliminated all these issues!      =(

If you look into my answer to David Wilkinson 18. April you will find
my attempt to explain what I'm doing.

There are also two extra images to clarify.

Regards,

Tor Olav
---

I'm sorry that these macros are not documented.
(I'm not good at finding descriptive names for my
variables or macros either.)

And I'm afraid that this makes them rather cryptic.

The macro; BetweenToruses was the only one that I made
calls to in order to make the "wheel" picture.

// ================================================
// (C) 2000 by Tor Olav Kristensen
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
// ================================================

#macro VectorAngles(Vector)

  <acos(vnormalize((x+z)*Vector).x)*(Vector.z < 0 ? -1 : 1),
   acos(vnormalize(Vector).y),
   0>

#end // macro VectorAngles


#macro vtilt(Thing, TVector)

  #local RotateAngles = VectorAngles(TVector);

  object {
    Thing
    rotate  degrees(RotateAngles.x)*y
    rotate -degrees(RotateAngles.y)*z
    rotate -degrees(RotateAngles.x)*y
  }

#end // macro vtilt


#macro Pythagoras(hyp, kat)

 sqrt(hyp*hyp - kat*kat)

#end // macro Pythagoras


#macro Cosinus(aa, bb, cc)

  ((aa*aa + bb*bb - cc*cc)/(2*aa*bb))

#end // macro Cosinus


#macro vCosSin(aa, bb, cc)

  #local Cos = (aa*aa + bb*bb - cc*cc)/(2*aa*bb);
  #local Sin = sqrt(1 - Cos*Cos);

  <Cos, Sin>

#end // macro vCosSin


#macro ExCircle(aa, bb, cc)

  #local vCS = vCosSin(aa, bb, cc);

  (<aa, bb*vCS.y + vCS.x/vCS.y*(vCS.x*bb - aa)>/2)

#end // macro ExCircle


#macro CirclesTouch(Type, R1, R2, R3, Dist, CirIntSct, Ctr3, TouchPt13,
TouchPt23, Ctr45, Rad45)

  #switch (Type)

    #case (1)
      #local Ra = R1 + R3;
      #local Rc = R2 + R3;
    #break // case

    #case (2)
      #local Ra = R1 - R3;
      #local Rc = R2 - R3;
    #break // case

    #case (3)
      #local Ra = R1 + R3;
      #local Rc = R2 - R3;
    #break // case

    #case (4)
      #local Ra = R1 - R3;
      #local Rc = R2 + R3;
    #break // case

    #else
      #debug "Macro CirclesTouch: Wrong Type number given."

  #end // switch Type

  #local vABC = vCosSin(Ra, Dist, Rc);
  #local vRBR = vCosSin(R1, Dist, R2);

//#local Ctr1 = <0, 0>;
  #local Ctr2 = <Dist, 0>;

  #declare Ctr3 = Ra*vABC;
  #declare CirIntSct = R1*vRBR;
  #declare TouchPt13 = R1*vABC;
  #declare TouchPt23 = Ctr2 + R2/Rc*(Ctr3 - Ctr2);

  #local sDir = ExCircle(vlength(CirIntSct - TouchPt13),
                         vlength(TouchPt23 - CirIntSct),
                         vlength(TouchPt13 - TouchPt23));
  #local MidPt = (TouchPt13 + CirIntSct)/2;
  #local vCtr = vnormalize(<vABC.y, -vABC.x > - <vRBR.y, -vRBR.x>)*sDir.y;

  #switch (Type)

    #range (1, 2)
      #declare Ctr45 = MidPt + vCtr;
    #break // range

    #range (3, 4)
      #declare Ctr45 = MidPt - vCtr;
    #break // range

    #else
      #debug "Macro CirclesTouch: Wrong Type number given."

  #end // switch Type

  #declare Rad45 = vlength(sDir);

#end // macro CirclesTouch


#macro v2D3D(v2D, vBas1, vBas2)

  (v2D.x*vBas1 + v2D.y*vBas2)

#end // macro v2D3D


#macro CSGselect(Type, MnThing1, MnThing2, MtThing, SmThing)

  intersection {

    object { MtThing }
    object { SmThing  inverse }

    #switch (Type)
      #case (1)
        object { MnThing1 inverse }
        object { MnThing2 inverse }
      #break // case

      #case (2)
        object { MnThing1 }
        object { MnThing2 }
      #break // case

      #case (3)
        object { MnThing1 inverse }
        object { MnThing2 }
      #break // case

      #case (4)
        object { MnThing1 }
        object { MnThing2 inverse }
      #break // case

      #else
        #debug "Macro CSGselect: Wrong Type number given."
    #end // switch Type

  }

#end // macro CSGselect


#macro BetweenToruses(Type, v3TCtr1, v3TCtr2,
                      R1b, R2b, R1s, R2s, R3s,
                      v3Ctr3_a, v3Ctr3_b, R3b_a, R3b_b,
                      oBetwO, oBetwI)

  #local v3Diff = v3TCtr2 - v3TCtr1; // v3Ts
  #local sTs = vlength(v3Diff); // sTs
  #local rDiff = R2b - R1b; // sD
  #local v2TT = <sTs, rDiff>;
  #local Distance = vlength(v2TT);

  #local v3Forw = vnormalize(v3Diff);

  #local v2Isect  = <0, 0>;
  #local v2Ctr3   = <0, 0>;
  #local v2Touch1 = <0, 0>;
  #local v2Touch2 = <0, 0>;
  #local v2CtrA   = <0, 0>;
  #local RadA     = 0;

  CirclesTouch(Type, R1s, R2s, R3s, Distance, v2Isect, v2Ctr3, v2Touch1,
v2Touch2, v2CtrA, RadA)

  #local v2Forw = vnormalize(v2TT);
  #local v2Side = <-v2Forw.y, v2Forw.x>;

  #declare v2Ctr3_a = v2D3D(v2Ctr3, v2Forw,  v2Side);
  #declare v2Ctr3_b = v2D3D(v2Ctr3, v2Forw, -v2Side);

  #local   v2CtrM_a = v2D3D(v2CtrA, v2Forw,  v2Side);
  #local   v2CtrM_b = v2D3D(v2CtrA, v2Forw, -v2Side);

  #local Obj1 =
  object {
    vtilt(torus { R1b, R1s }, v3Forw)
    translate v3TCtr1
  }

  #local Obj2 =
  object {
    vtilt(torus { R2b, R2s }, v3Forw)
    translate v3TCtr2
  }

  #local   v3CtrM_a = v3TCtr1 + v2D3D(v2CtrM_a, v3Forw, vNull);
  #local   v3CtrM_b = v3TCtr1 + v2D3D(v2CtrM_b, v3Forw, vNull);
  #local   RMb_a = R1b + v2CtrM_a.y;
  #local   RMb_b = R1b + v2CtrM_b.y;

  #declare v3Ctr3_a = v3TCtr1 + v2D3D(v2Ctr3_a, v3Forw,  vNull);
  #declare v3Ctr3_b = v3TCtr1 + v2D3D(v2Ctr3_b, v3Forw,  vNull);
  #declare R3b_a = R1b + v2Ctr3_a.y;
  #declare R3b_b = R1b + v2Ctr3_b.y;

  #local ObjM_a =
  object {
    vtilt(torus { RMb_a, RadA }, v3Forw)
    translate v3CtrM_a
  }

  #local Obj3_a =
  object {
    vtilt(torus { R3b_a, R3s  }, v3Forw)
    translate v3Ctr3_a
  }

  #local ObjM_b =
  object {
    vtilt(torus { RMb_b, RadA }, v3Forw)
    translate v3CtrM_b
  }

  #local Obj3_b =
  object {
    vtilt(torus { R3b_b, R3s  }, v3Forw)
    translate v3Ctr3_b
  }

  #declare oBetwO =
    CSGselect(Type, Obj1, Obj2, ObjM_a, Obj3_a)

  #declare oBetwI =
    CSGselect(Type, Obj1, Obj2, ObjM_b, Obj3_b)

#end // macro BetweenToruses


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.