POV-Ray : Newsgroups : povray.advanced-users : Solve edge case: is point inside/on object : Solve edge case: is point inside/on object Server Time22 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:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#XnsA9C48D36120BCseed7%40news.povray.org",
"headline": "Solve edge case: is point inside\/on object",
"dateCreated": "2018-12-26T12:52:54+00:00",
"datePublished": "2018-12-26T12:52:54+00:00",
"author": {
"@type": "Person",
"name": "ingo"
}
}
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
```