123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- const express = require('express');
- const { Bundle, Client } = require('node-osc');
- const path = require('path');
- const bodyParser = require('body-parser');
- const app = express();
- const oscClient = new Client('127.0.0.1', 3333);
- let alive = [];
- let fseq;
- var objTriangle = [] ;
- function getHypotenuse(touch1, touch2) {
- var x = Math.abs(touch1.x - touch2.x);
- var y = Math.abs(touch1.y - touch2.y);
- return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
- }
- function getTop(dotTrio) {
- var dist01 = getHypotenuse(dotTrio[0], dotTrio[1]);
- var dist02 = getHypotenuse(dotTrio[0], dotTrio[2]);
- var dist12 = getHypotenuse(dotTrio[1], dotTrio[2]);
- var diff01m02 = Math.abs(dist01 - dist02);
- var diff01m12 = Math.abs(dist01 - dist12);
- var diff02m12 = Math.abs(dist02 - dist12);
- if (diff01m02 < diff02m12 && diff01m02 < diff01m12) {return 0;}
- else if (diff01m12<diff01m02 && diff01m12<diff02m12) {return 1;}
- else if (diff02m12<diff01m02 && diff02m12<diff01m12) {return 2;}
- }
- function getAngleApex(dotTrio, topIndex) {
- var dotA, dotB, dotC;
- dotB = dotTrio[topIndex];
- if (topIndex == 0) {
- dotA = dotTrio[1];
- dotC = dotTrio[2];
- }
- else if (topIndex == 1) {
- dotA = dotTrio[0];
- dotC = dotTrio[2];
- }
- else if (topIndex == 2) {
- dotA = dotTrio[0];
- dotC = dotTrio[1];
- }
- var AB = [dotB.x - dotA.x, dotB.y - dotA.y] ;
- var CB = [dotB.x - dotC.x, dotB.y - dotC.y] ;
-
- var dotProd = (AB[0] * CB[0] + AB[1] * CB[1]);
- var crossProd = (AB[0]*CB[1] - AB[1] * CB[0]);
- var alpha = Math.atan2(crossProd, dotProd);
- //return alpha ;
- return Math.floor(alpha * 180. / Math.PI + 0.5) ;
- }
- function getOrientation(dotTrio, topIndex) {
- var dotA, dotB, dotC;
- dotB = dotTrio[topIndex];
- if (topIndex == 0) {
- dotA = dotTrio[1];
- dotC = dotTrio[2];
- }
- else if (topIndex == 1) {
- dotA = dotTrio[0];
- dotC = dotTrio[2];
- }
- else if (topIndex == 2) {
- dotA = dotTrio[0];
- dotC = dotTrio[1];
- }
- var middlePt = [(dotA.x+dotC.x)/2 ,(dotA.y+dotC.y)/2 ] ;
- var diff = [dotB.x - middlePt[0], dotB.y - middlePt[1]] ;
- var length = Math.sqrt(Math.pow(diff[0],2) + Math.pow(diff[1], 2) ) ;
- //normalize diff
- diff = [diff[0]/length, diff[1]/length];
- var rad = Math.atan2(diff[0], diff[1]) ;
- return Math.floor( -1 * rad * 180 / Math.PI) ;
- //return length ;
-
- }
- const server = require('http').Server(app);
- app.use(bodyParser.json());
- app.use(bodyParser.urlencoded({extended:true}));
- app.use(express.static('./frontend/assets'));
- app.get('/', function (req, res) {
- res.sendFile('./frontend/index.html', { root: path.resolve(__dirname + '/..') })
- });
- app.post('/json', function (req, res) {
- if (req.body.debug) {
- //console.log(req.body);
- }
- let oscBundle;
- if (req.body.event === 'touchend') {
- fseq = fseq ? fseq + 1 : 1;
- const aliveMessage = [ '/tuio/2Dcur', 'alive' ].concat(alive);
- oscBundle = new Bundle(
- [ '/tuio/2Dcur', 'source', `tangibles${req.body.section.toString()}@127.0.0.1` ],
- aliveMessage,
- [ '/tuio/2Dcur', 'fseq', fseq ],
- [
- '/tuio/2Dcur',
- 'del',
- req.body.changedTouches[0].identifier
- ]
- );
- oscClient.send(oscBundle, () => {
- const index = alive.indexOf(req.body.changedTouches[0].identifier);
- alive.splice(index, 1);
- if (alive.length === 0) {
- oscBundle = new Bundle(
- [ '/tuio/2Dcur', 'source', `tangibles${req.body.section.toString()}@127.0.0.1` ],
- [ '/tuio/2Dcur', 'alive' ],
- [ '/tuio/2Dcur', 'fseq', fseq ]
- );
- oscClient.send(oscBundle, () => {
- res.status(200).json(JSON.stringify(req.body));
- fseq = 0;
- });
- } else {
- res.status(200).send();
- }
- });
- } else {
- if (req.body.changedTouches && req.body.changedTouches.length && req.body.changedTouches.length > 0) {
- fseq = fseq ? fseq + 1 : 1;
- const touches = Object.keys(req.body.changedTouches);
- const aliveMessage = [ '/tuio/2Dcur', 'alive' ].concat(alive);
- touches.forEach(touch => {
- const id = req.body.changedTouches[touch].identifier;
- if (!alive.includes(id)) {
- alive.push(id);
- aliveMessage.push(id);
- }
- });
- /* Listage de tous les points */
- const dots = [];
- touches.forEach(function(touch) {
- dots.push({
- id: req.body.changedTouches[touch].identifier,
- x: req.body.changedTouches[touch].clientX,
- y: req.body.changedTouches[touch].clientY
- });
- });
- // console.log(dots, dots.length);
- /* Listage des segments */
- const segments = [];
- if (dots.length > 2) {
- for (var i = 0; i < dots.length; i++) {
- for (var j = 0; j < dots.length; j++) {
- if (j !== i) {
- /* on vérifie que le segment n'est pas déjà listé */
- const alreadyExists = segments.find(segment => {
- return segment.identifiers.includes(i) && segment.identifiers.includes(j);
- });
- /* on calcule la taille du segment (l'hypoténuse) */
- var hyp = getHypotenuse(dots[i], dots[j]);
- /* on garde uniquement les segments inférieurs à 550px
- * cette valeur devra être une variable de configuration */
- if (!alreadyExists && hyp <= 750) {
- segments.push({
- identifiers: [i, j],
- x1: dots[i].x,
- x2: dots[j].x,
- y1: dots[i].y,
- y2: dots[j].y,
- hyp
- });
- }
- }
- }
- }
- }
- // console.log(segments, segments.length);
- /* Listage des triangles */
- var triangles = [];
- /* on boucle sur les segments */
- segments.forEach((segment) => {
- const dot1 = segment.identifiers[0];
- const dot2 = segment.identifiers[1];
- /* on vérifie que le triangle n'est pas déjà listé */
- const alreadyExists = triangles.find(triangle => {
- return triangle.includes(dot1) && triangle.includes(dot2);
- });
- if (!alreadyExists) {
- /* on cherche les segments qui contiennent un des 2 points du segment actuel
- * ex: si le segment actuel est AB, on cherche un segment contenant A (pour AC) et un autre contenant B (pour BC) */
- const found1 = segments.findIndex(seg => {
- return (seg.identifiers.includes(dot1) && !seg.identifiers.includes(dot2));
- });
- const found2 = segments.findIndex(seg => {
- return (seg.identifiers.includes(dot2) && !seg.identifiers.includes(dot1));
- });
- /* si on trouve bien les 2 segments (AC et BC), on peut créer un triangle */
- if (found1 !== -1 && found2 !== -1) {
- /* on devine quel est le 3ème point du triangle par rapport au segment actuel (le point C par rapport au segment AB) */
- const dot3 = segments[found1].identifiers.find(identifier => {
- return identifier !== dot1 && identifier !== dot2;
- });
- triangles.push([dot1, dot2, dot3]);
- }
- }
- });
- console.log(triangles, triangles.length);
- //MOD TITI
- //objet pour stocker les informations des triangles identifiés (points, centre, apexAngle, orientation, indice apex, width, height)
-
- objTriangle = {} ;
- /* Définition de l'apex */
- triangles.forEach(triangle => {
- objTriangle.dots = [];
- objTriangle.dots[0] = dots[triangle[0]];
- objTriangle.dots[1] = dots[triangle[1]];
- objTriangle.dots[2] = dots[triangle[2]];
- objTriangle.apex = getTop(objTriangle.dots);
- objTriangle.center = [(objTriangle.dots[0].x+objTriangle.dots[1].x+objTriangle.dots[2].x)/3 ,
- (objTriangle.dots[0].y+objTriangle.dots[1].y+objTriangle.dots[2].y)/3] ;
- objTriangle.angleApex = getAngleApex(objTriangle.dots, objTriangle.apex) ;
- objTriangle.orientation = getOrientation(objTriangle.dots, objTriangle.apex) ;
- // /* on récupère les 3 côtés (segments) du triangle */
- // const segment1 = segments.find(segment => {
- // return segment.identifiers.includes(triangle[0]) && segment.identifiers.includes(triangle[1]);
- // });
- // const segment2 = segments.find(segment => {
- // return segment.identifiers.includes(triangle[1]) && segment.identifiers.includes(triangle[2]);
- // });
- // const segment3 = segments.find(segment => {
- // return segment.identifiers.includes(triangle[0]) && segment.identifiers.includes(triangle[2]);
- // });
- // /* on trouve quel côté est le plus court
- // * NOTE: dans notre cas, l'apex sera toujours le point opposé au plus petit côté
- // * cette méthode n'est pas généralisable à d'autres projets */
- // const smallestSegment = [segment1, segment2, segment3].reduce(function(prev, current) {
- // return (prev.hyp < current.hyp) ? prev : current
- // });
-
- // /* on déduit quel point du triangle est l'apex */
- // const apexDot = triangle.find(dot => {
- // return dot !== smallestSegment.identifiers[0] && dot !== smallestSegment.identifiers[1];
- // });
- console.log(objTriangle.apex );
- console.log("centerPos : " + objTriangle.center + " orientation : " + objTriangle.orientation);
- /* Reste à faire:
- * trouver la valeur de l'angle de l'apex (théorème des cosinus)
- * trouver le "centre" du triangle (via les orthocentres ou médianes??)
- * déduire l'orientation du triangle
- */
- });
- //plante vite
- // if (objTriangle.dots != undefined){
- // let oscBundleObj ;
- // oscBundleObj = new Bundle(
- // [ '/tuio/2Dobj', 'source', `tangibles${req.body.section.toString()}@127.0.0.1` ],
- // [ '/tuio/2Dobj', 'alive', 1 ],
- // [
- // '/tuio/2Dobj',
- // 'set',
- // 1,
- // 1,
- // objTriangle.center[0],
- // objTriangle.center[1],
- // objTriangle.orientation,
- // 0.0,
- // 0.0,
- // 0.0,
- // 0.0,
- // 0.0
- // ],
- // [ '/tuio/2Dobj', 'fseq', fseq ]
- // );
- // // // objTriangle.forEach(triangleIndex => {
- // // // oscBundle.append(
- // // // [
- // // // '/tuio/2Dobj',
- // // // 'set',
- // // // triangleIndex,
- // // // triangleIndex,
- // // // objTriangle[triangleIndex].center[0],
- // // // objTriangle[triangleIndex].center[1],
- // // // objTriangle[triangleIndex].orientation,
- // // // 0.0,
- // // // 0.0,
- // // // 0.0,
- // // // 0.0,
- // // // 0.0
- // // // ]
- // // // );
- // // // });
- // console.log(oscBundleObj);
- // oscClient.send(oscBundleObj, () => {
- // res.status(200).json(JSON.stringify(req.body));
- // });
- // }
-
- // oscBundle = new Bundle(
- // [ '/tuio/2Dcur', 'source', `tangibles${req.body.section.toString()}@127.0.0.1` ],
- // aliveMessage,
- // [ '/tuio/2Dcur', 'fseq', fseq ]
- // );
- // touches.forEach(touch => {
- // oscBundle.append(
- // [
- // '/tuio/2Dcur',
- // 'set',
- // req.body.changedTouches[touch].identifier,
- // req.body.changedTouches[touch].clientX / req.body.screenW,
- // req.body.changedTouches[touch].clientY / req.body.screenH,
- // 0.0,
- // 0.0
- // ]
- // );
- // });
- oscBundle = new Bundle ;
- oscBundle.append([ '/tuio/2Dobj', 'alive', 1 ]);
- if (objTriangle.dots != undefined){
-
- oscBundle.append([
- '/tuio/2Dobj',
- 'set',
- 1,
- 1,
- objTriangle.center[0],
- objTriangle.center[1],
- objTriangle.orientation,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ]);
- }
- oscBundle.append([ '/tuio/2Dobj', 'fseq', fseq ]);
-
- oscClient.send(oscBundle, () => {
- res.status(200).json(JSON.stringify(req.body));
- });}
-
- else {
- res.status(400).send();
- }
- }
- });
- server.listen(5001, function () {
- console.log('Votre app est disponible sur localhost:5001 !')
- });
|