Graphviz Sparse Matrix Node Aligment - vertical-alignment

i am trying to graph a sparse matrix with dot language, in fact the node connections are ok, but the problem is the vertical alignment of these nodes, i have tried to use pos and place nodes with x and y values, but just doesn't work (I think because of the default layout). If you can help me a stressed student will thank you. My dot code is bellow and a link of the image generated.
https://github.com/Gualtix/Learn_CPP/blob/master/Matrix.png
Thank you.
digraph Sparce_Matrix {
node [shape=box]
Mt [label = "Matrix" width = 1.5 style = filled, fillcolor = firebrick1];
//(^< ............ ............ ............ ............ ............ U S U A R I O S
U0 [label = "Estructuras" pos = "5.3,3.5!" width = 1.5 style = filled, fillcolor = bisque1];
U1 [label = "Redes" width = 1.5 style = filled, fillcolor = bisque1];
U2 [label = "Compiladores" width = 1.5 style = filled, fillcolor = bisque1];
U3 [label = "Investigacion" width = 1.5 style = filled, fillcolor = bisque1];
U4 [label = "Lenguajes" width = 1.5 style = filled, fillcolor = bisque1];
//(^< ............ Links
U0 -> U1 { constraint = true };
U1 -> U0 { constraint = true };
U1 -> U2 { constraint = true };
U2 -> U1 { constraint = true };
U2 -> U3 { constraint = true };
U3 -> U2 { constraint = true };
U3 -> U4 { constraint = true };
U4 -> U3 { constraint = true };
//(^< ............ ............ ............ ............ ............ A R C H I V O S
A0 [label = "Josefina" width = 1.5 style = filled, fillcolor = lightskyblue];
A1 [label = "Alejandro" width = 1.5 style = filled, fillcolor = lightskyblue];
A2 [label = "Marco" width = 1.5 style = filled, fillcolor = lightskyblue];
A3 [label = "Julian" width = 1.5 style = filled, fillcolor = lightskyblue];
A4 [label = "Pamela" width = 1.5 style = filled, fillcolor = lightskyblue];
//(^< ............ Links
A0 -> A1;
A1 -> A0;
A1 -> A2;
A2 -> A1;
A2 -> A3;
A3 -> A2;
A3 -> A4;
A4 -> A3;
Mt -> U0;
Mt -> A0 { constraint = true };
{ rank = same; Mt; A0; A1; A2; A3; A4; }
//(^< ............ ............ ............ ............ ............ P E R M I S O S
//(^< ............ ............ L E V E L 0
N0_L0 [label = "Jose-Estr" width = 1.5];
N1_L0 [label = "Marc-Estr" width = 1.5];
N2_L0 [label = "Juli-Estr" width = 1.5];
//(^< ............ ............ L E V E L 2
N0_L2 [label = "Marc-Comp" width = 1.5];
N1_L2 [label = "Juli-Comp" width = 1.5];
//(^< ............ ............ L E V E L 4
N0_L4 [label = "Marc-Leng" width = 1.5];
N1_L4 [label = "Juli-Leng" width = 1.5];
N2_L4 [label = "Pame-Leng" width = 1.5];
//(^< ............ ............ ............ ............ ............ L I N K I N G
//(^< ............ ............ L E V E L 0
U0 -> N0_L0;
A0 -> N0_L0;
N0_L0 -> N1_L0;
N1_L0 -> N0_L0;
A2 -> N1_L0;
N1_L0 -> N2_L0;
N2_L0 -> N1_L0;
A3 -> N2_L0;
{ rank = same; U0; N0_L0;N1_L0;N2_L0; }
//(^< ............ ............ L E V E L 2
U2 -> N0_L2;
N0_L2 ->N1_L0;
N1_L0 ->N0_L2;
N0_L2 -> N1_L2;
N1_L2 -> N0_L2;
N1_L2 ->N2_L0;
N2_L0 ->N1_L2;
{ rank = same; U2; N0_L2;N1_L2; }
//(^< ............ ............ L E V E L 4
U4 -> N0_L4;
N0_L4 ->N0_L2;
N0_L2 ->N0_L4;
N0_L4 -> N1_L4;
N1_L4 -> N0_L4;
N1_L4 ->N1_L2;
N1_L2 ->N1_L4;
N1_L4 -> N2_L4;
N2_L4 -> N1_L4;
A4 -> N2_L4;
{ rank = same; U4; N0_L4;N1_L4;N2_L4; }
}
enter code here

