POV-Ray : Newsgroups : povray.advanced-users : Solve edge case: is point inside/on object : Solve edge case: is point inside/on object Server Time
22 Feb 2024 23:52:37 EST (-0500)
  Solve edge case: is point inside/on object  
From: ingo
Date: 26 Dec 2018 07:52:54
Message: <XnsA9C48D36120BCseed7@news.povray.org>
While trying to add movement constraints to the FABRIK IK solvers I ran 
into trouble, best described by the scene with comments below (at least I 
hope so).

I'm looking for a solution that is 100% safe in detecting whether a point 
is outside an object. I want to count exactly on the surface as inside.

ingo

---%<------%<-------%<---

#version 3.7;
#include "rand.inc"

#global_settings{assumed_gamma 1.0 }
#default{pigment{rgb 1} finish{ ambient 0.2 diffuse 0.9 }} 
light_source{<1000,1000,-1000>, rgb 1}
camera{location <0,1.5,-2> look_at <0,0.5,0>}

// Create an ObjectOfConstraint. A bone should stay within this object
// The object is always enclosed within a unit sphere.
#declare C = object{
  intersection {
    sphere {0,1}
    cone{<0,0,0>,0,<0,1,0>,0.5}
  }
};


// To create the edge case:
// Creat a point A (green) somewhere on a unit sphere.

// inside but not seen as such, needs the oject to scaled up a bit
//#declare A = vrotate(<0,1,0>,<0,0,1>); 

//fails on all tries
// #declare A = vrotate(<0,1,0>,<0,0,-90>);
//ok on last trial
 #declare A = vrotate(<0,1,0>,<0,0,-90.01>);

//#declare Stream = seed(7);
//#declare A = VRand_On_Sphere(Stream);

// Create a TraceTarget (red), the 'centre piece' of our 
ObjectOfConstraint.
#declare TT = <0,1,0>;
// Now trace from A to TT. Normalise the found intersection point (yellow)
// so it will end up exactly on the rim of the sphere-cone intersection
// (cyan sphere). 
#declare Norm = <0,0,0>;
#declare Inter1 = trace(C, A, TT-A, Norm);
#debug "Trace A\n"
#debug concat("Norm : ", vstr(3,Norm,",",3,3),"\n")
#debug concat("Inter: ", vstr(3,Inter1,",",3,3),"\n")
#declare Np = vnormalize(Inter1);
#debug concat("NP : ", vstr(3,Np,",",3,3),"\n")

// Now we can't check whether NP is inside the ObjectOfConstraint,
// it is exactly on the surface, so neither in or out. Yet I'd like
// to count it as 'inside', so more testing.
#declare Inside = inside(C,Np);
#debug concat("\n===>> Inside : ",str(Inside,3,3),"\n\n")

#if(!Inside)
  // Lets scale the cone
  #declare C_s = object{C scale 1.0001} //object{C scale 2}
  #declare Inside = inside(C_s,Np);
  #debug concat("\n===>> Inside C_s: ",str(Inside,3,3),"\n\n")
  // No result as Np stays exactly on the surface, uncomment C_s below.
  // Cannot change te radius of the cone a bit as the ObjectOfConstraint
  // can be something else than a cone.
  
  // What can be done with trace?
  #declare Norm = <0,0,0>;
  #declare C = object{C}; //object{C scale 1.0001}; //object{C scale 
0.9999};
  #declare Inter2 = trace(C, TT, TT-Np, Norm);
  #debug "Trace NP 2 : \n"
  #debug concat("Norm : ", vstr(3,Norm,",",3,3),"\n")
  #debug concat("Inter2: ", vstr(3,Inter2,",",3,3),"\n")
  // Just a trace form Np to TT results in nothing, no hit
  // scale up a bit results in the intersection point being TT
  // scale down a bit results in the intersection point being close to Np 
  //
  // Is this always the case?
  //
  // Fiddling with the position of A has shown there are situations where
  // it does not work. Coincident surface like problems? Scaling should 
  // not matter as Np is and stays exactly on the surface as seen with the
  // inside test.
  
  // Trace in opposite direction: nope
  #declare Inter3 = trace(C, Np, Np-TT, Norm);
  #debug "\nTrace NP 3 : \n"
  #debug concat("Norm : ", vstr(3,Norm,",",3,3),"\n")
  #debug concat("Inter3: ", vstr(3,Inter3,",",3,3),"\n")
  
  
  // Lets trace from a slightly different position. Extend TT to Np a bit.
  // The resulting intersection should be equal to Np
  
  #local NPn = Np+(vnormalize((Np-TT))*0.1);
  sphere {NPn 0.031}
  #declare Inter4 = trace(C, NPn, TT-NPn, Norm);
  #debug "\nTrace NPn : \n"
  #debug concat("Norm : ", vstr(3,Norm,",",3,3),"\n")
  #debug concat("Inter4: ", vstr(3,Inter4,",",3,3),"\n")
  // No result??? Because it exactly hits the rim???
  
  // Trace in opposite direction?
  #declare Inter5 = trace(C, TT, NPn-TT, Norm);
  #debug "\nTrace NPn : \n"
  #debug concat("Norm : ", vstr(3,Norm,",",3,3),"\n")
  #debug concat("Inter5: ", vstr(3,Inter5,",",3,3),"\n")
  // Seems to work ...? Not!
  
  object {C pigment {rgbf 0.6}}
  //object {C_s pigment {rgbf 0.9}}
  sphere {A 0.03 pigment{rgb y}}
  sphere {TT 0.03 pigment{rgb x}}
  sphere {Inter1 0.031 pigment{rgb x+y}}
  sphere {Inter2 0.031 pigment{rgb x+y}}
  sphere {Inter3 0.031 pigment{rgb x+y}}
  sphere {Inter4 0.031 pigment{rgb x+y}}
  sphere {Inter5 0.031 pigment{rgb x+y}}
  sphere {Np 0.03 pigment{rgb y+z}}
  cylinder {A, TT, 0.02}
  cylinder {Np, TT, 0.02}
#end


Post a reply to this message

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