Orientation of 3 vertices on GUI - javascript

I am trying to find the orientation of 3 ordered points in space. I am using the algorithm that I found from this site. https://www.geeksforgeeks.org/orientation-3-ordered-points/
I want to print out the orientation updated on GUI whether it is Clockwise or CounterClockwise when I play with coordinates by slider.
You can view what I did so far in below fiddle.
https://jsfiddle.net/ewLkta45/48/
So to implement this, I added this function.
function findOrientation(){
var Orientation;
var x1=geometry.vertices[0].x;
var y1=geometry.vertices[0].y;
var x2=geometry.vertices[1].x;
var y2=geometry.vertices[1].y;
var x3=geometry.vertices[2].x;
var y3=geometry.vertices[2].y;
Orientation=(y2 - y1)*(x3 - x2) - (y3 - y2)*(x2 - x1);
}
But I do not know how to refresh a text controller. My question is how can I display orientation as CW or CCW on temp controller whenever I move slider?

You can use .listen() of a controller to display changes of its value:
var camera, scene, renderer;
var geometry, material, mesh;
var controller;
var orientation = {
value: 'Sam'
};
init();
animate();
function findOrientation() {
let Orientation = 0;
var x1 = geometry.vertices[0].x;
var y1 = geometry.vertices[0].y;
var x2 = geometry.vertices[1].x;
var y2 = geometry.vertices[1].y;
var x3 = geometry.vertices[2].x;
var y3 = geometry.vertices[2].y;
Orientation = (y2 - y1) * (x3 - x2) - (y3 - y2) * (x2 - x1);
return Orientation;
}
function addDatGui() {
var gui = new dat.GUI();
gui.add(geometry.vertices[0], 'x').name("v1.x").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(geometry.vertices[0], 'y').name("v1.y").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(geometry.vertices[1], 'x').name("v2.x").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(geometry.vertices[1], 'y').name("v2.y").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(geometry.vertices[2], 'x').name("v3.x").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(geometry.vertices[2], 'y').name("v3.y").min(-800).max(800).step(5).onChange(onFinishChange);
gui.add(orientation, 'value').name("orientation").listen();
}
function onFinishChange() {
if (findOrientation() < 0) {
orientation.value = 'CW';
} else {
orientation.value = 'CCW';
}
}
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
scene = new THREE.Scene();
geometry = new THREE.Geometry();
geometry.vertices = [
new THREE.Vector3(-94, -200, 0),
new THREE.Vector3(92, 68, 0),
new THREE.Vector3(-105, 180, 0)
];
geometry.faces = [new THREE.Face3(0, 1, 2)];
mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
color: 0xffff00,
side: THREE.DoubleSide,
wireframe: true
}));
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
addDatGui();
}
function animate() {
requestAnimationFrame(animate);
//mesh.rotation.y += 0.09;
mesh.geometry.verticesNeedUpdate = true;
//if(resultOfOrientation<0) text.val='cw';
// else text.val='wc';
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.3/dat.gui.min.js"></script>

I think dat.GUI is a interface for changing variables not for showing variables, there are many other ways to show the text, e.g. <a>,<p> HTML tag.
You can listen events on dat.GUI controllers:
gui.add(geometry.vertices[0], 'x').name("v1.x").min(-800).max(800).step(5).onChange(function() {
var text = document.getElementById('text');
if (findOrientation() < 0) text.innerHTML = 'The orientation of points : CW';
else text.innerHTML = 'The orientation of points : CCW';
});
Here is my example.

Related

Using .intersect/.intersectsBox for object collision threeJS

Hi I am working on a basic breakout/arkanoid game in threeJS. Right now all I have is a paddle and a ball that bounces around the screen. I am trying to get collision working so that when the ball hits the paddle it bounces away. I've been trying to using bounding boxes to accomplish this however I am running into an issue where the .intersect/.intersectsBox are not properly registering an intersection and I don't know why. Below is the code I have so far -
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry(5, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
var cubeBoxHelper = new THREE.BoxHelper(cube, 0xff0000);
var boundingBoxPaddle = new THREE.Box3().setFromObject(cubeBoxHelper);
cubeBoxHelper.update();
const geometrySphere = new THREE.SphereGeometry(1, 32, 32);
const materialSphere = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const sphere = new THREE.Mesh(geometrySphere, materialSphere);
var sphereBoxHelper = new THREE.BoxHelper(sphere, 0xff0000);
var boundingBoxBall = new THREE.Box3().setFromObject(sphereBoxHelper);
sphereBoxHelper.update();
scene.add(cube, cubeBoxHelper, sphere, sphereBoxHelper);
sphere.position.y = 5;
camera.position.z = 15;
camera.position.y = 10;
var xSpeed = 0.0005;
var dx = 0.1;
var dy = 0.1;
function bounce()
{
if (sphere.position.x < -19 || sphere.position.x > 18.5)
{
dx = -dx;
}
if (sphere.position.y < -5 || sphere.position.y > 19)
{
dy = -dy;
}
sphere.position.x += dx;
sphere.position.y += dy;
sphereBoxHelper.update();
}
function intersect()
{
if (boundingBoxBall.intersect(boundingBoxPaddle) == true)
{
console.log("intersection");
}
}
const animate = function ()
{
requestAnimationFrame(animate);
document.addEventListener("keydown", onDocumentKeyDown, false);
function onDocumentKeyDown(event)
{
var keyCode = event.which;
if (keyCode == 65 && cube.position.x >= -18.5)
{
cube.position.x -= xSpeed;
}
else if (keyCode == 68 && cube.position.x <= 18)
{
cube.position.x += xSpeed;
}
cubeBoxHelper.update();
};
bounce();
intersect();
sphereBoxHelper.update();
renderer.render(scene, camera);
};
animate();
Right now I have set it so the intersect function just logs to the console so I can tell what's happening. Any help would be great as I'm not sure what I'm doing wrong.
Box3.intersect
.intersect ( box : Box3 ) : this
box - Box to intersect with.
Computes the intersection of this and box, setting the upper bound of this box to the lesser of the two boxes' upper bounds and the lower bound of this box to the greater of the two boxes' lower bounds. If there's no overlap, makes this box empty.
What this function is actually doing is updating boundingBoxBall with information from boundingBoxPaddle, and possibly even setting boundingBoxBall to be an empty box!
I think the function you're really after is:
Box3.intersectsBox
.intersectsBox ( box : Box3 ) : Boolean
box - Box to check for intersection against.
Determines whether or not this box intersects box.
The intersectsBox function returns a simple true/false, so you can tell if the two boxes have collided.
Also note that your bounding box is relative to the associated geometry. If your transform the Mesh, then you will also need to transform the bounding box. The example code on the Box3 docs actually highlights this:
const box = new THREE.Box3();
// ...
// in the animation loop, compute the current bounding box with the world matrix
box.copy( mesh.geometry.boundingBox ).applyMatrix4( mesh.matrixWorld );
Full Example:
let W = window.innerWidth;
let H = window.innerHeight;
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(28, 1, 1, 1000);
camera.position.set(0, 0, 50);
camera.lookAt(scene.position);
scene.add(camera);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, -1);
camera.add(light);
let geo = new THREE.BoxBufferGeometry(5, 5, 5);
geo.computeBoundingBox();
let mat = new THREE.MeshPhongMaterial({
color: "red"
});
const left = new THREE.Mesh(geo, mat);
left.position.set(-15, 0, 0)
scene.add(left);
const right = new THREE.Mesh(geo, mat);
right.position.set(15, 0, 0)
scene.add(right);
geo = new THREE.SphereBufferGeometry(1, 16, 16);
geo.computeBoundingBox();
mat = new THREE.MeshPhongMaterial({
color: "yellow"
});
const ball = new THREE.Mesh(geo, mat);
scene.add(ball);
function render() {
renderer.render(scene, camera);
}
function resize() {
W = window.innerWidth;
H = window.innerHeight;
renderer.setSize(W, H);
camera.aspect = W / H;
camera.updateProjectionMatrix();
render();
}
let rate = 0.1;
let goingRight = true;
let ballBox = new THREE.Box3();
let wallBox = new THREE.Box3();
function animate() {
render();
ball.position.x += ((goingRight) ? 1 : -1) * rate;
ball.updateMatrix();
ball.updateMatrixWorld(true);
ballBox.copy(ball.geometry.boundingBox);
ballBox.applyMatrix4(ball.matrixWorld);
if (goingRight) {
wallBox.copy(right.geometry.boundingBox);
wallBox.applyMatrix4(right.matrixWorld);
if (ballBox.intersectsBox(wallBox)) {
goingRight = false;
}
} else {
wallBox.copy(left.geometry.boundingBox);
wallBox.applyMatrix4(left.matrixWorld);
if (ballBox.intersectsBox(wallBox)) {
goingRight = true;
}
}
requestAnimationFrame(animate);
}
window.addEventListener("resize", resize);
resize();
requestAnimationFrame(animate);
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
background: skyblue;
}
<script src="https://threejs.org/build/three.min.js"></script>