The most important tool to get closer to the sparse matrix you want is group:
group
If the end points of an edge belong to the same group, i.e., have the same group attribute, parameters are set to avoid crossings and keep the edges straight.
As your sparse matrix is very sparse, I needed some empty nodes as well. I have also removed [constraint = true] as it is the default anyway. The changes I made are as comments in the source code:
digraph Sparce_Matrix {
node [shape=box]
/* add group 1 for vertical alignment */
Mt[ label = "Matrix", width = 1.5, style = filled, fillcolor = firebrick1, group = 1 ];
/* empty nodes, needed to override graphiz' default node placement */
e0[ shape = point, width = 0 ];
e1[ shape = point, width = 0 ];
//(^< ............ ............ ............ ............ ............ U S U A R I O S
/* groups added for vertical alignment */
U0 [label = "Estructuras" pos = "5.3,3.5!" width = 1.5 style = filled, fillcolor = bisque1, group = 1 ];
U1 [label = "Redes" width = 1.5 style = filled, fillcolor = bisque1, group = 1 ];
U2 [label = "Compiladores" width = 1.5 style = filled, fillcolor = bisque1, group = 1 ];
U3 [label = "Investigacion" width = 1.5 style = filled, fillcolor = bisque1, group = 1 ];
U4 [label = "Lenguajes" width = 1.5 style = filled, fillcolor = bisque1, group = 1 ];
//(^< ............ Links
U0 -> U1;
U1 -> U0;
U1 -> U2;
U2 -> U1;
U2 -> U3;
U3 -> U2;
U3 -> U4;
U4 -> U3;
//(^< ............ ............ ............ ............ ............ A R C H I V O S
/* groups 2 to 6 added for vertical alignment */
A0 [label = "Josefina" width = 1.5 style = filled, fillcolor = lightskyblue, group = 2 ];
A1 [label = "Alejandro" width = 1.5 style = filled, fillcolor = lightskyblue, group = 3 ];
A2 [label = "Marco" width = 1.5 style = filled, fillcolor = lightskyblue, group = 4 ];
A3 [label = "Julian" width = 1.5 style = filled, fillcolor = lightskyblue, group = 5 ];
A4 [label = "Pamela" width = 1.5 style = filled, fillcolor = lightskyblue, group = 6 ];
//(^< ............ Links
A0 -> A1;
A1 -> A0;
A1 -> A2;
A2 -> A1;
A2 -> A3;
A3 -> A2;
A3 -> A4;
A4 -> A3;
Mt -> U0;
Mt -> A0;
{ rank = same; Mt; A0; A1; A2; A3; A4; }
//(^< ............ ............ ............ ............ ............ P E R M I S O S
//(^< ............ ............ L E V E L 0
/* groups 2 to 6 added for vertical alignment */
N0_L0 [label = "Jose-Estr" width = 1.5, group = 2 ];
N1_L0 [label = "Marc-Estr" width = 1.5, group = 4 ];
N2_L0 [label = "Juli-Estr" width = 1.5, group = 5 ];
//(^< ............ ............ L E V E L 2
N0_L2 [label = "Marc-Comp" width = 1.5, group = 4 ];
N1_L2 [label = "Juli-Comp" width = 1.5, group = 5 ];
//(^< ............ ............ L E V E L 4
N0_L4 [label = "Marc-Leng" width = 1.5, group = 4 ];
N1_L4 [label = "Juli-Leng" width = 1.5, group = 5 ];
N2_L4 [label = "Pame-Leng" width = 1.5, group = 6 ];
//(^< ............ ............ ............ ............ ............ L I N K I N G
//(^< ............ ............ L E V E L 0
U0 -> N0_L0;
A0 -> N0_L0;
N0_L0 -> N1_L0;
N1_L0 -> N0_L0;
A2 -> N1_L0;
N1_L0 -> N2_L0;
N2_L0 -> N1_L0;
A3 -> N2_L0;
{ rank = same; U0; N0_L0;N1_L0;N2_L0; }
//(^< ............ ............ L E V E L 2
U2 -> N0_L2;
N0_L2 ->N1_L0;
N1_L0 ->N0_L2;
N0_L2 -> N1_L2;
N1_L2 -> N0_L2;
N1_L2 ->N2_L0;
N2_L0 ->N1_L2;
{ rank = same; U2; N0_L2;N1_L2; }
//(^< ............ ............ L E V E L 4
U4 -> N0_L4;
N0_L4 -> N0_L2;
N0_L2 -> N0_L4;
N0_L4 -> N1_L4;
N1_L4 -> N0_L4;
N1_L4 -> N1_L2;
N1_L2 -> N1_L4;
N1_L4 -> N2_L4;
N2_L4 -> N1_L4;
{ rank = same; U4; N0_L4;N1_L4;N2_L4; }
/* we divide the edge from A4 to N2_L4 into 'sub-edges',
thus indirectly making sure that the U nodes stay in their place */
{ rank = same; U2; e0 }
{ rank = same; U3; e1 }
A4 -> e0 -> e1[ dir = none ];
e1 -> N2_L4;
}
yields

