How does terminal points work for edges in mxGraph? Need edges to connect at left-side-mid-height of a vertex - mxgraph

edge = graph.insertEdge(parent,
null,
'',
vertex1,
vertex2);
var destX = vertex2.geometry.x;
var destY = vertex2.geometry.y;
var destHeight = vertex2.geometry.height;
var sourceX = vertex2.geometry.x;
var sourceY = vertex2.geometry.y;
var sourceHeight = vertex2.geometry.height;
edge.geometry.setTerminalPoint(new
mxPoint(sourceX,sourceY+(sourceHeight/2)),true);
edge.geometry.setTerminalPoint(new
mxPoint(destX,destY+(destHeight/2)),false);
edge.geometry.relative = true;
This is creating the default edge.Please assume that the vertex is inserted.

The terminal points are only required if an edge is unconnected, and are stored in the sourcePoint> and targetPoint variables, respectively.
https://jgraph.github.io/mxgraph/docs/js-api/files/model/mxGeometry-js.html#mxGeometry

Related

Default Navigation speed in Forge Viewer

How can the default navigation speed be changed in the Forge Viewer? The default setting is far to fast for my sample models. I should like to write code so that the speed may be changed during a session.
Copy an existing navigation tool from the viewer3D.js implementation, modify the speed parameters as you wish or expose methods to do so dynamically from your app, then set it active.
You can check the implementation of OrbitDollyPanTool L#14545 in viewer3D.js
Autodesk.Viewing.OrbitDollyPanTool = function( viewerImpl, viewerApi ){
var avp = Autodesk.Viewing.Private;
var _this = this;
var kScreenEpsilon = 0.001;
var kEpsilon = 0.00001;
var kAutoDeltaZ = 1.5; // Dolly increment
var kAutoDeltaXY = 0.01;
var kAutoScreenXY = 20;
var kDollyDragScale = 100.0;
var kDollyPinchScale = 0.5;
var kOrbitScale = 2.0;
// ...
That tool is instantiated as follow (L#40923):
Viewer3D.prototype.createControls = function( ) {
var self = this;
var impl = self.impl;
self.navigation = new av.Navigation(impl.camera);
self.__initAutoCam(impl);
self.utilities = new av.ViewingUtilities(impl, self.autocam, self.navigation);
self.clickHandler = new av.DefaultHandler(impl, self.navigation, self.utilities);
self.toolController = new av.ToolController(impl, self, self.autocam, self.utilities, self.clickHandler);
self.toolController.registerTool( new av.GestureHandler(self) );
self.toolController.registerTool( av.theHotkeyManager );
self.toolController.activateTool( av.theHotkeyManager.getName() );
self.registerUniversalHotkeys();
self.toolController.registerTool( new av.OrbitDollyPanTool(impl, self) );
self.toolController.activateTool( "gestures" );
return self.toolController;
};
I recently found out that you can use viewer.navigation.fitBounds(true, THREE.Box3) which will impact the navigation speed to match the extends defined by those bounds.

Randomising array coordinates with no duplicates AS3

very new to this kind of thing so please bear with me.
So basically I have 4 buttons that I have put to the stage using the Actions panel. They all have set coordinates so every time I run my game, they are in the same place.
Now here's my issue, I want these buttons to randomise their positions using those coordinates, but I often get duplicates, meaning one button is on top of another.
Here is my code so far
var coordArray : Array = [
new Point(44,420),
new Point(270,420),
new Point(44,550),
new Point(270,550),
];
var pointRange:Number = 4;
var randomPoint:int = Math.random()*pointRange;
answerButtons.x = coordArray[randomPoint].x;
answerButtons.y = coordArray[randomPoint].y;
var pointRange_2:Number = 4;
var randomPoint_2:int = Math.random()*pointRange_2;
answerButtons_2.x = coordArray[randomPoint_2].x;
answerButtons_2.y = coordArray[randomPoint_2].y;
var pointRange_3:Number = 4;
var randomPoint_3:int = Math.random()*pointRange_3;
answerButtons_3.x = coordArray[randomPoint_3].x;
answerButtons_3.y = coordArray[randomPoint_3].y;
var pointRange_4:Number = 4;
var randomPoint_4:int = Math.random()*pointRange_4;
answerButtons_4.x = coordArray[randomPoint_4].x;
answerButtons_4.y = coordArray[randomPoint_4].y;
I have googled this profusely and I keep getting answers to do with the splice and shift methods. Is this the type of thing I need? I'm assuming I need a function that removes a point from the array after it is used.
Cheers.
Just remove the coordinate from the list when you pick it randomly using splice:
var coordinates:Vector.<Point> = new <Point>[
new Point(44, 420),
new Point(270, 420),
new Point(44, 550),
new Point(270, 550)
];
function positionAtRandomCoordinate(object:DisplayObject):void {
var index:int = Math.random() * coordinates.length;
var coordinate:Point = coordinates.splice(index, 1)[0];
object.x = coordinate.x;
object.y = coordinate.y;
}
positionAtRandomCoordinate(answerButtons);
positionAtRandomCoordinate(answerButtons_2);
positionAtRandomCoordinate(answerButtons_3);
positionAtRandomCoordinate(answerButtons_4);

Issues with BitmapData of a MovieClip with rotationY applied to it

So I have a simple file right now that eventually will take a movieclip and save it as an image. I am currently rotating the clip's y by 45 to give it kind of a 3D look and adding it back to the stage. I've tried googling and a couple different things, but I can't quite get it to work. The first thing I tried was getting the BitmapData of the movieclip I rotated. That flattened the clip:
test_mc.response_mc.rotationY = 45;
var mc:MovieClip = test_mc.response_mc;
var bmp:BitmapData = new BitmapData(mc.width, mc.height);
bmp.draw(mc);
var output:Bitmap = new Bitmap(bmp);
output.x = 270;
output.y = 191;
addChild(output);
The next thing I tried was getting the parent clip's BD. That gave it an angle... just the wrong one:
(same code as above with this line change)
var mc:MovieClip = test_mc;
Any thoughts here would be nice. I tried doing stuff with matrices, but had no luck. I also have images... just can't post them yet :(
Something else I've tried with no luck:
var target:DisplayObject = test_mc as DisplayObject;
var targetTransform:Matrix = target.transform.concatenatedMatrix;
var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
var targetGlobalPos:Point = target.localToGlobal(new Point());
var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);
targetTransform.tx = targetOriginOffset.x;
targetTransform.ty = targetOriginOffset.y;
var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width, targetGlobalBounds.height, true, 0x00000000);
cloneData.draw(target, targetTransform);
var output:Bitmap = new Bitmap(cloneData);
**Another update**
So hopefully this will help a little. I was able to recreate what I was doing using Matrix3D.
test_mc.response_mc.rotationY = 45;
var matrix:Matrix3D = new Matrix3D();
matrix.prependRotation(45, Vector3D.Y_AXIS);
test2_mc.response_mc.transform.matrix3D = matrix;
test2_mc.response_mc.transform.matrix3D.appendTranslation(0, 0, 0);
And I've come closer to getting the bitmap to look correct (thank to a Mike Chambers blog).
var mcOffset:Matrix3D = test2_mc.response_mc.transform.matrix3D;
var rawMatrixData:Vector.<Number> = mcOffset.rawData;
var globalBounds:Rectangle = test2_mc.response_mc.getBounds(test2_mc);
var matrix:Matrix = new Matrix();
matrix.a = rawMatrixData[0];
matrix.c = rawMatrixData[1];
matrix.tx = test2_mc.response_mc.x - globalBounds.x;
matrix.b = rawMatrixData[4];
matrix.d = rawMatrixData[5];
matrix.ty = test2_mc.response_mc.y - globalBounds.y;
var bmp:BitmapData = new BitmapData(150, test2_mc.height);
test2_mc.response_mc.transform.matrix3D = null;
bmp.draw(test2_mc.response_mc, matrix);
test2_mc.response_mc.transform.matrix3D = mcOffset;
var output:Bitmap = new Bitmap(bmp);
Well I took it a step further back and went to the stage. For whatever reason trying to draw the parent (test_mc) of the rotated movie clip (response_mc) WON'T work, however drawing the stage and setting the bounds to the area of the parent DOES work. Here's my code (which is sadly very simple):
var bmp:BitmapData = new BitmapData(test_mc.width, test_mc.height);
bmp.draw(stage.getChildAt(0), new Matrix(1, 0, 0, 1, -test_mc.x, -test_mc.y));
var output:Bitmap = new Bitmap(bmp);

