In digital twin visualizations, you may run into the problem of measuring the distance between different objects in the digital twin visualizations. Through this measurement, we can clearly know the position of each target in the visual scene and the distance between each target, which is convenient for making reasonable planning. This requirement is not difficult. What we need to do is to determine the starting and ending positions of the coordinate points of the object to be measured.

The running effect is as follows:

In ThingJS, to know the spatial distance between two points in a scene, you can calculate the spatial distance between two points by calling all coordinate points in three-dimensional space and calculating the distance between two coordinate points. You need to click the mouse to get the spatial distance between two points. For example, if I want to know the distance between two scenes in a scene, I can click two or more scene locations with the mouse to calculate the spatial distance of any THREE-DIMENSIONAL point in a THREE-DIMENSIONAL scene. Let’s take a look at the operation steps:

1. Add the registration event and drag event on the registration measurement details interface. Set the drag range not beyond the screen.

registerEvent() { var _this = this; $('# datadetails.tj-close '). On ('click', function() {$('#dataDetails').css('display', 'none'); }); $('# datadetails.tj-title '). On ('mousedown', function(ev) {ev.preventdefault (); var domEle = $('#dataDetails .tj-panel'); var spacX = ev.pageX - domEle[0].offsetLeft; var spacY = ev.pageY - domEle[0].offsetTop; $(document).bind('mousemove', function(event) { var x = event.pageX - spacX; var y = event.pageY - spacY; if (event.pageX < 0 || event.pageX > $(window).width() || event.pageY < 0 || event.pageY > $(window).height()) { $(document).unbind('mousemove'); } if (x <= 0) x = 0; if (x > ($(window).width() - domEle.width())) { x = $(window).width() - domEle.width(); } if (y <= 0) y = 0; if (y > ($(window).height() - domEle.height())) { y = $(window).height() - domEle.height(); } domEle.css('left', x + 'px').css('top', y + 'px'); }); }).on('mouseup', function() { $(document).unbind('mousemove'); }); / / register click event, create instances app. The range line on (THING. EventType. SingleClick, '*', function (e) {if (e.b utton = = 0) {_this. LineNum++; let line = new DrawLine({ app: app, modelNum: _this.lineNum, currPosition: E.p ickedPosition}) app. PauseEvent (THING) EventType) SingleClick, '*', 'create distance line'); }}, "create range line "); }}Copy the code

2. ThingJS uses Constructor () as an object Constructor function to construct an “object type” that creates a skeleton of objects of the same type. The Constructor () Constructor assigns initial values to the properties of the object. JS can arbitrarily extend the construction parameter option to achieve dynamic binding. The construction parameters for drawing the measurement line are created as follows:

Constructor (constructor) {this.opts = option; / / const const (const const) {const const (const const); this.pointsArr = [this.opts.currPosition]; CoordinatesArr = [this.opts.currPosition]; This.eposition = null; this.ePosition = null; // Store mouse position after trigger event this.linecoor = [this.opts.currPosition]; This.disarr = []; This.numindex = 0; this.numindex = 0; // Incrementing this.reSetDistance; // Store the distance between two points this.lastStatus = false; This.pointsobjarr = []; this.pointsobjarr = []; this.rianleyDom = $('#marker'); This.pointcarddom = $('#pointMarker'); // mouse over the node prompt this.init(); // initialize this.appclick (); // Call method}Copy the code

3. Click the left mouse button to add a point point. Double-click or right-click to finish. If it is a multi-line measurement, moving the mouse can continue to draw.

appClick() { var _this = this; _this.opts.app.on('SingleClick', function(e) {if (e.button == 0) {if (! e.picked) return; _this.numIndex++; _this.ePosition = e.pickedPosition; _this.createPoint(_this.ePosition); _this.coordinatesArr.push(_this.ePosition); _this.lineCoor.push(_this.ePosition); _this.createLine(_this.coordinatesArr); _this.getDistance(); _this.template = `<div id="line` + _this.opts.modelNum + _this.numIndex + `" class="card-label card-line` + _this.opts.modelNum + `"> <span class="text">`; if (_this.lineDistanceAll ! = null) {_this.template += _this.lineDistanceAll + 'm'; } else { _this.template += `<span style="color:#f45905; border-right: 1px solid #ccc; margin-right: Template += '</span> <span><img id="linePoints' + _this.opts.modelnum + _this.numIndex + `" src="/guide/examples/images/measure/remove.png"></span> </div>`; _this.boardId = 'line' + _this.opts.modelNum + _this.numIndex; _this.createCard(_this.regionPoint); _this.pointsObj = { id: 'linePoints' + _this.opts.modelNum + _this.numIndex, parent: 'line' + _this.opts.modelNum + _this.numIndex, coor: _this.ePosition, distance: _this.lineDistance } _this.pointsObjArr.push(_this.pointsObj); _this.cardClick(); } else { if (_this.coordinatesArr.length < 2) { _this.destroyAll(); _this.rianleyDom.css('display', 'none'); return; }; _this.end(); } _this.rianleyDom.css('display', 'none'); }, 'click '); On ('MouseMove', function(e) {if (e.p) {_this.ePosition = e.pickedPosition; _this.pointsArr = [..._this.coordinatesArr, _this.ePosition]; _this.createLine(_this.pointsArr); _this.line.style.color = '#f88020'; if (_this.pointsArr.length >= 2) { _this.moveDistance = THING.Math.getDistance(_this.pointsArr[_this.pointsArr.length - 1], _this.pointsArr[_this.pointsArr.length - 2]); let countNum = 0; _this.disArr.forEach(v => { countNum += parseFloat(v); }); countNum = 1 * parseFloat(countNum).toFixed(2) + 1 * parseFloat(_this.moveDistance).toFixed(2); _this.rianleyDom.css('display', 'block'); _this.rianleyDom.find('span.value').text(countNum.toFixed(2)); _this.rianleyDom.css('left', e.clientX + 10 + 'px'); _this.rianleyDom.css('top', e.clientY + 'px'); }}}, 'move '); / / end to draw the current measurement line. _this opts. App. On (' DBLClick ', function (ev) {if (_this. CoordinatesArr. Length < 2) {_this. DestroyAll (); _this.rianleyDom.css('display', 'none'); return; }; _this.end(); }, 'double click '); } @param {Array} ePosition - coordinate */ createPoint(ePosition) {var _this = this; _this.regionPoint = _this.opts.app.create({ type: 'Sphere', id: 'linePoints' + _this.opts.modelNum + _this.numIndex, name: 'linePoints' + _this.opts.modelNum, radius: 0.2, // radius widthSegments: 16, heightSegments: 16, position: ePosition, // sphere coordinate style: {color: '#c10000', roughness: Opacity: 0}}); }Copy the code

4, create node, line segment and node top card these basic elements, determine the starting point, the coordinates of each node. The line segment belongs to the set of coordinate points after all mouse clicks, that is, the total distance measured.

createPoint(ePosition) { var _this = this; _this.regionPoint = _this.opts.app.create({ type: 'Sphere', id: 'linePoints' + _this.opts.modelNum + _this.numIndex, name: 'linePoints' + _this.opts.modelNum, radius: 0.2, // radius widthSegments: 16, heightSegments: 16, position: ePosition, // sphere coordinate style: {color: '#c10000', roughness: Opacity: 0}}); Coordinates @param {Array} coordinates - set of coordinates after all mouse clicking */ coordinates (coordinates) {let id = this.opts.modelnum >= 10 ? this.opts.modelNum : '0' + this.opts.modelNum; if (this.line) { this.line.destroy(); } this.lineId = 'Line' + id; This. line = this.opts.app. Create ({type: 'PolygonLine', name: 'line', id: 'line' + id, width: 0.05, points: Coordinates, style: {color: '#f45905', roughness: 5, opacity: 0.9}}); } /** * getDistance() {if (this.linecoor.length < 2) return; if (this.coordinatesArr.length > 2) { this.lineCoor.shift(); } this.lineDistance = THING.Math.getDistance(this.lineCoor[0], this.lineCoor[1]); this.lineDistance = this.lineDistance.toFixed(2); this.disArr.push(this.lineDistance); let countNum = 0; this.disArr.forEach(v => { countNum += parseFloat(v); }); this.lineDistanceAll = countNum.toFixed(2); } @param {Object} parent - createCard(parent) {$('#div3d').append(this.template); this.srcElem = document.getElementById(this.boardId); this.imgElem = document.getElementById('linePoints' + this.opts.modelNum + this.numIndex); this.ui = this.opts.app.create({ type: 'UIAnchor', parent: parent, element: this.srcElem, localPosition: [0.4, 0.3, 0.4], pivotPixel: [0, 0]}); }Copy the code

Through the above operations, multi-point line segment can be drawn and the distance between the multi-point line segment can be calculated. The figure above shows the test results of multi-point line segment length. Come and try it!