Related

Haskell Function not accepting argument

I wrote a simple code to convert rgb to cmyk. Then I defined the datatype Color.
now I got this error:
Couldn't match expectet type `Color' with actual type `(t0, t1, t2)'
I thought Color would refer to Rgb(Int,Int,Int). What I have done wrong?
My code:
data Color = Rgb (Int,Int,Int) | Cmyk Double Double Double Double deriving (Show)
rgb2cmyk :: Color -> Color
rgb2cmyk (Rgb (0,0,0)) = (Cmyk 0 0 0 1)
rgb2cmyk (Rgb (r,g,b)) = (Cmyk c m y k)
where
rd = (fromIntegral r)/255
gd = (fromIntegral g)/255
bd = (fromIntegral b)/255
w = max3 rd gd bd
c = w - rd/w
m = w - gd/w
y = w - bd/w
k = 1 - w
max3 :: Double -> Double -> Double -> Double
max3 a b c | a>=b && a>=c = a
| b>=a && b>=c = b
| otherwise = c
test1 = rgb2cmyk 233 123 123
Error occours in test1 line. Do I have to write rgb2cmyk $ Rgb?
I would suggest to keep the syntax, keep Rgb Int Int Int instead of Rgb (Int,Int,Int)
data Color = Rgb Int Int Int | Cmyk Double Double Double Double deriving (Show)
rgb2cmyk :: Color -> Color
rgb2cmyk (Rgb 0 0 0) = (Cmyk 0 0 0 1)
rgb2cmyk (Rgb r g b) = (Cmyk c m y k)
where
(...)
*Main> rgb2cmyk $ Rgb 0 0 0
Cmyk 0.0 0.0 0.0 1.0
Explaining the comment:
You cant call rgb2cmyk as rgb2cmyk x y z, the function is expecting an Rgb x y z so you must call it as rgb2cmyk Rgb 10 10 10 for example. Rgb is a Color is a constructor and either Rgb or Cmyk must be called if your function takes a Color.

Can't match expected type

On the call of coordenadas = criaCoordenada(num_col, width, height) I'm getting the error for the 3 variables:
Couldn't match expected type `Integer' with actual type `Float'
In the expression: num_col
In the first argument of `criaCoordenada', namely
`(num_col, width, height)'
type Point = (Float,Float)
type Rect = (Point,Float,Float)
writeRect :: (String,Rect) -> String
writeRect (style,((x,y),w,h)) =
printf "<rect x='%.3f' y='%.3f' width='%.2f' height='%.2f' style='%s' />\n" x y w h style
writeRects :: Float -> Float -> [(String,Rect)] -> String
writeRects w h rs =
printf "<svg width='%.3f' height='%.2f' xmlns='http://www.w3.org/2000/svg'>\n" w h
++ (concatMap writeRect rs) ++ "</svg>"
criaPosicoes :: (Integer, Integer) -> [Float]
criaPosicoes (num_col, x) = [fromIntegral x | x <-[0,x..(x*num_col)] ]
criaCoordenada :: (Integer, Integer, Integer) -> [Point]
criaCoordenada (col, w, h) =
let
lx = criaPosicoes (col, w)
ly = criaPosicoes (col, h)
in
[(x,y) | y <- ly, x <- lx]
main :: IO ()
main = do
let
(num_lin, num_col) = (5, 5) -- Número de linha / coluna do retângulo maior.
(width, height) = ( 41,19 ) -- Width / Height do retângulo colorido.
(w, h) = ( (width * num_col), (height * num_col) ) -- Width / Height do SVG.
coordenadas = criaCoordenada(num_col, width, height) --Error here
style = "fill:hsl(20, 20%, 30%);stroke:rgb(156,156,139)"
rects = [ (style, (( 0, 0), width, height))
, (style, (( 41, 0), width, height))
, (style, (( 82, 0), width, height))
, (style, ((123, 0), width, height))
, (style, ((164, 0), width, height))
]
writeFile "colors.svg" $ writeRects w h rects
I know what the error means but I have no idea why...
The compiler inferred w and h to be Float because writeRects says they are. So also width, num_col and height are inferred to be Float because of (w, h) = ( (width * num_col), (height * num_col) ). That results in a type conflict in criaCoordenada(num_col, width, height) because Floats are passed to criaCoordenada which says it expects Integers.

