Repository: three.js
Issue: Raycaster: Floating point tolerance
Labels: Bug

##### Description of the problem 

When casting a ray with Raycaster, it happens under some conditions in my test example that the caster fails to detect the object on top of it.

In the test example, when casting UP from one (or multiple) vertices of the rectangular block top, it does not detect the sphere above.

When varying the "influence" parameter, one can see the points that failed to being detected, as they are not morphed to match the sphere shape.

The error can be reproduced if the sphere is 70 unit of radius. However, if the radius is set to 100 units, then there are no errors.

```js
var sphereGeo = new THREE.SphereGeometry(70); // if 100, no issue
```

Also, if the tessalation of the block is changed, by dividing the edges by 10 points per edge instead of 15, then the issue appears twice!

```js
var geometry = new THREE.BoxGeometry(200, 100, 200, 15, 1, 15); // Change to 10, 1, 10 for double trouble!
```

##### Three.js version
- [x] r85

##### Browser
- [x] Chrome

##### OS
- [x] Windows 10

##### Hardware Requirements (graphics card, VR Device, ...)
None observed.

[CODE]
<body>
	<div id="container"></div>
	<div id="info">
		<a href="http://threejs.org" target="_blank">three.js</a> - Morph by Raycasting
	</div>

	<script src="three.js"></script>

	<script src="OrbitControls.js"></script>
	<script src="Detector.js"></script>
	<script src="dat.gui.min.js"></script>

	<script>
		if (!Detector.webgl) Detector.addGetWebGLMessage();

		var container;

		var camera, scene, renderer;

		var mesh;
		var morphMesh;
		var sphere;

		init();
		animate();

		function init() {

			container = document.getElementById('container');

			camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 15000);
			camera.position.z = 500;

			scene = new THREE.Scene();

			var light = new THREE.PointLight(0xff2200);
			light.position.set(100, 100, 100);
			scene.add(light);

			var light = new THREE.AmbientLight(0x111111);
			scene.add(light);

			//

			var geometry = new THREE.BoxGeometry(200, 100, 200, 15, 1, 15);
			var material = new THREE.MeshLambertMaterial({ color: 0xffffff, 
														   morphTargets: true ,
														   wireframe: true});

			var sphereGeo = new THREE.SphereGeometry(70);
			var sphereMat = new THREE.MeshPhongMaterial({ color: 0xff00ff, morphTargets: false });

			var morphGeo = geometry.clone();
			var morphMat = new THREE.MeshLambertMaterial({ color: 0xff00ff, morphTargets: false});

			{
				var vertices = [];

				for (var v = 0; v < morphGeo.vertices.length; v++) {
					vertices.push(morphGeo.vertices[v]);
				}

				geometry.morphTargets.push({ name: "sphere", vertices: vertices });
			}

			mesh = new THREE.Mesh(geometry, material);
			morphMesh = new THREE.Mesh(morphGeo, morphMat);
			sphere = new THREE.Mesh(sphereGeo, sphereMat);
			sphere.geometry.translate(0, 200, 0);

			mesh.geometry.morphTargets.push({name: "morphed", vertices: morphMesh.geometry.vertices});

			scene.add(mesh);
			scene.add(sphere);

			//

			findIntersection(mesh.geometry, sphere);

			//

			var params = {
				influence1: 0,
			};

			var gui = new dat.GUI();

			var folder = gui.addFolder('Morph Targets');
			folder.add(params, 'influence1', 0, 1).step(0.01).onChange(function (value) { mesh.morphTargetInfluences[0] = value; });
			folder.open();

			//

			renderer = new THREE.WebGLRenderer();
			renderer.setClearColor(0x222222);
			renderer.setPixelRatio(window.devicePixelRatio);
			renderer.setSize(window.innerWidth, window.innerHeight);
			renderer.sortObjects = false;
			container.appendChild(renderer.domElement);

			//

			controls = new THREE.OrbitControls(camera, renderer.domElement);

			//

			window.addEventListener('resize', onWindowResize, false);

		}

		function findIntersection(baseGeo, targetMesh) {

		    var rayCaster = new THREE.Raycaster();
		    var UP = new THREE.Vector3(0, 1, 0);

			var counter = 0;

			for (var v = 0; v < baseGeo.vertices.length; v++)
			{
				
				var vertex = baseGeo.vertices[v]; 

				// Reduce computation by only looking for top vertices
				if (vertex.y > 0)
				{
					rayCaster.set(vertex, UP);

					var intersects = rayCaster.intersectObject(targetMesh);

					if (intersects.length > 0)
					{

						// Distance is hardcoded, but delta could be calculated
						// relative to a target bounding box
						var delta = 150 - intersects[0].distance;

						morphMesh.geometry.vertices[v].y -= delta;
					}
				}
			}
		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize(window.innerWidth, window.innerHeight);

		}

		function animate() {

			requestAnimationFrame(animate);
			render();

		}

		function render() {

			renderer.render(scene, camera);

		}
	</script>

</body>

</html>