In graphviz I would like to have an edge that doesn't cross the node.
Here is my graph:
digraph G {
rankdir=LR;
fontname = "Bitstream Vera Sans";
fontsize = 8;
node [
fontname = "Bitstream Vera Sans"
fontsize = 8
shape = "record"
];
edge [
fontname = "Bitstream Vera Sans"
fontsize = 8
];
MethodContext [
label = "{ <head> MethodContext | <parent> parent \l| nativeIP \l | ip \l| sp \l| receiver \l| method \l| flags \l| Temp Var 1 \l Temp Var 2 \l ... \l Temp Var n \l| Stack \l ... \l Stack \l }"
];
MethodContext:parent -> MethodContext:head [tailport=e];
}
Without the tailport I got a nice vertical graph except that the edge is crossing the node. But as soon as I add [tailport=e] like in the example my graph is horizontal and the edge is still crossing the node.
How could I keep the node vertical and have the edge attached to the right side?
Thanks
Who ever want to know the solution is
MethodContext:parent -> MethodContext:head:e;
Related
I am trying to draw a minimap from a randomly generated matrix that represents my level.
To do so, I am drawing black or white little squares one by one to represent the matrix visually (I don't know if it the best way to do that with phaser, actually, I am a beginner with this framework).
The map draws correctly but its position is bound to the world not to camera, so when I move it is not visible anymore.
Here is the code I use to draw the map:
generate() {
let wallsGraphics = this._scene.add.graphics({fillStyle : {color : LabyrinthConfig.MAPS.MINI_MAP.WALLS_COLOR}});
let pathGraphics = this._scene.add.graphics({fillStyle : {color : LabyrinthConfig.MAPS.MINI_MAP.PATH_COLOR}});
// Draw the map
let y = 0;
for (let line of this._matrix) {
let x = 0;
for (let cell of line) {
let rect = new Phaser.Geom.Rectangle();
rect.width = LabyrinthConfig.MAPS.MINI_MAP.CELL_WIDTH;
rect.height = LabyrinthConfig.MAPS.MINI_MAP.CELL_HEIGHT;
rect.x = LabyrinthConfig.MAPS.MINI_MAP.POSITION_X + x * LabyrinthConfig.MAPS.MINI_MAP.CELL_WIDTH;
rect.y = LabyrinthConfig.MAPS.MINI_MAP.POSITION_Y + y * LabyrinthConfig.MAPS.MINI_MAP.CELL_HEIGHT;
cell === 0 ? wallsGraphics.fillRectShape(rect) : pathGraphics.fillRectShape(rect);
x++;
}
y++;
}
}
Any help on how to fix this map to the camera view ?
Set scroll factor of your graphics objects to 0.
wallsGraphics.setScrollFactor(0);
pathGraphics.setScrollFactor(0);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
What would be the typical game skeleton for a Haskell game, let's say a simple shoot them up for instance?
I am particularly interested on the data structure, and how to manage the update of all the elements in the world, in regards of immutability issue.
Just saying that
new_world=update_world(world)
is a little bit simplistic. For instance, how to deal with multiple interaction that can occurs between element of the world (collisions, reaction to player, etc....) especially when you have a lot of 'independent' elements impacted.
The main concern is about immutability of the world, which makes very difficult to update a "small" part of the world based on another subset of the world.
I love gloss (gloss 2D library. it's very closed to your needs (I think)
A very simple example
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
-- Your app data
data App = App { mouseX :: Float
, mouseY :: Float
}
-- Draw world using your app data
-- Here thing about *draw* your world (e.g. if radius > MAX then red else blue)
drawWorld (App mousex mousey) = color white $ circle mousex
-- Handle input events and update your app data
-- Here thing about user interaction (e.g. when press button start jump!)
handleEvent
(EventMotion (x, y)) -- current viewport mouse coordinates
(App _ _) = App x y
handleEvent e w = w
-- Without input events you can update your world by time
-- Here thing about time (e.g. if jumping use `t` to compute new position)
handleTime t w = w
runApp =
play
( InWindow "Test" (300, 300) (0, 0) ) -- full screen or in window
black -- background color
20 -- frames per second
( App 0 0 ) -- your initial world
drawWorld -- how to draw the world?
handleEvent -- how app data is updated when IO events?
handleTime -- how app data is updated along the time?
-- enjoy!
main = runApp
One simple example modifying some data structure (a list of circle radius) along the three event handlers (draw, input and time)
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
import System.IO.Unsafe
data App = App { mouseX :: Float
, mouseY :: Float
, circleList :: [Float]
, lastTime :: Float
, currTime :: Float
}
drawWorld app =
color white $ pictures $ map circle $ circleList app
handleEvent
(EventMotion (x, y)) -- current viewport mouse coordinates
app = app { mouseX = x, mouseY = y,
-- drop circles with radius > mouse **MOVED** position
circleList = filter (<(abs x)) $ circleList app }
handleEvent e app = app
handleTime t app =
app { currTime = currTime', lastTime = lastTime', circleList = circleList' }
where currTime' = currTime app + t
-- create new circle each 1 second
createNew = currTime' - lastTime app > 1
lastTime' = if createNew then currTime' else lastTime app
-- each step, increase all circle radius
circleList' = (if createNew then [0] else []) ++ map (+0.5) (circleList app)
runApp =
play
( InWindow "Test" (300, 300) (0, 0) )
black
20
( App 0 0 [] 0 0 )
drawWorld
handleEvent
handleTime
main = runApp
with result
I'm brand new to svg and thought I would try out snap svg. I have a group of circles that I am dragging around, and am looking to get the coordinates of the group. I am using getBBox() to do this, but it isn't working as I would expect. I would expect getBBox() to update its x and y coordinates but it does not seem to do that. It seems simple but I think I am missing something. Here's the code
var lx = 0,
ly = 0,
ox = 0,
oy = 0;
moveFnc = function(dx, dy, x, y) {
var thisBox = this.getBBox();
console.log(thisBox.x, thisBox.y, thisBox);
lx = dx + ox;
ly = dy + oy;
this.transform('t' + lx + ',' + ly);
}
startFnc = function(x, y, e) { }
endFnc = function() {
ox = lx;
oy = ly;
console.log(this.getBBox());
};
var s = Snap("#svg");
var tgroup = s.group();
tgroup.add(s.circle(100, 150, 70), s.circle(200, 150, 70));
tgroup.drag(moveFnc, startFnc, endFnc);
The jsfiddle is at http://jsfiddle.net/STpGe/2/
What am I missing? How would I get the coordinates of the group? Thanks.
As Robert says it won't change. However getBoundingClientRect may help.
this.node.getBoundingClientRect(); //from Raphael
Jsfiddle here showing the difference http://jsfiddle.net/STpGe/3/.
Edit: Actually I'd be tempted to go here first, I found this very useful Get bounding box of element accounting for its transform
Per the SVG specification, getBBox gets the bounding box after transforms have been applied so in the co-ordinate system established by the transform attribute the position is the same.
Imagine like you drew the shape on graph paper setting a transform moves the whole graph paper but when you look at position of the shape on the graph paper it hasn't changed, it's the graph paper that's moved but you're not measuring that.
Try to use the group.matrix object to get x and y coordinate of group object.
moveFnc = function(dx, dy, x, y, event) {
lx = this.matrix.e;
ly = this.matrix.f;
this.transform('translate(' + lx + ',' + ly+')');
}
The imageviewer example shows how to display an image in a ScrolledWindow.
What if I want to display the image in the available space, scaling the bitmap as needed?
My google-fu failed me on this one.
edit: I thought I had something with scrolledWindowSetScale, but it looks like it's not going to help here.
Some people pointed me to functions in wxCore, so I could find a solution that works.
The function that does the drawing in the original example is:
onPaint vbitmap dc viewArea
= do mbBitmap <- get vbitmap value
case mbBitmap of
Nothing -> return ()
Just bm -> drawBitmap dc bm pointZero False []
using dcSetUserScale from wxCore, I was able to modify it to scale that way:
( sw is the scrolledWindow )
onPaint sw img dc viewArea = do
mimg <- get img value
case mimg of
Nothing -> return ()
Just bm -> do
bsize <- get bm size
vsize <- get sw size
let scale = calcScale bsize vsize
dcSetUserScale dc scale scale
drawBitmap dc bm pointZero False []
calcScale :: Size -> Size -> Double
calcScale (Size bw bh) (Size vw vh) = min scalew scaleh
where scalew = fromIntegral vw / fromIntegral bw
scaleh = fromIntegral vh / fromIntegral bh
I want to make a haskell program where some shape is drawn in a window. When I click inside the window the color of the shape should change.
I have come up with this:
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
colorRef <- newIORef Green
let
loop0 = do
color <- readIORef colorRef
e <- getWindowEvent w
case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> writeIORef colorRef Red
| isDown && color == Red -> writeIORef colorRef Green
_ -> return ()
color <- readIORef colorRef
drawInWindow w (withColor color (polyline points))
loop0
color <- readIORef colorRef
drawInWindow w (withColor color (polyline points))
loop0
It kinda works.
The problem is, that I think that a window event is triggered almost all the time, so everything is drawn all the time which makes it slow.
How could I make it so, that I only change the drawing when a click is registered?
First of all, getWindowEvent will block until the next event occurs, so everything is drawn only on event. If you think that a window event is triggered too often, then you can print events to the stdout to figure out what event is triggered and just ignore it (e.g. skip drawing on all the events except Button event).
BTW: you don't IORef, you can just pass the current color through the loop.
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
let
loop0 color = do
e <- getWindowEvent w
let newColor = case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> Red
| isDown && color == Red -> Green
_ -> color
when (newColor != color) (drawInWindow w (withColor color (polyline points)))
loop0 color
let color = Red
drawInWindow w (withColor color (polyline points))
loop0 color
(The code is not tested with the compiler, so...)
Thanks for the answer.
I modified the code slightly according to my understanding of what it should do.
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
let
loop0 color = do
e <- getWindowEvent w
let newColor = case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> Red
| isDown && color == Red -> Green
_ -> color
when (newColor /= color) (drawInWindow w (withColor newColor (polyline points)))
loop0 newColor
let color = Green
drawInWindow w (withColor color (polyline points))
loop0 color
The results are a bit sketchy though. Sometimes the color changes immediately and sometimes it takes a very long time. I believe it could be some update issue, because when I close a window I see an issued color-change happen just before the window is gone.
Any ideas?
It helps if I call clearWindow before I draw the new stuff. I don't really understand why. Does it schedule a redraw of the window maybe?
Would be nice to know, but in general the problem is solved for now.