Post by inventordave on Dec 9, 2019 23:25:41 GMT
I have implemented the cone code (local_intersect and local_normal_at), and run a test with the following setup:
I get the following image:
Er.... doesn't look right. (I haven't added an attempt to truncate into a unit cone as suggested on page 191 - my last test was the test on p189, which was successful). So, I decided to add the following transformation to get a better look:
When cone1.closed is set to the default, false, I get this:
Again, doesn't look right. When I set
It is clearly broken. Here is my cone constructor function:
I followed the instructions for modifying the cylinder code, which according to my tests, and sample scene, works just fine. What am I doing wrong in my implementation of either
var cone1 = cone()
//cone1.closed = true
cone1.max = 2.5;
cone1.min = 0.5;
cone1.transform = scaling(0.5, 0.5, 0.5)
cone1.material = new material();
cone1.material.color = colour(0.5, 1, 0.1);
cone1.material.diffuse = 0.7;
cone1.material.specular = 0.5;
cone1.material.reflective = 0;
I get the following image:
Er.... doesn't look right. (I haven't added an attempt to truncate into a unit cone as suggested on page 191 - my last test was the test on p189, which was successful). So, I decided to add the following transformation to get a better look:
cone1.transform = m_multiply(m_multiply(rotation_x(0.5,0.5,0.5), rotation_y(0.25,0.25,0.25)), scaling(0.5, 0.5, 0.5))
When cone1.closed is set to the default, false, I get this:
Again, doesn't look right. When I set
cone1.closed = true
I get this:It is clearly broken. Here is my cone constructor function:
function cone(id2) {
var c = new Shape("cone", id2)
c.min = -Infinity
c.max = Infinity
c.closed = false
c.local_intersect = function(r) { // r is a local_ray
var xs = []
var t;
var a = (r.direction.x ** 2) - (r.direction.y ** 2) + (r.direction.z ** 2)
var b = (2 * r.origin.x * r.direction.x) - (2 * r.origin.y * r.direction.y) + (2 * r.origin.z * r.direction.z)
var c = (r.origin.x ** 2) - (r.origin.y ** 2) + (r.origin.z ** 2)
if ((Math.abs(a) < EPSILON) && (Math.abs(b)< EPSILON))
return []
if (Math.abs(a) < EPSILON) {
t = (-c)/(b*2)
xs.push(new intersection(this, t))
}
else {
var disc = (b*b) - (4 * a * c)
// ray does not intersect with cone
if (disc < 0)
return []
var t0 = (-b - Math.sqrt(disc)) / (2*a)
var t1 = (-b + Math.sqrt(disc)) / (2*a)
var temp;
if (t0 > t1) {
temp = t1;
t1 = t0;
t0 = temp;
}
var y0 = r.origin.y + (t0 * r.direction.y)
if(this.min<y0 && this.max>y0)
xs.push(new intersection(this,t0))
var y1 = r.origin.y + (t1 * r.direction.y)
if(this.min<y1 && this.max>y1)
xs.push(new intersection(this,t1))
}
// inline intersect_caps(...) with inline check_cap(...)
if(this.closed && (Math.abs(r.direction.y) >= EPSILON)) {
t = (this.min - r.origin.y) / r.direction.y
var x = r.origin.x + t * r.direction.x
var z = r.origin.z + t * r.direction.z
if ((x**2 + z**2) <= this.min)
xs.push(new intersection(this,t))
t = (this.max - r.origin.y) / r.direction.y
x = r.origin.x + t * r.direction.x
z = r.origin.z + t * r.direction.z
if ((x**2 + z**2) <= this.max)
xs.push(new intersection(this,t))
}
xs = order(xs)
return xs
};
c.local_normal_at = function(p) {
var dist = p.x**2 + p.z**2
if ((dist < 1) && (p.y >= (this.max - EPSILON)))
return vector(0,1,0)
if ((dist < 1) && (p.y <= (this.min + EPSILON)))
return vector(0,-1,0)
var y = Math.sqrt((p.x**2) + (p.z**2))
if (p.y > 0)
y = -y
return vector(p.x, y, p.z)
};
return c
}
I followed the instructions for modifying the cylinder code, which according to my tests, and sample scene, works just fine. What am I doing wrong in my implementation of either
cone.local_intersect(...)
or cone.local_normal_at(...)
....??