How to enforce a layout for nodes containing other nodes - position

I use plantuml 1.2019.8 and graphviz 2.38
I want to position the middle node in the center of the diagramme and the up and down nodes above and below it.
But I cannot move up, down and middle to the center while at the same enforcing that right shows on the right side and left on the left side.
#startuml
skinparam linetype ortho
node up
node down
node "\n\n<b> middle\n\n" as middle
node " " as left {
node "left" as in_left
}
node " " as right {
node "right" as in_right
}
middle -u- up
down -u- middle
right -u- up
down -u- right
left -u- up
down -u- left
#enduml
now this complex problem
#startuml
skinparam linetype ortho
node up
node down
node " " as left {
node "left1" as in_left1
node "left2" as in_left2
node "left3" as in_left3
}
together " " as T {
node " " as middle {
node "middle1" as in_middle1
node "middle2" as in_middle2
}
node " " as right {
node "right1" as in_right1
node "right2" as in_right2
}
}
in_left1 .d. in_left2
in_left2 .d. in_left3
in_right1 .r. in_right2
in_middle1 .d. in_middle2
middle -u- up
down -u-- middle
right -u- up
down -u--- right
left -u- up
down -u- left
#enduml
Here is the Result
but the up and down are again not centered with middle1 and middle2

You could use the together keyword to enforce that middle and right stick together. Left will then flow around it on the other side.
#startuml
skinparam linetype ortho
node up
node down
node " " as left {
node "left" as in_left
}
together {
node "\n\n<b> middle\n\n" as middle
node " " as right {
node "right" as in_right
}
}
middle -u- up
down -u- middle
right -u- up
down -u- right
left -u- up
down -u- left
#enduml

Related

How to get polygon points in Fabric.js

I am drawing polygon by capturing mouse clicks on canvas and then passing these points to fabric.Polygon. So, in this manner I'm drawing multiple polygons.
What I need know is, I want to get the mouse co-ordinates (pixel points on canvas) for the polygon which is selected now?
I have tried with:
canvas.getActiveObject().get('points');
But this is giving some negative and some positive values.
So, can u please tell me a way to find out the polygon points?
Polygon points are relative to its center so you can get their "absolute" position like so:
var polygon = canvas.getActiveObject();
var polygonCenter = polygon.getCenterPoint();
var translatedPoints = polygon.get('points').map(function(p) {
return {
x: polygonCenter.x + p.x,
y: polygonCenter.y + p.y
};
});
Let's check how this looks:
translatedPoints.forEach(function(p) {
canvas.getContext().strokeRect(p.x-5, p.y-5, 10, 10);
});
I think this will only work if polygon's angle is at 0 (otherwise need to "rotate" points coordinates as well).
It looks like that from version 2.0 they changed the coordinates of the polygon. Before 2.0 points relative to the center of the polygon; after 2.0 they are absolute to the canvas;
Check out my response to the similar questions https://stackoverflow.com/a/53710375/4681279

Line width in raphaeljs

Is it real to make line with 1px weight in SVG or raphaeljs?
The follow code
var p = Paper.path("M1 1 L50 1");
p.attr("stroke", "#D7D7D7");
p.attr("stroke-width", "1");
p.attr("opacity", 0.5);
draw line which looks like 2px or 3px. Any alternative?
When SVG lines lie at their apparently correct coordinates they actually lie inbetween pixels, so when you state M1 1 L50 1 it paints half a pixel on the top and the other half in the bottom of the pixel, making it look like a thick, semitransparent line.
To solve this problem you need to either paint at half pixels, or translate your elements half a pixel, ie. element.translate(0.5, 0.5)
You can see the blurry and sharp lines here:
http://jsfiddle.net/k8AKy/
You should also use the Paper.renderfix() function since you do not know which browser your users will be using.
From the documentation
Fixes the issue of Firefox and IE9 regarding subpixel rendering. If
paper is dependant on other elements after reflow it could shift half
pixel which cause for lines to lost their crispness. This method fixes
the issue.
This links take you point what's going wrong with integer coordinates and why +0.5 was fixed edge blurring (with nice pictures!!):
http://diveintohtml5.info/canvas.html#pixel-madness
http://kilianvalkhof.com/2010/design/the-problem-with-svg-and-canvas/
Compare:
with +0.5:
You can avoid +0.5 by:
SVG_Area.setAttribute("viewBox", "0.5 0.5 " + width + " " + height);
or by wrapper:
function fiXY(x) { return parseInt(x) + 0.5; }
var rect = document.createElementNS(SVGobj.svgNS, "rect");
rect.setAttribute("x", fiXY(x));
rect.setAttribute("y", fiXY(y));
or by:
SVG_Area.setAttribute("shape-rendering", "crispEdges");
which effect on all shapes in you SVG image....