AS3 Multiple Webcams not showing 3rd webcam

Hi I'm trying to create a simple AIR 3 application that displays 3 Webcams on the stage. For some reason the 3rd webcam doesn't want to show, it doesn't even turn on the LED indicator on the webcam.
I have tried multiple webcams eg. microsoft, logitech, built in....
The following code doesn't work:
var videoWidth:int = 1000 / totalCols;
var videoHeight:int = 800 / totalRows;
for (var i:int = 0; i < Math.min(Camera.names.length, totalRows * totalCols); i++) {
var currRow:int = Math.floor(i / totalCols);
var currCol:int = i % totalCols;
var video:Video = new Video(videoWidth, videoHeight);
var cam:Camera = Camera.getCamera(i.toString());
if (cam) {
cam.setMode(videoWidth, videoHeight, 30);
video.attachCamera(cam);
video.x = currCol * videoWidth;
video.y = currRow * videoHeight;
StageObj.addChild(video);
}
}
Neither does this:
//camera settings
track_cam = new Camera();
track_cam = Camera.getCamera("1");
track_cam.setMotionLevel(100);
track_cam.setQuality(0, 100);
track_cam.setMode(1920, 1080, 30);
track_feed = new Video();
track_feed.width = track_cam.width;
track_feed.height = track_cam.height;
track_feed.smoothing = true;
track_feed.attachCamera(track_cam);
StageObj.addChild(track_feed);
player_one_cam = new Camera();
player_one_cam = Camera.getCamera("2");
player_one_cam.setMotionLevel(100);
player_one_cam.setQuality(0, 100);
player_one_cam.setMode(200, 200, 30);
player_one_feed = new Video();
player_one_feed.width = player_one_cam.width;
player_one_feed.height = player_one_cam.height;
player_one_feed.smoothing = true;
player_one_feed.attachCamera(player_one_cam);
StageObj.addChild(player_one_feed);
player_one_feed.x = 500;
player_one_feed.y = 500;
player_two_cam = new Camera();
player_two_cam = Camera.getCamera("0");
player_two_cam.setMotionLevel(100);
player_two_cam.setQuality(0, 100);
player_two_cam.setMode(200, 200, 30);
player_two_feed = new Video();
player_two_feed.width = player_two_cam.width;
player_two_feed.height = player_two_cam.height;
player_two_feed.smoothing = true;
player_two_feed.attachCamera(player_two_cam);
StageObj.addChild(player_two_feed);
Is there a limit on the amount of webcams you can use in AS3?
It seems that I ran out of USB Bandwidth, when using usb 3 on a seperate machine it started working.
Looks like it should work from the docs:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Camera.html#getCamera()
name:String (default = null) — Specifies which camera to get, as
determined from the array returned by the names property. For most
applications, get the default camera by omitting this parameter. To
specify a value for this parameter, use the string representation of
the zero-based index position within the Camera.names array. For
example, to specify the third camera in the array, use
Camera.getCamera("2").