Round Corners Box Geometry - threejs

This question is more about Math, than about threejs but maybe there are usable Alternatives for my issue.
So what I want to do, is to go through every vertice in a Box Geometry and check weither it has to be moved down/up and move it then by a specific value. (it is only about the y-values of each vertice)
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = var roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helper = Math.abs(v.x)-helperWidth/2;
v.y = Math.sign(v.y)*(helperHeight + Math.cos(helper/roundWidth * Math.PI/2)*roundHeight);
}
}
});
The code above creates corners like you can see on the example image. Those aren't kind of beautiful! :( Another "function" than cos() is needed.
I've used a method without trigonometrical functions, as we can manipulate with vectors:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var radius = 10;
var width = 200,
height = 100;
var geometry = new THREE.BoxGeometry(width, height, 50, 100, 50, 10);
var v1 = new THREE.Vector3();
var w1 = (width - (radius * 2)) * 0.5,
h1 = (height - (radius * 2)) * 0.5;
var vTemp = new THREE.Vector3(),
vSign = new THREE.Vector3(),
vRad = new THREE.Vector3();
geometry.vertices.forEach(v => {
v1.set(w1, h1, v.z);
vTemp.multiplyVectors(v1, vSign.set(Math.sign(v.x), Math.sign(v.y), 1));
vRad.subVectors(v, vTemp);
if (Math.abs(v.x) > v1.x && Math.abs(v.y) > v1.y && vRad.length() > radius) {
vRad.setLength(radius).add(vTemp);
v.copy(vRad);
}
});
var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Disadvantage: you can't control the smoothness of the roundness without increasing the amount of width or height or depth segments.
EDIT: copied surrounding Code Blocks from prisoner849 to make result visbile for everyone.
I wanted to stay with the box Geometry, because I also deform the Geometry on the z-axis, so this is my solution:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helperX = Math.abs(v.x)-helpWidth/2;
let helperY2 = (Math.abs(v.y)-helpHeight/2)/roundCornerHeight;
let helperY = (1-helperX/roundCornerWidth) * roundCornerHeight * helperY2;
v.y = Math.sign(v.y)*((helpHeight/2 + helperY)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerHeight/4))*helperY2);
v.x = Math.sign(v.x)*(Math.abs(v.x)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerWidth/4))*helperY2);
}
}
});
var mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({
color: 0xffce00,
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
This worked for me perfectly and seems to be the simplest solution for my issue.

Animate vertices in Three.js

I'm new to three.js and I'm following this tutorial. I've followed the source code in the tutorial correctly but I'm not getting the same animated results. I'm using three.js 86 whereas the tutorial (https://www.youtube.com/watch?v=_Lz268dlvmE) was from 3 years ago. I realise the problem its most likely stems from outdated syntax but I'm struggling to find the related updates.
I want the vertices in the bottom sphere to drop away as the sphere above rises on the y-axis. Here's my code with the vertex animations detailed under draw() towards the bottom. I've excluded the HTML to just show the JavaScript.
Thanks!
var scene = new THREE.Scene();
var start_breaking=0;
var w = window.innerWidth, h = window.innerHeight;
var camera = new THREE.PerspectiveCamera(45, w/h, 0.1, 10000);
camera.position.set(0,100,400);
var renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
renderer.setSize(w,h);
var geometry = new THREE.SphereGeometry(70,64,64);
var colors = [];
for (var i = 0; i < geometry.vertices.length; i++) {
colors[i] = new THREE.Color();
colors[i].setRGB(Math.random(),Math.random(),Math.random());
}
geometry.colors = colors;
material = new THREE.PointsMaterial({
size:7,
vertexColors: true
});
particleSystem = new THREE.Points(geometry, material);
particleSystem.position.y = 100;
scene.add(particleSystem);
function create_particles() {
var geomx = new THREE.Geometry();
geomx.colors = colors;
var materiax = new THREE.PointsMaterial({
size: 5,
vertexColors: true
});
var verticex = particleSystem.geometry.vertices;
verticex.forEach(function (p) {
var particle = new THREE.Vector3(
p.x * 1.0,
p.y * 1.0,
p.z * 1.0
);
geomx.vertices.push(particle);
});
particleSystemx = new THREE.Points(geomx, material);
particleSystemx.sortParticles = true;
scene.add(particleSystemx);
}
create_particles();
renderer.render(scene, camera);
setTimeout(draw, 500);
function draw() {
particleSystem.rotation.y += 0.0075;
particleSystem.position.y += 0.275;
if (particleSystem.position.y <= 181 && particleSystem.position >= 180.7) {
create_particles();
//scene.remove(particleSystem);
start_breaking=1;
}
if (start_breaking) {
var vertices = particleSystemx.geometry.vertices;
vertices.forEach(function (v){
v.y -= v.vy;
v.x -= v.vx;
v.z -= v.vz;
});
}
renderer.render(scene, camera);
requestAnimationFrame(function() {draw(); });
}

Point sprite rendering issues with three.js

I'm currently working an a project which will visualize data on browser by rendering excessive amounts of animated stroked circles. I started evaluating 3D libraries and ended up trying to create a proof of concept application with three.js. It is capable of animating and rendering up to 150 000 point sprites at 60 fps on my 1440p monitor. Everything looks great until you start looking at the details. It has two rendering issues:
It creates strange horizontal lines even when you turn animation off
https://imgur.com/a/3Ugd0
When you turn the camera, transparent areas of overlapping point sprites will show the background instead of underlying point sprites
https://imgur.com/a/NcIwX
Here is the proof of concept application: https://jsfiddle.net/tcpvfbsd/1/
var renderer, scene, camera, controls;
var points;
var stats;
var controls;
var worldWidth = 200;
var worldRadius = worldWidth / 2;
var patchSize = 10;
var pointsAmount = 100000;
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x1d252d);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.set(0, worldWidth * 1.5, 0);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minDistance = 100;
controls.maxDistance = 1100;
scene.add(new THREE.GridHelper(2 * worldRadius, 2 * worldWidth / patchSize, 0x444444, 0x444444));
var geometry = new THREE.BufferGeometry();
var positions = new Float32Array(pointsAmount * 3);
var rotations = new Float32Array(pointsAmount * 1);
for (var i = 0; i < pointsAmount; i++) {
positions[i] = 0;
positions[i + 1] = 0;
positions[i + 2] = 0;
rotations[i] = 2 * Math.PI * Math.random();
}
controls = new function() {
this.speed = 10;
this.amount = 10;
};
var gui = new dat.GUI();
gui.add(controls, 'speed', 0, 100);
//gui.add(controls, 'amount', 0, 10000).step(1);;
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.addAttribute('rotation', new THREE.BufferAttribute(rotations, 1));
var loader = new THREE.TextureLoader();
loader.load('//i.imgur.com/AmQQnZc.png', function(texture) {
var material = new THREE.PointsMaterial({
size: 5,
transparent: true,
map: texture
});
points = new THREE.Points(geometry, material);
scene.add(points);
stats = new Stats();
document.body.appendChild(stats.dom);
animate();
});
}
function animate() {
requestAnimationFrame(animate);
var position = points.geometry.attributes.position;
var count = position.count;
var rotation = points.geometry.attributes.rotation;
var speed = patchSize * controls.speed / 100;
if (speed > 0) {
for (var i = 0; i < count; i++) {
var wiggle = Math.random() > 0.9 ? THREE.Math.randFloat(-0.1, 0.1) : 0;
var theta = rotation.getX(i) + wiggle;
let dx = speed * Math.cos(theta);
let dz = speed * Math.sin(theta);
var x0 = position.getX(i);
var z0 = position.getZ(i);
var x = THREE.Math.clamp(x0 + dx, -worldRadius, worldRadius);
var z = THREE.Math.clamp(z0 + dz, -worldRadius, worldRadius);
if (Math.abs(x) === worldRadius) dx = -dx;
if (Math.abs(z) === worldRadius) dz = -dz;
position.setX(i, x);
position.setZ(i, z);
position.setY(i, 1);
rotation.setX(i, Math.atan2(dz, dx));
}
}
position.needsUpdate = true;
stats.update();
renderer.render(scene, camera);
}
init();
Best way to see the issues is to wait couple of seconds for the point sprites to spread across to area, use speed control on top right corner to pause animation and the use mouse's left button to turn and rotate the camera.
Using alphaTest with value 0.5 clipped the corners off the circles without affecting the rendering of other circles
Setting transparent value to false removed the buggy fade effect which came after setting alphaTest to 0.5
Adding fading to the texture itself made the circles' borders smooth even thought the transparent setting which caused the fade effect was disabled
Randomizing the position on y axis by 0.01 units removed the strange horizontal lines