Rendering a texture on screen

I'm new to both Haskell and OpenGL and I'm trying to render a texture on the screen.
Here's what I've got so far:
makeTexture :: FilePath -> IO GL.TextureObject
makeTexture f = do
t <- either error id <$> GLU.readTexture f
GL.textureFilter GL.Texture2D GL.$= ((GL.Linear', Nothing), GL.Linear')
GLU.texture2DWrap GL.$= (GL.Mirrored, GL.ClampToEdge)
return t
renderEntity :: Entity -> IO ()
renderEntity e = do
GL.activeTexture GL.$= GL.TextureUnit 0
GL.textureBinding GL.Texture2D GL.$= Just (texture $ model e)
-- I see a white triangle on the screen.
renderTriangle $ fmap (vadd $ position e) (points $ model e :: [Vector2])
-- I do not see this. Nor is the triangle textured either.
GL.renderPrimitive GL.Quads $ do
n 0 1 0
t 0 1 >> v 10 (-10) 10
t 1 1 >> v 10 (-10) (-10)
t 1 0 >> v (-10) (-10) (-10)
t 0 0 >> v (-10) (-10) 10
where v x y z = GL.vertex (GL.Vertex3 x y z :: GL.Vertex3 GL.GLfloat)
n x y z = GL.normal (GL.Normal3 x y z :: GL.Normal3 GL.GLfloat)
t u v = GL.texCoord (GL.TexCoord2 u v :: GL.TexCoord2 GL.GLfloat)
Where Entity looks like:
texMetal <- makeTexture "texture/metal.jpg"
let
entity = Entity
{ angle = 0
, position = (0, 0) :: Vector2
, velocity = (5, 5) :: Vector2
, model = Model
{ points = [(-60, -40), (60, -40), (0, 60)] :: [Vector2]
, texture = texMetal
}
}
And when I'm initializing I have these:
GL.viewport GL.$= (pos, size)
GL.matrixMode GL.$= GL.Projection
GL.texture GL.Texture2D GL.$= GL.Enabled
GL.normalize GL.$= GL.Enabled
GL.loadIdentity
GL.ortho2D (-fromIntegral width / 2)
(fromIntegral width / 2)
(-fromIntegral height / 2)
(fromIntegral height / 2)
GL.matrixMode GL.$= GL.Modelview 0
GL.loadIdentity
And the resulting picture:
It has two triangles because I have two 'entities' set in my code. But I don't see my quad nor do I see any sign of texturing.
It seems I had incorrect coordinates, because this works well:
renderEntity :: Entity -> IO ()
renderEntity e = do
GL.activeTexture GL.$= GL.TextureUnit 0
GL.textureBinding GL.Texture2D GL.$= Just (texture $ model e)
GL.renderPrimitive GL.Quads $ do
v 100 100
t 0 1
v 100 (-100)
t 1 1
v (-100) (-100)
t 1 0
v (-100) 100
t 0 0
where v x y = GL.vertex (GL.Vertex2 x y :: GL.Vertex2 GL.GLfloat)
t u v = GL.texCoord (GL.TexCoord2 u v :: GL.TexCoord2 GL.GLfloat)

Is it possible to use a rgY color space?

Would it be possible to take a rgY color space:
r = R / (R + G + B)
g = G / (R + G + B)
Y = R * 0.299 + G * 0.587 + B * 0.114
(unnecessary) b = 1 - r - g
and convert it back to RGB? If so, how would it be done?
(No factorials are in this answer. The syntax is similar to Wolfram-Alpha plain text output standards, exception being spaces are placed before and after the != [not equals] sign and the use of 'if [conditional] then' statements.)
if r = 0 and 473 g+114 != 0 and Y != 0 then
R = 0 and G = (1000 g Y)/(473 g+114) and B = -(1000 (g-1) Y)/(473 g+114)
if Y = 0 and g = 1/473 (-185 r-114) and r != 0 then
G = -((185 r+114) R)/(473 r) and B = ((587-288 r) R)/(473 r) and R!=0
if Y = 0 and r = 0 and g = -114/473 then
R = 0 and B = -(587 G)/114 and G!=0
if 473 g+185 r+114 != 0 and r != 0 and r Y != 0
R = (1000 r Y)/(473 g+185 r+114) and G = (1000 g Y)/(473 g+185 r+114) and B = -(1000 Y (g+r-1))/(473 g+185 r+114)

Equation for Sliding Collision of LineSegments

I need an equation to find point F.
Point A, B, and D are known. Point F is unknown. Point F is on line AB. Line AB is perpendicular to line DF. What is the equation for F?
I'm assuming you want something computationally fast, since you mention 'collision', and this is Stack Overflow. First, a diagram:
We want to calculate the components of AF, which we'll label f = qi + pj. AFD forms a triangle, so we can get the length of f from AD, which we'll label d. Let's mark lengths in italics versus vectors in bold:
f = d cos(θ).
But trig is computationally expensive. So let's use the fact that the vector dot product between b (AB) and d is:
b · d = b d cos(θ)
The angle is the same because AF and AB are on the same line. Substituting in for dcos(θ):
b · d = b f
f = (b · d) / b
Now we have f, but we want its components p and q. Calling the angle to the horizontal φ:
q = f cos(φ)
p = f sin(φ)
But again we're avoiding trig. We know that f is along b, so f = kb, and in fact using the unit vector in the direction of b:
f = f (b/b)
Substituting our expression for f:
f = [(b · d) / b ] (b/b)
= [(b/ b) · d ] (b/b)
= [b · d] b / (b2)
Defining a factor k which is common to both components:
k = (bx dx + by dy) /b2
By keeping the b2 separate, we can avoid a square root operation to get the unit vector along b
Our components, then:
q = k bx
p = k by
Finally, add back in the offset of point A.
Fx = Ax + q
Fy = Ay + p
So, the pseudo code:
var vbx = Bx - Ax; //vector b x component
var vby = By - Ay; //vector b y component
var dot = vbx*(Dx-Ax) + vby*(Dy-Ay); // dot product of b and d
var k = dot/(vbx*vbx + vby*vby); // inverse of square of vector b length
var fx = Ax + k*vbx
var fy = Ay + k*vby
No square root calls, no trig, 8 additions/subtractions, 6 multiplications, 1 division. The only instabilities I can see are: divide by zero when A and B are at the same position, possible overflow calculating dot if AB is large and AD is large.
First, find the slope of line AB with the point-slope formula using A and B's coordinates:
Point Slope Formula
You can then find b to finished the equation for line AB:
y = mx + b where m is the slope you already found and b is the y-intercept that you just found.
The slope of line DF would be the negative reciprocal of the slope of line AB. Plug this into the equation:
y = mx + b where m is the negative reciprocal of the slope of line AB and b comes later.
Now, solve for b using the x and y values of point D, and plug that into the equation.
You should now have an equation for line DF and another equation for line AB. Now solve for the intercept of the two equations by setting them equal to one another and solving for x first and then plugging in x and finding y.
Here's an example.
A = (1, 2). B = (4, 8). D = (2, 5).
Line AB:
(y - y1) = m*(x - x1)
(1 - 4) = m*(2 - 8)
-3 = m*(-6)
0.5 = m
y = (0.5)*x + b
2 = (0.5)*1 + b
2 = (0.5) + b
1.5 = b
y = 0.5*x + 1.5
Line DF:
m = -(1/mAB)
m = -(1/0.5)
m = -2
y = -2*x + b
5 = -2*2 + b
5 = -4 + b
9 = b
y = -2*x + 9
Intersection of AB and DF (i.e. coordinates of point F)
Line DF: y = -2*x + 9
Line AB: y = 0.5*x + 1.5
-2*x + 9 = 0.5*x + 1.5
9 = 2.5*x + 1.5
7.5 = 2.5*x
x = 3
y = -2*x + 9
y = -2*3 + 9
y = -6 + 9
y = 3
F = (3, 3)
You haven't specified exactly where point F is along line DF, so there's no single answer. If you're just trying to find SOME point along a line perpendicular to line AB, from point D, then
F.x = D.x + (B.y - A.y)
F.y = D.y + (B.x - A.x)
will work.

Resources