JSON string changes its keys for Google MAPS API v3

I've seen this question a few times already on here but the responses aren't quite applicable to my case.
I am using a google.maps.Polygon object to save bounds that is drawn on a map.
Later I am using the "getPath" method and I add this to a Json string.
The JSON string is always different. Sometimes I can grab the polygon corners by:
thisShape.data.b[i].kb
thisShape.data.b[i].lb
other times by
thisShape.data.b[i].Qa
thisShape.data.b[i].Ra
etc.
It seems over time, the key for the Json string changes. However I am not responsible what the Google Api returns as far the Polygon object goes.
Is there a way to grab the longtitute and latitude without knowing the key?
Any ideas how to loop through my polygons without fear that it'll break in a few weeks?
Many thanks
Suppose you have a method called "SavePolygonData" that, among other things, creates a Json string like this:
var allData = {};
$("div.shapes").each(function(){
var id = $(this).attr("id");
var type = id.split('_')[0];
var feature = MapToolbar.features[type+'Tab'][id];
var vertices = feature.getPath();
allData[id] = { color: feature.fillColor, data: vertices};
});
var allDataJson = JSON.stringify(allData);
and then later another method that reads the json string somewhere else like this:
for (var polyId in allData) {
if (allData.hasOwnProperty(polyId)) {
var thisShape = allData[polyId];
var color = thisShape.color;
var vertices=new Array();
for ( var i=0; i<thisShape.data.b.length; ++i )
{
var coordX = thisShape.data.b[i].kb; //Problem here
var coordY = thisShape.data.b[i].lb; //Problem here
var point = new google.maps.LatLng(coordX, coordY);
vertices[i] = point;
}
var poly = new google.maps.Polygon({
strokeWeight: 2,
fillColor: color,
paths: vertices
});
poly.setMap(map);
}
I can't use the getLat() methods on the json string because obviously it only contains strings. Instead I have to create a new data structure for my "data" variable that contains processed data instead of feature.getPath().
That's what I need help with. What is the structure of that new data structure?
I have noticed there is the google.maps.geometry.encoding.encodePath() method.
But I need to be able to decode it in server side.
The problem in your SavePolygonData example code is that you are trying to use the vertices data directly in your JSON object. Instead, you need to use the documented methods to get the latitude and longitude values from the vertex array and serialize those.
To fix it, you can change this code:
var vertices = feature.getPath();
allData[id] = { color: feature.fillColor, data: vertices};
to:
var vertices = getLatLngVertices( feature.getPath() );
allData[id] = { color: feature.fillColor, data: vertices };
and elsewhere define this function:
function getLatLngVertices( path ) {
var pathArray = path.getArray();
var vertices = [];
for( var i = 0, n = pathArray.length; i < n; i++ ) {
var latLng = pathArray[i];
vertices.push({ lat: latLng.lat(), lng: latLng.lng() });
}
return vertices;
}
Now in your code that parses this JSON you can use:
var data = thisShape.data;
for( var i = 0, n = data.length; i < n; ++i ) {
var point = data[i];
vertices[i] = new google.maps.LatLng( point.lat, point.lng );
}
It looks like getPath() returns an MVCArray of LatLng, from which you are supposed to extract latitude and longitude by calling the lat() and lng() methods, not by directly accessing properties. If it were possible in JavaScript, these properties would have been declared private. But the same applies to the MVCArray, for which you have the choice of looping over with forEach(), or, if are not at ease with lambda functions yet, with getAt(), using the result of getLength() as guard:
polygon.getPath().forEach(function(latLng, idx) {
var lat = latLng.lat();
var lng = latLng.lng();
// do something
});
or
var path = polygon.getPath();
var len = path.getLength();
for (var idx = 0; idx < len; idx++) {
var latLng = path.getAt(idx);
var lat = latLng.lat();
var lng = latLng.lng();
// do something
}
These examples are OK if the polygon consists of only one path. If not, you will have to loop over paths too.