POV-Ray : Newsgroups : povray.general : Need math help : Re: Need math help Server Time
10 Aug 2024 03:16:30 EDT (-0400)
  Re: Need math help  
From: Tor Olav Kristensen
Date: 9 Mar 2000 15:57:31
Message: <38C80F21.14B82B67@hotmail.com>
Hi  Sebastian

I like problems like the one you presented here, so I have tried
to do some thinking.

I have not seen John VanSickle's Connect macro, but I think that
I understand your problem anyway. I have tried to figure it out by
examining your variable names:

(I did however not understand your description of what the problem
with your macro was.)

Correct me if I'm wrong:

You have two toruses that are parallel to each other.
The centres of these are at two given locations (some distance apart).
And you want to connect the "outsides" of these with a cone.

So if I this is your problem, then I have a suggestion for a solution.
Se my POV-ray file below.

(I have tried to make it easy to understand, and because of this it
became quite long. Abut about half of it can be removed if you don't
need my comments, debug macros and objects)

I have tried to solve the problem with vector math.
My solution is not perfect, because if the centres of both your toruses
lies on a line through origo, then my solution will not work.
(If I have time I'll might try to remove this weakness.)

(And because I didn't understand what the problem with your macro
was, I don't know if my macro is any better than yours.)


Regards,

Tor Olav Kristensen

mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Sebastian Strand wrote:

> I've been trying to create a macro that would seamlessly connect two
> toruses, just like John VanSickle's Connect macro does for spheres. I can't
> seem to get it right, however, so I'd be very grateful if someone with more
> math skills than me could help me.
>
> Here's something to work with:
> #macro TorusConnect(SP,SMaR,SMiR,EP,EMaR,EMiR)
>   #local D=vlength(EP-SP);
>
>   #local Rd=(SMaR+SMiR)-(EMaR+EMiR);
>   #local D2=sqrt(D*D-Rd*Rd);
>
>   cone { SP+(EP-SP)/D*(SMiR-EMiR)*(SMaR+SMiR)/D, (SMaR+SMiR)*D2/D,
> EP+(EP-SP)/D*(SMiR-EMiR)*(SMaR+SMiR)/D, (EMaR+EMiR)*D2/D }
> #end
>
> This, obviously, doesn't work but it does come quite close; it just leaves a
> tiny edge at the connection point.
>







// =============================================================
//
// Connecting two torus-"outsides" with a cone
//
// Copyright 2000 by Tor Olav Kristensen
//
// =============================================================

#version 3.1;

#include "colors.inc"

// =============================================================

// Some useful constants

#declare Origo = <0, 0, 0>;
#declare Nullv = <0, 0, 0>;
#declare Unitv = <1, 1, 1>;

// =============================================================
// Just some of my macros

/* // Remove this line for debugging

#macro vCos(UU, VV)
// Returns cosinus of the angle between two vectors

  (vdot(UU, VV)/(vlength(UU)*vlength(VV)))

#end // macro vCos


#macro vangle(UU, VV)
// Returns the angle in radians between two vectors
// 0 <= returned angle < pi

  acos(vCos(UU, VV))

#end // macro vangle


#macro VectorAngles(Vector)
// Returns two angles.
// The first is the angle between Vector and the Y-axis
// The second is the angle between the projection
// of Vector to the XZ-plane and the X-axis

  #local VAngles = Nullv;
  #if (vlength(Vector) > 0)
    #local VAngles = y*vangle(Vector, y);
    #if (VAngles.y > 0)
      #local Sign = 1;
      #if (Vector.z < 0)
        #local Sign = -1;
      #end
      #local VAngles = VAngles + Sign*x*vangle(Vector*(x+z), x);
    #end
  #end // if

  VAngles

#end // macro VectorAngles


#macro vtilt(Thing, TVector)
// Returns the object Thing "tilted" in the
// direction of TiltVector

  #local RotateAngles = VectorAngles(TVector);

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

#end // macro vtilt

*/ // Remove this line for debugging


#macro vproject(UU, VV)
// Projection of the vector UU in the direction
// of the vector VV.

  ((VV)*vdot(UU, VV)/vdot(VV, VV))

#end // macro vproject


#macro TorusConnect(SP, SMaR, SMiR, EP, EMaR, EMiR)
// SP: S Point (Center of one torus)
// SMaR: S Major Radius
// SMiR: S Minor Radius
// EP: E Point (Center of other torus)
// EMaR: E Major Radius
// EMiR: E Minor Radius
// And suffixes; v: Vector, p: Point, R: Radius
// Note: Origo, SP and EP may not be colinear

  #local Upv = vcross(EP, SP);

  #local Dv = EP - SP;
  #local Outv = vnormalize(vcross(Dv, Upv));

  #local SMaRv = SMaR*Outv;
  #local EMaRv = EMaR*Outv;

  #local SMaRp = SP + SMaRv;
  #local EMaRp = EP + EMaRv;

  #local Slopev = EMaRp - SMaRp;
  #local SlopeNv = vnormalize(vcross(Slopev, Upv));

  #local SMiRv = SMiR*SlopeNv;
  #local EMiRv = EMiR*SlopeNv;

  #local SMiRp = SMaRp + SMiRv;
  #local EMiRp = EMaRp + EMiRv;

  #local EndSp = SP + vproject(SMiRv, Dv);
  #local EndEp = EP + vproject(EMiRv, Dv);

  #local EndSR = vlength(SMiRp - EndSp);
  #local EndER = vlength(EMiRp - EndEp);

/* // Remove this line for debugging
  #local sr = 0.3;
  #local Storus = torus { SMaR, SMiR }
  #local Etorus = torus { EMaR, EMiR }
  #local Storus = object { vtilt(Storus, Dv) translate SP }
  #local Etorus = object { vtilt(Etorus, Dv) translate EP }

  union {
    sphere { SP   , sr }
    sphere { SMaRp, sr }
    sphere { SMiRp, sr }
    sphere { EndSp, sr }
    object { Storus }
    sphere { EP   , sr }
    sphere { EMaRp, sr }
    sphere { EMiRp, sr }
    sphere { EndEp, sr }
    object { Etorus }
*/ // Remove this line for debugging
    cone { EndSp, EndSR, EndEp, EndER }
/* // Remove this line for debugging
  }
*/ // Remove this line for debugging

#end


#declare CenterPoint1 = <1, 4, 2>;
#declare MajorRadius1 = 5;
#declare MinorRadius1 = 0.5;

#declare CenterPoint2 = <2, 0, 3>;
#declare MajorRadius2 = 2;
#declare MinorRadius2 = 1;


object {
  TorusConnect(CenterPoint1, MajorRadius1, MinorRadius1,
               CenterPoint2, MajorRadius2, MinorRadius2)
  pigment { color Yellow }
}


#declare PlaneNormal = vnormalize(vcross(CenterPoint1, CenterPoint2));

/* // Remove this line for debugging
plane { PlaneNormal, 0 pigment { color White } }
*/ // Remove this line for debugging

// =============================================================

background { color Grey }

light_source { 1000*PlaneNormal, White }

camera {
  location 15*PlaneNormal
  look_at Origo
}

// =============================================================


Post a reply to this message

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