how to check if a solid rectangular box is a subset of solid ball

Suppose we have been given the coordinates of the centre of a solid rectangular box, the box's length, breadth, height and a solid ball with a given centre and radius.
Is there a fast way to check if the box is a subset of the ball? The only simple method that comes to my mind is to check if each of the 8 corner vertices lies inside the sphere. If yes, the box is indeed a subset of the ball (by convexity property of the ball).
If you expect that most of the time the box will not be inside the sphere, you can do some quick tests:
if (sphere.center.x+sphere.radius<box.center.x-box.size.x) return false;
if (sphere.center.x-sphere.radius>box.center.x+box.size.x) return false;
etc.
If you expect that the box will usually be far inside the sphere, you can do other quick tests:
bsx = box.size.x;
bsy = box.size.y;
bsz = box.size.z;
box_radius = sqrt(bsx*bsx+bsy*bsy+bsz*bsz)/2;
brx = box.center.x-sphere.center.x;
bry = box.center.y-sphere.center.y;
brz = box.center.z-sphere.center.z;
box_dist = sqrt(brx*brx+bry*bry+brz*brz);
if (box_radius+box_dist<sphere.radius) return true;
You will still need more precise tests if the quick tests fail though.
There are only 4 corners to check, but in fact you only need to check 2 which are diagonal to each other. This follows from the property of the rectangle having straight sides, while the circle is convex, as you state.
Alternatively, consider that if the left upper corner and right lower corner are both within the circle, then the rectangle they form is a boudning box. The circle is obviously not, and thus the rectangle must be a sub-region of the circle.
EDIT: You might be talking about a box and a sphere, in which case the same idea applies, you just have to choose points which have different x, y, and z values

How does one define double-lines for edge and node shapes in graphviz dot?

How can edges and nodes be styled using graphviz dot with doubled lines as shown the in the "LEGAL" and "TAX DISC" nodes of the following diagram?
Doubled shapes can be done by using [peripheries=2] on the node
Doubled edges can be done by specifying more than one colour for the edge, separated by a colon. In this case use the same colour twice: [color="black:black"] (or, to separate them slightly more, do [color="black:invis:black"])
I got there eventually! Sorry for the "evolutionary" nature of this answer :-)
So for example
graph G {
Foo [peripheries=2]
Foo -- Bar [color="black:white:black"]
}
The accepted answer is correct about using the peripheries attribute for multiple node outlines.
However, using the color white to draw widely-separated double edges between nodes is not ideal. If such an edge is drawn over a non-white background or crosses non-white objects, a white line will be visible. It is much better to use one of the colors none or invis. To update part of the example from the accepted answer:
graph G {
Foo [peripheries = 2]
Foo -- Bar [color = "black:invis:black"]
}
See the Graphviz color documentation for more information.
(See other answers about normal edges and nodes)
The three color solution does not work with directed edges with dir="back".
digraph A {
foo -> bar [dir = "back", color = "black:invis:black"];
}
results in this output:
I tried wrapping it with invis layers outside. Looks a bit weird compared to normal arrows because of the increased edge width, but at least it is understandable to readers:
digraph A {
foo -> bar [dir = "back", color = "invis:black:invis:black:invis"];
}
However this won't work with forward edges.

iOS Detect Circular Touches (Clockwise and Counter Clockwise)

I am working on an iOS/iPad educational app that will display a clock with 2 hands (hour and minute). When the user spins there finger on the clock face I want to move the time either forward or backward. This will be a single finger gesture or spinning motion.
Any ideas on how to tell if the user is spinning their finger clockwise or counter clockwise around the circular clock face?
I thought about calculating the angle, then translating the angle into a "section" of say 30 degrees. Then watching the pattern of sections that are tripping.
Just wondering if anyone has a "whiz bang" solution that I am not considering?
Something elegant perhaps?
Thanks.
What you need to do is keep at least three points, then just calculate the area of the "triangle" they form.
CGPoint a = lastStart;
CGPoint b = start;
CGPoint c = end;
float area = a.x * b.y - a.y * b.x + a.y * c.x - a.x * c.y + b.x * c.y - c.x * b.y;
if(area > 0) {
// you're moving CCW
}
Make starting point of the gesture nominal 0,0 and divide the screen into four quadrants with x and y axes running through your nominal 0,0. Note which quadrants get visited, in turn. After the first two, you have the directionality:
Movement into lower right quadrant followed by movement into upper right is counterclockwise
Movement into lower right quadrant followed by movement into lower left is clockwise
Movement into lower left quadrant followed by movement into lower right is counterclockwise
Movement into lower left quadrant followed by movement into upper left is clockwise
Movement into upper left quadrant followed by movement into lower left is counterclockwise
Movement into upper left quadrant followed by movement into upper right is clockwise
etc etc

Resources