ThreeJS: Draw lines at mouse click coordinates

I am working with ThreeJS to create a solar system. I have a sun in the middle and 8 orbits around it. Now I want to get the nearest ring poisiton when the users clicks anywhere on the map!
Here is an image to describe it visually what I mean
The arrows stands for the "click" of the user, then there should be a function to get the nearest orbit and its coordinates (the white dots) where the line between the click point and middle collides.
I tried many different functions I found here, but non of them gave me the result I want.
Thanks for your help!
The code looks currently like this:
var container, stats, parent, pivots, domEvents, twins, planets, sun, fleets, raycaster, mouse;
var camera, controls, scene, renderer;
var cross;
planets = new Array();
init();
animate();
function init()
{
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
//init
camera = new THREE.PerspectiveCamera(10, 1, 1, 4000);
camera.position.z = 200;
camera.position.x = 200;
camera.position.y = 200;
controls = new THREE.OrbitControls(camera);
controls.addEventListener('change', render);
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000000, 0);
// renderer
renderer = new THREE.WebGLRenderer({antialias: false, alpha: true});
renderer.setSize(document.getElementById('canvasreference').offsetWidth, document.getElementById('canvasreference').offsetWidth);
renderer.setClearColor(0x787878, 0.5); // the default
container = document.getElementById('canvasreference');
container.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
domEvents = new THREEx.DomEvents(camera, renderer.domElement);
//axihelper
scene.add(new THREE.AxisHelper(130));
// parent
parent = new THREE.Object3D();
scene.add(parent);
//arrays
orbits = new Array();
addOrbit();
window.addEventListener('click', onMouseMove, false);
}
function onMouseMove(event) {
canvas = renderer.domElement;
raycaster = new THREE.Raycaster();
mousePosition = new THREE.Vector2();
canvasPosition = $("#canvasreference canvas").position();
console.log(canvasPosition);
mousePosition.x = ((event.clientX - canvasPosition.left) / canvas.width) * 2 - 1;
mousePosition.y = -((event.clientY - canvasPosition.top) / canvas.height) * 2 + 1;
raycaster.setFromCamera(mousePosition, camera);
var geometry = new THREE.Geometry();
var origin = new THREE.Vector3(raycaster.ray.origin.x, 0, raycaster.ray.origin.y);
geometry.vertices.push(origin);
var vektor = new THREE.Vector3(raycaster.ray.direction.x, 0, raycaster.ray.direction.y);
for (var i = 0; i < 1000; i++)
{
origin.add(vektor);
geometry.vertices.push(vektor);
}
var material = new THREE.LineBasicMaterial({
color: 0xffffff, linewidth: 20
});
var line = new THREE.Line(geometry, material);
scene.add(line);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(600, 600);
render();
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
function render() {
renderer.render(scene, camera);
}
/**
* add Orbit line
* #param {type} orbit
* #returns {undefined}
*/
function addOrbit(orbit)
{
for (var i = 0; i < 8; i++)
{
//make orbit line
var orbit = new THREE.EllipseCurve(
0, 0, // ax, aY
i * 10 + 30, i * 10 + 30, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
var path = new THREE.Path(orbit.getPoints(100));
var geometry = path.createPointsGeometry(100);
var material = new THREE.LineBasicMaterial({color: 0xffffff});
var ellipse = new THREE.Line(geometry, material);
ellipse.rotation.x = 1.5708;
scene.add(ellipse);
}
}
</script>
Cast a ray from your camera to a point where your mouse is. Then check closest distance from that ray to the middle of you solar system using distanceToPoint function. The length of output vector will be the radius of a sphere to which your ray is tangent. Using this length you can determine how close you are to a sphere that is an orbit and if it should be selected. Here's some pseudo code of that check:
var length = getDistanceToCenter(...);
var closestSphere = _(orbits).min(function(orbit) { return Math.abs(length - orbit.radius); });
if (Math.abs(closestSphere.radius - length) < EPSILON) {
selectOrbit(closestSphere);
}

Categories

Resources