How to achieve similar functionality to Matlab's fill3 function and output to SVG in ILNumerics - ilnumerics

I am trying to achieve something similar to Matlab's fill3 function in ILNumerics and output to an SVG file. fill3 allows you to plot 3d shapes with a solid fill color and specify an edge color for the shapes that you are plotting.
The code that I am using to plot the shapes is as follows:
var scene = new ILScene();
scene.Camera.Add(new ILTriangles
{
Positions = new float[,]
{
{-1, -1, -1}, {-1, 1, -1}, {0, 1, 0},
{-1, -1, -1}, {0, 1, 0}, {0, -1, 0},
{0, -1, 0}, {0, 1, 0}, {1, 1, -1},
{0, -1, 0}, {1, 1, -1}, {1, -1, -1}
},
Color = Color.Red,
AutoNormals = false
});
scene.Camera.Add(new ILLines
{
Positions = new float[,]
{
{-1, -1, -1}, {-1, 1, -1}, {0, 1, 0}, {0, -1, 0}
},
Indices = new[] {0, 1, 1, 2, 2, 3, 3, 0},
Color = Color.Black,
Width = 3
});
scene.Camera.Add(new ILLines
{
Positions = new float[,]
{
{0, -1, 0}, {0, 1, 0}, {1, 1, -1}, {1, -1, -1}
},
Indices = new[] { 0, 1, 1, 2, 2, 3, 3, 0 },
Color = Color.Black,
Width = 3
});
ilPanel1.Scene = scene;
The code that I am using to output to SVG is as follows:
using (var fs = new FileStream(#"C:\test.svg", FileMode.Create))
{
new ILSVGDriver(fs, scene: ilPanel1.GetCurrentScene(), width: 500, height: 600).Render();
}
The result looks perfect in the ILPanel, but when rendered to an SVG the triangle shapes seem to step on/cover the lines.
Is there another way to go about this to achieve what I am looking for? Thanks!

ILNumerics renders all filled shapes based on triangles. This gives the most flexibility and corresponds to the way all 3D engines basically work. SVG on the other side is designed as a 2D description format. It knows more shapes than only triangles - what makes sense and is efficient if you are in 2D space. In theory you can always assemble any polygon out of triangles. This is what is done at the very low level end in all renderers I guess (OpenGL at least does so).
Now, the problem is, all popular SVG renderer today try to be "nice looking". I.e. they render edges antialiased. Antialiasing involves transparency. And transparency involves a change of color. If you try to draw adjacent edges antialiased you end up with the result you obtain: The color on the edge will vary slightly, leaving an imaginary line where a solid colored area is expected.
This is an limitation of SVG - not of ILNumerics. If you want to use SVG in order to create solid filled polygon shapes, you need to 'design' by using those shapes provided by SVG. If you observe different results in SVG files created by other libs, post these SVG as an example here in order for us to inspect them. I am pretty sure they will not use triangles. (?)

Related

Visualization failed when display two polygon in the same time

I want to display two polygons in one renderer. And the result is:
The green and red color indicates two polygons.
However, when I rotate it, some part of green color disappear:
My environment is:
win 10
python 3.7.13
vtk: 9.2.4
I can 100% reproduce this phenomenon, and the code to reproduce my problem is:
import vtkmodules.all as vtk
def buildPolygon(points):
polydata = vtk.vtkPolyData()
vps = vtk.vtkPoints()
polygon = vtk.vtkPolygon()
polygon.GetPointIds().SetNumberOfIds(len(points))
for i in range(len(points)):
vps.InsertNextPoint(points[i][0], points[i][1], points[i][2])
polygon.GetPointIds().SetId(i, i)
polygons = vtk.vtkCellArray()
polygons.InsertNextCell(polygon)
polydata.SetPoints(vps)
polydata.SetPolys(polygons)
return polydata
polydata1 = buildPolygon([
[0, 0, 0],
[10, 0, 0],
[10, 10, 0],
[0, 10, 0]
])
map1 = vtk.vtkPolyDataMapper()
map1.SetInputData(polydata1)
actor1 = vtk.vtkActor()
actor1.SetMapper(map1)
actor1.GetProperty().SetColor(1, 0, 0)
polydata2 = buildPolygon([
[0, 0, 0],
[5, 0, 0],
[5, 5, 0],
[0, 5, 0]
])
map2 = vtk.vtkPolyDataMapper()
map2.SetInputData(polydata2)
actor2 = vtk.vtkActor()
actor2.SetMapper(map2)
actor2.GetProperty().SetColor(0, 1, 0)
render = vtk.vtkRenderer()
render.AddActor(actor1)
render.AddActor(actor2)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(render)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
iren.Initialize()
iren.Start()
As they lie exactly on the same plane z=0 there is no way to know which should be drawn on top of the other. Just add a small tolerance:
polydata2 = buildPolygon([
[0, 0, 0.001],
[5, 0, 0.001],
[5, 5, 0.001],
[0, 5, 0.001]
])

OR-Tools: how to define node that not possible to visit in VRP/CVRP/VRPTW?

im trying this vrp example
From my understanding, we must have 2d array to define distance matrix between all nodes
But for my demand, there is few nodes wont have distance matrix between, like this graph
The distance matrix array will be:
public final long[][] distanceMatrix = {
{0, 2, 1, 0, 0},
{0, 0, 0, 2, 1},
{0, 1, 0, 0, 0},
{0, 0, 0, 0, 3},
{0, 0, 0, 0, 0},
};
The issue is that for the distance matrix array, we must have int number between all nodes, so for two nodes that dont have direct path between (like A->D) i use 0, but OrTool will understand the cost to travel between those two nodes is zero. and the solver always choose that path to go.
So is there any support from ortool library to declare this kind on directional graph?
Thanks
To forbid an arc you have basically two ways:
Using a Distance Dimension and a value above the vehicle max capacity.
e.g. suppose you have a distance dimension:
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.AddDimension(
transit_callback_index,
0, # no slack for distance, can be use as waiting time for Time dimension
42, # maximum distance a vehicle can travel
True, # force start cumul to zero, i.e. vehicle start a km 0
"Distance"
)
...
As you can see, here 42 is the limit for vehicles SO if in your distance matrix you use 43 no vehicle could take this arc since it is above the vehicle capacity (ed above the upper bound of the CumulVar domain).
Thus you could write your distance matrix as:
public final long[][] distanceMatrix = {
{43, 2, 1,43,43},
{43,43,43, 2, 1},
{43, 1,43,43,43},
{43,43,43,43, 3},
{43, 3,43,43,43},
};
note: your SetArcCost() and AddDimension() can use the same registered evaluator.
You can set the list of allowed next nodes.
For each node you can define a list a allowed nodes (by default all nodes)
e.g. here you have:
next = {
[A, [B, C]],
[B, [E, D]],
[C, [B]],
[D, [E]],
[E, []]}
note(instead of A-E you must use 0-4)
Then you can use:
for node, l in next:
node_index = manager.NodeToIndex(node)
next_indices = [node_index] # need itself in case node is dropped
for next_node in l:
next_indices.append(manager.NodeToIndex(next_node))
routing.NextVar(node_index).SetValues(next_indices)
Instead of 0, I would try to initialize those nodes with an unaffordable cost, eg int64.Maxvalue

Polygons transparency

I need to bind texture on 2 crossed polygons and make them(polygons) invisible (with alpha=0). But textures are transparent with polygons.
Is is possible to make transparent only polygons without their textures?
By this way i bind textute
Gl.glEnable(Gl.GL_BLEND);
Gl.glEnable(Gl.GL_ALPHA_TEST);
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
Gl.glColor4d(255,255,255,0.1);
Gl.glBegin(Gl.GL_QUADS);
Gl.glTexCoord2f(1, 0); Gl.glVertex3d(2, 2, 3);
Gl.glTexCoord2f(0, 0); Gl.glVertex3d(4, 2, 3);
Gl.glTexCoord2f(0, 1); Gl.glVertex3d(4, 4, 3);
Gl.glTexCoord2f(1, 1); Gl.glVertex3d(2, 4, 3);
Gl.glEnd();
Image
I need smth like on the left part of the img.
I found the solution.
Load png!! image
GL.glBindTexture(GL.GL_TEXTURE_2D, this.texture[i]);
Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
Gl.glAlphaFunc(Gl.GL_LESS, 0.2f);
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, (int)Gl.GL_RGBA, image[i].Width, image[i].Height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
And drow object:
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
GL.glEnable(GL.GL_BLEND); // Enable Blending
GL.glDisable(GL.GL_DEPTH_TEST);
GL.glBlendFunc(Gl.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
GL.glBindTexture(GL.GL_TEXTURE_2D, texture[0]);
Gl.glBegin(Gl.GL_QUADS);
Gl.glTexCoord2f(1, 0); Gl.glVertex3d(2, 2, 3);
Gl.glTexCoord2f(0, 0); Gl.glVertex3d(4, 2, 3);
Gl.glTexCoord2f(0, 1); Gl.glVertex3d(4, 6, 3);
Gl.glTexCoord2f(1, 1); Gl.glVertex3d(2, 6, 3);
Gl.glEnd();
And you will get your image without any background.

Microsoft charting stacked area still visible even when y-values are all 0

Here is my problem. Let's say I have 2 stacked area series and their data looks like this :
Series A (Color blue) :
X values {1, 2, 3, 4}
Y values {4, 6, 7, 6}
Series B (Color red) :
X values {1, 2, 3, 4}
Y values {0, 0, 0, 0}
If I had these 2 series to a chart (A first and B second), there is still a red line that appears on top of the blue area even if all the y-values of the B series are 0. Is there a way to make sure that the red line doesn't appear in the graph without removing the B-series from the legend?
Format the data series to have a fill only and no border. If the areas have a border, it will show even if the values are 0.

How to use vertex buffer objects (VBO) instead of calling glDrawArrays thousands of times in OpenGL ES 1.0 on iOS?

For a simulation we've created a OpenGL1.1 view with a grid of 32 x 48 rectangles.
We're drawing this grid every time the CADisplayLink calls our draw function, and the vertex positions never change. The only thing that changes from frame to frame is the color of a vertex.
This is a simplified example of how we do it:
- (void)drawFrame {
// draw grid
for (int i = 0; i < numRectangles; i++) {
// ... calculate CGPoint values for vertices ...
GLshort vertices[ ] = {
bottomLeft.x, bottomLeft.y,
bottomRight.x, bottomRight.y,
topLeft.x, topLeft.y,
topRight.x, topRight.y
};
glVertexPointer(2, GL_SHORT, 0, vertices);
glColor4f(r, g, b, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
}
The OpenGL instrument recommended using Vertex Buffer Objects (VBO) for better performance.
Is there an example of how to set up a very basic, simple usage of Vertex Buffer Objects in a case where the vertices don't change from frame to frame?
Apple is providing an example over here, under the section Use Vertex Buffer Objects to Manage Copying Vertex Data, but it's incomplete.
GLuint vertexBuffer;
GLuint indexBuffer;
void CreateVertexBuffers()
{
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
It doesn't show how to really create the data. The previous listing (which is supposed to be a "bad example") contains these two lines:
const vertexStruct vertices[] = {...};
const GLubyte indices[] = {...};
So these two arrays or structs have to be passed into:
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
and
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
?
Is this the "Interleaved (array of structs)" format preferred by iOS, according to Apple under the Use Interleaved Vertex Data section?
You're not supposed to draw single primitives using glDrawArrays, but large batches. So far you're using only regular vertex arrays, not vertex buffer objects.
The idea is, to put the geometry off all rectangles into one single VBO (a VBO is essentially a vertex array stored "in" OpenGL, rather your process). Changing single vertices is possible by using glBufferSubData.
Vertex color can be put into a vertex array, and hence into a VBO as well.
Update
Say you have some hexagon:
GLfloat vertices[2][] = {
{0, 0}, // 0
{1, 0}, // 1
{0.5, 0.866}, // 2
{-0.5, 0.866}, // 3
{-1, 0}, // 4
{0.5, -0.866}, // 5
{-0.5, -0.866}, // 6
};
and you want to draw only part of the triangles, say the triangles consisting of vertices [0,1,2], [0,3,4] and [0,5,6], then you'd create the following index array
GLushort indices[] = {
0, 1, 2,
0, 3, 4,
0, 5, 6
};
And use that as the indices for glDrawElements.
Update 2
One thing that many computer graphics and OpenGL newbies get wrong is, that a vertex is not merely a position, but a combination of vertex attributes. Which attributes make a vertex is a design choice made by the programmer. But the commonly used vertex attributes are
position
normal
texture coordinates
vertex color
Until OpenGL-3 core the position attribute was mandatory. Since OpenGL-3 core, which made shaders mandatory, vertex attributes are just arbitrary input data into shaders, and as long as a vertex shader manages to deliver the *gl_Position* output, OpenGL is happy.
The important thing is, that two vertices are identical only then, if all the attributes are the same. If they differ in just one attribute, they're not the same vertex. Now let's take our previous example of the hexagon. We're now making the triangles red, green and blue and were going to add two triangles, to extend the red and green ones into kind of diamond shapes:
// x, y, red, green, blue
GLfloat vertices[5][] = {
// red
{0, 0, 1, 0, 0}, // 0
{1, 0, 1, 0, 0}, // 1
{0.5, 0.866, 1, 0, 0}, // 2
{1, 1, 1, 0, 0}, // 3
// green
{0, 0, 0, 1, 0}, // 4
{-0.5, 0.866, 0, 1, 0}, // 5
{-1, 0, 0, 1, 0}, // 6
{-1, 1, 0, 1, 0}, // 7
// blue
{0, 0, 0, 0, 1}, // 8
{0.5, -0.866, 0, 0, 1}, // 9
{-0.5, -0.866, 0, 0, 1}, // 10
};
The triangles we now want to draw are
GLushort indices[] = {
// the two red triangles
0, 1, 2,
3, 2, 1,
// the two green triangles
4, 5, 6,
5, 7, 6,
// the blue triangle
8, 9, 10
};
Now we need to tell OpenGL about the structure of our vertex array. This is where the stride parameter of the gl…Pointer functions enters the picture. If nonzero, the stride tells OpenGL the distance (in bytes) between the start of each vertex in the array. By passing the data pointer with the right offset this makes OpenGL access the right things. In our case a vertex consists of
2 position elements of GLfloat with offset 0
3 color elements of GLfloat with offset 2*sizeof(GLfloat)
and each vertex is sizeof(GLfloat)*5 bytes apart.
We'll let the C compiler do the offset calculations for us, by simply dereferencing the right array elements and taking the address of it:
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, &vertices[0][0]);
glColorPointer(3, GL_FLOAT, sizeof(GLfloat)*5, &vertices[0][2]);
The rest is just glDrawElements(GL_TRIANGLES, 5, GL_UNSIGNED_SHORT, indices).
Note that we're not using VBOs at this point, but client side vertex arrays only. VBOs build upon vertex arrays. So I strongly suggest you first get a strong grip of vertex arrays, before going to tackle VBOs. They quite easy to use actually, but there are a few conceptional pitfalls, like tricking the compiler to pass a number for a pointer parameter.