I followed this great tutorial on how to prepare an .obj file parser and I got lost in the end and I don't know what to do!
I Made some very simple model in Blender and saved it just like it is said in the tutorial. According to that, I should have 3 faces coordinates like this:
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8
In my case, I have only two, and the middle one is empty:
f 1//1 2//1 4//1
f 5//2 8//2 7//2
f 1//3 5//3 2//3
f 2//4 6//4 7//4
f 3//5 7//5 8//5
f 5//6 1//6 4//6
f 8//7 5//7 4//7
f 6//8 5//8 7//8
f 2//9 3//9 4//9
f 5//10 6//10 2//10
f 3//11 2//11 7//11
f 4//5 3//5 8//5
I'm surely doing something wrong, but I have no idea what is that.
It's allowed in OBJ file format to simply omit texture attribute. Thus, f 1//1 2//1 3//1 is a valid triangle, just only with positions and normals. You should change your parser to accept that (which shouldn't be very hard).
Wikipedia article about OBJ explains that rather well:
Vertex/normal
As texture coordinates are optional, one can define geometry without them, but one must put two slashes after the vertex index before putting the normal index:
f v1//vn1 v2//vn2 v3//vn3
Also keep in mind that you don't have to specify normals either, and a face can look like:
f 1/1 2/2 3/3
Related
I have a comment in my code that indicates what is contained inside of a two-dimensional array:
(**
I
N H
F A
A B L A T E
B A I N T
R T H O U G H
A E A
S T
I N C I N E R A T E
V
E
*)
Due to its nature, it needs to be formatted exactly like this. However, whenever I run ocamlformat, it gets reformatted to look like this:
(** I N H F A A B L A T E B A I N T R T H O U G H A E A S T I N C I
N E R A T E V E *)
How do I fix this? The closest I've been able to get without affecting anything else is this:
let _ =
()
(*
I
N H
F A
A B L A T E
B A I N T
R T H O U G H
A E A
S T
I N C I N E R A T E
V
E
*)
[#ocamlformat "disable"]
But that's not very satisfying. This comment is supposed to be attached to a top-level item, but I can't do that with this method b/c then ocamlformat will be disabled for the entire item. I can't figure out how to disable the comment formatting only.
You can use [##ocamlformat "wrap-comments=false"] to disable only the comment-wrapping feature,
let _ =
()
(*
I
N H
F A
A B L A T E
B A I N T
R T H O U G H
A E A
S T
I N C I N E R A T E
V
E
*)
[##ocamlformat "wrap-comments=false"]
You can also disable it in .ocamlformat, but since it is already disabled by default, I think it was the intention to have it. You can also disable the feature on a module level, using [###ocamlformat "wrap-comments=false"] at the beginning of your file.
As a side note, if you want ocamldoc to preserve the look of the comment in the generated documentation, you should also wrap it in the verbatim tag, e.g., the following will be rendered verbatim,
(**
{v
If P, then Q.
Not Q.
Therefore, not P.
v}
*)
I am learning about monads from the book 'Learn You a Haskell for Great Good!' by Miran Lipovaca. I am trying to understand the associativity law for monads. Essentially, the law states that when you have a chain of monadic function applications with >>=, it shouldn't matter how they're nested.
The following code enables one to pass the result of a function of type a -> m b to a function of type b -> m c:
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)
However, for the example below:
ghci> let f x = [x, -x]
ghci> let g x = [x*3, x*2]
ghci> let h = f <=< g
ghci> h 3
[9, -9, 6, -6]
Are f x and g x both functions? It seems to be that they are lists with different values of x and not functions. How does the line let h = f <=< g work in the above code? f and g have to be functions since they are used with <=< but I am not sure what they are.
f x = [x, -x]
This is ordinary function definition syntax. We are defining a new function f, by writing down what it would produce when applied to a hypothetical value x.
let (whether as a statement or a let ... in ... expression) just introduces a block where you can make definitions, much like where. The definitions themselves use the same syntax as global ones do.
If you know how to define functions by writing e.g. plusOne n = n + 1 in a file, then this syntax is exactly the same (if you don't know how to do that, then I'd suggest reading through some introductory tutorials on fundamental Haskell syntax before you try to understand monadic function composition).
So after those definitions f and g are functions. f x and g x don't really make sense, since you don't have an x in scope to apply them to.
If you did have such a value in scope, then f x would be an expression that evaluates to a list, which involves calling the function f. It still wouldn't be true to say that f x or g x are functions.
So now it should be clear that let h = f <=< g is defining a new value h by applying the <=< operator to f and g.
Nothing's better for gaining a feeling of understanding, like working through the definitions by hand on a sheet of paper.
f x = [x, -x] can also be written f = (\ x -> [x, -x]). Thus
h 3
= {- by def of h -}
(f <=< g) 3
= {- by def of (<=<) -}
(\x -> g x >>= f ) 3
= {- by defs of f and g -}
(\x -> (\ x -> [x*3, x*2]) x >>= (\ x -> [x, -x])) 3
= {- by substitution -}
(\ x -> [x*3, x*2]) 3 >>= (\ x -> [x, -x])
= {- by substitution -}
[3*3,
3*2] >>= (\ x -> [x, -x])
= {- by definition of (>>=) for [] -}
concat [ (3*3) & (\ x -> [x, -x]) -- x & f == f x
, (3*2) & (\ x -> [x, -x])
]
= {- by definition of concat -}
(3*3) & (\ x -> [x, -x])
++ (3*2) & (\ x -> [x, -x])
=
[9, -9, 6, -6]
(edit) For a picture, and some more discussion of these Kleisli arrows and their composability, see this older answer of mine.
I'm trying to load model from obj file and display it in OpenGL 2.0 but I have two problems.
Loaded model sometimes flickers and crashes my application randomly.
I have no idea what causes exception because I don't have even a stacktrace.
I only have "Frame not in module" and message:
Exception thrown at 0x000000CE25E7FF68 in Clock.exe: 0xC0000005: Access violation reading location 0x000000CE26640000.
Do you have any idea what is wrong? Code? File?
ObjLoader.h:
#pragma once
#include <vector>
using namespace std;
typedef struct _vertex {
float x, y, z;
} Vertex;
typedef struct _face {
unsigned int v, vn;
} Face;
struct ObjModel
{
vector<Vertex> Vertices;
vector<Vertex> Normals;
vector<vector<Face>> Faces;
};
class ObjLoader
{
public:
ObjModel LoadObjModel(const char* filePath);
private:
void ProcessIndices(ObjModel &model);
void ProcessLine(string &dataType, stringstream &ss, ObjModel &model);
Vertex ObjLoader::GetVertex(stringstream &ss);
vector<Face> ObjLoader::GetFaces(stringstream &ss);
};
ObjLoader.cpp:
#include "ObjLoader.h"
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
using namespace std;
ObjModel ObjLoader::LoadObjModel(const char* filePath)
{
ObjModel model;
fstream in(filePath);
string line;
while (std::getline(in, line))
{
if (line.empty())
{
continue;
}
string dataType = line.substr(0, 2);
line = line.substr(2, line.size() - 2);
if (line[0] == ' ')
{
line = line.substr(1, line.size() - 1);
}
stringstream ss(line);
ProcessLine(dataType, ss, model);
}
ProcessIndices(model);
return model;
}
void ObjLoader::ProcessLine(string &dataType, stringstream &ss, ObjModel &model)
{
if (dataType == "v ")
{
model.Vertices.push_back(GetVertex(ss));
}
else if (dataType == "vn")
{
model.Normals.push_back(GetVertex(ss));
}
else if (dataType == "f ")
{
vector<Face> faces = GetFaces(ss);
model.Faces.push_back(faces);
}
}
Vertex ObjLoader::GetVertex(stringstream &ss)
{
Vertex vertex;
ss >> vertex.x >> vertex.y >> vertex.z;
return vertex;
}
vector<Face> ObjLoader::GetFaces(stringstream &ss)
{
vector<Face> faces;
string s;
while (getline(ss, s, ' '))
{
Face face;
int a, b;
sscanf(s.c_str(), "%d//%d", &a, &b);
face.v = a;
face.vn = b;
faces.push_back(face);
}
return faces;
}
void ObjLoader::ProcessIndices(ObjModel &model)
{
ObjModel temp;
temp.Vertices = vector<Vertex>();
temp.Normals = vector<Vertex>();
for (int i = 0; i < model.Faces.size(); i++)
{
for (int j = 0; j < model.Faces[i].size(); j++)
{
unsigned int vertexIndex = model.Faces[i][j].v - 1;
unsigned int normalIndex = model.Faces[i][j].vn - 1;
Vertex vertex = model.Vertices[vertexIndex];
Vertex normal = model.Normals[normalIndex];
temp.Vertices.push_back(vertex);
temp.Normals.push_back(vertex);
}
}
model.Vertices = temp.Vertices;
model.Normals = temp.Normals;
}
Displaying model:
float *vertices, *normals;
vertices = &model.Vertices[0].x;
normals = &model.Normals[0].x;
glEnable(GL_NORMALIZE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, sizeof(float) * 4,normals);
glDrawArrays(GL_TRIANGLES, 0, model.Vertices.size());
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
Obj file:
v -0.048773 -0.250000 -1.004804
v -0.048773 0.250000 -1.004804
v 0.243863 0.250000 -0.975982
v 0.243863 -0.250000 -0.975982
v 0.784410 -0.250000 -0.156029
v 1.004804 -0.250000 -0.048773
v 0.975982 -0.250000 0.243863
v 0.738899 -0.250000 0.306062
v 0.664991 -0.250000 0.444333
v 0.744991 -0.250000 0.676016
v 0.517686 -0.250000 0.862560
v 0.306062 -0.250000 0.738899
v 0.156029 -0.250000 0.784410
v 0.048772 -0.250000 1.004804
v -0.243863 -0.250000 0.975981
v -0.306062 -0.250000 0.738898
v -0.444333 -0.250000 0.664991
v -0.676017 -0.250000 0.744991
v -0.862561 -0.250000 0.517685
v -0.738899 -0.250000 0.306061
v -0.784411 -0.250000 0.156028
v -0.293088 -0.250000 -0.006913
v -0.287323 -0.250000 0.051614
v -0.270251 -0.250000 0.107892
v -0.242528 -0.250000 0.159758
v -0.205220 -0.250000 0.205219
v -0.159759 -0.250000 0.242528
v -0.107893 -0.250000 0.270251
v -0.051615 -0.250000 0.287323
v 0.006912 -0.250000 0.293088
v 0.065440 -0.250000 0.287323
v 0.121718 -0.250000 0.270251
v 0.173584 -0.250000 0.242528
v 0.219045 -0.250000 0.205220
v 0.256353 -0.250000 0.159759
v 0.284076 -0.250000 0.107892
v 0.301148 -0.250000 0.051615
v 0.306913 -0.250000 -0.006913
v 0.306062 -0.250000 -0.738899
v 0.444333 -0.250000 -0.664991
v 0.676016 -0.250000 -0.744991
v 0.862560 -0.250000 -0.517686
v 0.738899 -0.250000 -0.306062
v 0.301148 -0.250000 -0.065440
v 0.284076 -0.250000 -0.121718
v 0.256353 -0.250000 -0.173584
v 0.219045 -0.250000 -0.219045
v 0.173584 -0.250000 -0.256353
v 0.121718 -0.250000 -0.284076
v 0.065440 -0.250000 -0.301148
v 0.006913 -0.250000 -0.306913
v -0.051614 -0.250000 -0.301148
v -0.107892 -0.250000 -0.284077
v -0.159758 -0.250000 -0.256354
v -0.205219 -0.250000 -0.219045
v -0.242528 -0.250000 -0.173584
v -0.270251 -0.250000 -0.121718
v -0.287323 -0.250000 -0.065440
v -1.004804 -0.250000 0.048772
v -0.975981 -0.250000 -0.243864
v -0.738898 -0.250000 -0.306063
v -0.664991 -0.250000 -0.444334
v -0.744990 -0.250000 -0.676017
v -0.517685 -0.250000 -0.862561
v -0.306061 -0.250000 -0.738899
v -0.156028 -0.250000 -0.784411
v -0.156028 0.250000 -0.784411
v -0.306061 0.250000 -0.738899
v -0.517685 0.250000 -0.862561
v -0.744990 0.250000 -0.676017
v -0.664991 0.250000 -0.444334
v -0.738898 0.250000 -0.306063
v -0.975981 0.250000 -0.243864
v -1.004804 0.250000 0.048772
v -0.784411 0.250000 0.156028
v -0.738899 0.250000 0.306061
v -0.862561 0.250000 0.517685
v -0.676017 0.250000 0.744991
v -0.444333 0.250000 0.664991
v -0.306062 0.250000 0.738898
v -0.243863 0.250000 0.975981
v 0.048772 0.250000 1.004804
v 0.156029 0.250000 0.784410
v 0.006912 0.250000 0.293088
v -0.051615 0.250000 0.287323
v -0.107893 0.250000 0.270251
v -0.159759 0.250000 0.242528
v -0.205220 0.250000 0.205219
v -0.242528 0.250000 0.159758
v -0.270251 0.250000 0.107892
v -0.287323 0.250000 0.051614
v -0.293088 0.250000 -0.006913
v -0.287323 0.250000 -0.065440
v -0.270251 0.250000 -0.121718
v -0.242528 0.250000 -0.173584
v -0.205219 0.250000 -0.219045
v -0.159758 0.250000 -0.256354
v -0.107892 0.250000 -0.284077
v -0.051614 0.250000 -0.301148
v 0.006913 0.250000 -0.306913
v 0.306062 0.250000 -0.738899
v 0.065440 0.250000 -0.301148
v 0.121718 0.250000 -0.284076
v 0.173584 0.250000 -0.256353
v 0.219045 0.250000 -0.219045
v 0.256353 0.250000 -0.173584
v 0.284076 0.250000 -0.121718
v 0.301148 0.250000 -0.065440
v 0.306913 0.250000 -0.006913
v 0.301148 0.250000 0.051615
v 0.284076 0.250000 0.107892
v 0.256353 0.250000 0.159759
v 0.219045 0.250000 0.205220
v 0.173584 0.250000 0.242528
v 0.121718 0.250000 0.270251
v 0.065440 0.250000 0.287323
v 0.306062 0.250000 0.738899
v 0.517686 0.250000 0.862560
v 0.744991 0.250000 0.676016
v 0.664991 0.250000 0.444333
v 0.738899 0.250000 0.306062
v 0.975982 0.250000 0.243863
v 1.004804 0.250000 -0.048773
v 0.784410 0.250000 -0.156029
v 0.738899 0.250000 -0.306062
v 0.862560 0.250000 -0.517686
v 0.676016 0.250000 -0.744991
v 0.444333 0.250000 -0.664991
vn 0.0980 0.0000 -0.9952
vn 0.0000 -1.0000 -0.0000
vn -0.8992 0.0000 -0.4376
vn 0.0000 1.0000 0.0000
vn 0.9673 0.0000 -0.2538
vn 0.4714 0.0000 -0.8819
vn -0.3264 0.0000 -0.9452
vn 0.7730 0.0000 -0.6344
vn 0.8634 0.0000 0.5045
vn 0.9569 0.0000 -0.2903
vn 0.4376 0.0000 -0.8992
vn 0.9952 0.0000 0.0980
vn 0.2538 0.0000 0.9673
vn 0.8819 0.0000 0.4714
vn 0.9452 0.0000 -0.3264
vn 0.6344 0.0000 0.7730
vn -0.5045 0.0000 0.8634
vn 0.2903 0.0000 0.9569
vn 0.8992 0.0000 0.4376
vn -0.0980 0.0000 0.9952
vn -0.9673 0.0000 0.2538
vn -0.4714 0.0000 0.8819
vn 0.3264 0.0000 0.9452
vn -0.7730 0.0000 0.6344
vn -0.8634 0.0000 -0.5045
vn -0.9569 0.0000 0.2903
vn -0.4376 0.0000 0.8992
vn -0.9952 0.0000 -0.0980
vn -0.2538 0.0000 -0.9673
vn -0.8819 0.0000 -0.4714
vn -0.9452 0.0000 0.3264
vn -0.6344 0.0000 -0.7730
vn 0.5045 0.0000 -0.8634
vn -0.2903 0.0000 -0.9569
vn 0.0980 0.0000 0.9952
vn -0.2903 0.0000 0.9569
vn 0.4714 0.0000 0.8819
vn -0.6344 0.0000 0.7730
vn 0.7730 0.0000 0.6344
vn -0.8819 0.0000 0.4714
vn 0.9569 0.0000 0.2903
vn -0.9952 0.0000 0.0980
vn 0.9952 0.0000 -0.0980
vn -0.9569 0.0000 -0.2903
vn 0.8819 0.0000 -0.4714
vn -0.7730 0.0000 -0.6344
vn 0.6344 0.0000 -0.7730
vn -0.4714 0.0000 -0.8819
vn 0.2903 0.0000 -0.9569
vn -0.0980 0.0000 -0.9952
s off
f 2//1 4//1 1//1
f 16//2 28//2 29//2
f 51//2 52//2 66//2
f 67//3 1//3 66//3
f 79//4 87//4 88//4
f 111//4 112//4 121//4
f 3//5 39//5 4//5
f 101//6 40//6 39//6
f 128//7 41//7 40//7
f 127//8 42//8 41//8
f 126//9 43//9 42//9
f 125//10 5//10 43//10
f 124//11 6//11 5//11
f 123//12 7//12 6//12
f 122//13 8//13 7//13
f 121//14 9//14 8//14
f 120//15 10//15 9//15
f 119//16 11//16 10//16
f 118//17 12//17 11//17
f 117//18 13//18 12//18
f 83//19 14//19 13//19
f 82//20 15//20 14//20
f 81//21 16//21 15//21
f 80//22 17//22 16//22
f 79//23 18//23 17//23
f 78//24 19//24 18//24
f 77//25 20//25 19//25
f 76//26 21//26 20//26
f 75//27 59//27 21//27
f 74//28 60//28 59//28
f 73//29 61//29 60//29
f 72//30 62//30 61//30
f 71//31 63//31 62//31
f 70//32 64//32 63//32
f 69//33 65//33 64//33
f 68//34 66//34 65//34
f 50//20 100//20 51//20
f 51//35 99//35 52//35
f 49//36 102//36 50//36
f 52//18 98//18 53//18
f 48//22 103//22 49//22
f 53//37 97//37 54//37
f 47//38 104//38 48//38
f 54//16 96//16 55//16
f 46//24 105//24 47//24
f 55//39 95//39 56//39
f 45//40 106//40 46//40
f 56//14 94//14 57//14
f 44//26 107//26 45//26
f 57//41 93//41 58//41
f 38//42 108//42 44//42
f 58//12 92//12 22//12
f 37//28 109//28 38//28
f 22//43 91//43 23//43
f 36//44 110//44 37//44
f 23//10 90//10 24//10
f 35//30 111//30 36//30
f 24//45 89//45 25//45
f 34//46 112//46 35//46
f 25//8 88//8 26//8
f 33//32 113//32 34//32
f 26//47 87//47 27//47
f 32//48 114//48 33//48
f 27//6 86//6 28//6
f 31//34 115//34 32//34
f 28//49 85//49 29//49
f 30//50 116//50 31//50
f 29//1 84//1 30//1
f 2//1 3//1 4//1
f 38//2 5//2 37//2
f 6//2 7//2 8//2
f 9//2 10//2 12//2
f 5//2 6//2 8//2
f 10//2 11//2 12//2
f 5//2 8//2 37//2
f 37//2 8//2 36//2
f 35//2 36//2 8//2
f 13//2 14//2 16//2
f 14//2 15//2 16//2
f 9//2 35//2 8//2
f 9//2 34//2 35//2
f 13//2 16//2 29//2
f 17//2 18//2 19//2
f 20//2 21//2 24//2
f 17//2 19//2 20//2
f 9//2 33//2 34//2
f 9//2 12//2 33//2
f 16//2 17//2 27//2
f 21//2 22//2 23//2
f 21//2 23//2 24//2
f 33//2 12//2 32//2
f 32//2 12//2 31//2
f 20//2 24//2 25//2
f 20//2 25//2 26//2
f 31//2 12//2 13//2
f 30//2 31//2 13//2
f 17//2 20//2 26//2
f 17//2 26//2 27//2
f 29//2 30//2 13//2
f 16//2 27//2 28//2
f 66//2 1//2 4//2
f 66//2 4//2 39//2
f 63//2 64//2 65//2
f 65//2 66//2 53//2
f 40//2 41//2 42//2
f 66//2 39//2 51//2
f 62//2 63//2 65//2
f 59//2 60//2 61//2
f 61//2 57//2 58//2
f 39//2 40//2 49//2
f 43//2 5//2 44//2
f 40//2 42//2 43//2
f 59//2 61//2 21//2
f 22//2 61//2 58//2
f 22//2 21//2 61//2
f 5//2 38//2 44//2
f 43//2 44//2 45//2
f 61//2 62//2 57//2
f 57//2 62//2 56//2
f 43//2 45//2 46//2
f 43//2 46//2 40//2
f 56//2 62//2 55//2
f 55//2 62//2 65//2
f 40//2 46//2 47//2
f 40//2 47//2 48//2
f 54//2 55//2 65//2
f 53//2 54//2 65//2
f 40//2 48//2 49//2
f 39//2 49//2 50//2
f 52//2 53//2 66//2
f 39//2 50//2 51//2
f 67//3 2//3 1//3
f 3//4 2//4 67//4
f 68//4 69//4 71//4
f 101//4 3//4 67//4
f 69//4 70//4 71//4
f 101//4 67//4 100//4
f 99//4 100//4 67//4
f 98//4 99//4 67//4
f 67//4 68//4 98//4
f 72//4 73//4 74//4
f 68//4 71//4 96//4
f 97//4 98//4 68//4
f 96//4 97//4 68//4
f 71//4 95//4 96//4
f 72//4 74//4 75//4
f 71//4 94//4 95//4
f 76//4 77//4 79//4
f 72//4 94//4 71//4
f 72//4 93//4 94//4
f 77//4 78//4 79//4
f 80//4 81//4 82//4
f 76//4 79//4 88//4
f 72//4 92//4 93//4
f 72//4 75//4 92//4
f 79//4 80//4 87//4
f 82//4 83//4 80//4
f 83//4 84//4 85//4
f 92//4 75//4 91//4
f 91//4 75//4 90//4
f 80//4 83//4 85//4
f 80//4 85//4 86//4
f 90//4 75//4 76//4
f 89//4 90//4 76//4
f 80//4 86//4 87//4
f 88//4 89//4 76//4
f 128//4 101//4 103//4
f 101//4 100//4 102//4
f 126//4 127//4 125//4
f 125//4 127//4 128//4
f 101//4 102//4 103//4
f 128//4 103//4 104//4
f 124//4 125//4 108//4
f 122//4 123//4 121//4
f 121//4 123//4 124//4
f 125//4 128//4 106//4
f 128//4 104//4 105//4
f 120//4 121//4 112//4
f 118//4 119//4 117//4
f 84//4 83//4 116//4
f 117//4 119//4 120//4
f 128//4 105//4 106//4
f 125//4 106//4 107//4
f 117//4 120//4 114//4
f 116//4 83//4 117//4
f 115//4 116//4 117//4
f 125//4 107//4 108//4
f 124//4 108//4 109//4
f 114//4 115//4 117//4
f 113//4 114//4 120//4
f 121//4 124//4 110//4
f 124//4 109//4 110//4
f 112//4 113//4 120//4
f 121//4 110//4 111//4
f 3//5 101//5 39//5
f 101//6 128//6 40//6
f 128//7 127//7 41//7
f 127//8 126//8 42//8
f 126//9 125//9 43//9
f 125//10 124//10 5//10
f 124//11 123//11 6//11
f 123//12 122//12 7//12
f 122//13 121//13 8//13
f 121//14 120//14 9//14
f 120//15 119//15 10//15
f 119//16 118//16 11//16
f 118//17 117//17 12//17
f 117//18 83//18 13//18
f 83//19 82//19 14//19
f 82//20 81//20 15//20
f 81//21 80//21 16//21
f 80//22 79//22 17//22
f 79//23 78//23 18//23
f 78//24 77//24 19//24
f 77//25 76//25 20//25
f 76//26 75//26 21//26
f 75//27 74//27 59//27
f 74//28 73//28 60//28
f 73//29 72//29 61//29
f 72//30 71//30 62//30
f 71//31 70//31 63//31
f 70//32 69//32 64//32
f 69//33 68//33 65//33
f 68//34 67//34 66//34
f 50//20 102//20 100//20
f 51//35 100//35 99//35
f 49//36 103//36 102//36
f 52//18 99//18 98//18
f 48//22 104//22 103//22
f 53//37 98//37 97//37
f 47//38 105//38 104//38
f 54//16 97//16 96//16
f 46//24 106//24 105//24
f 55//39 96//39 95//39
f 45//40 107//40 106//40
f 56//14 95//14 94//14
f 44//26 108//26 107//26
f 57//41 94//41 93//41
f 38//42 109//42 108//42
f 58//12 93//12 92//12
f 37//28 110//28 109//28
f 22//43 92//43 91//43
f 36//44 111//44 110//44
f 23//10 91//10 90//10
f 35//30 112//30 111//30
f 24//45 90//45 89//45
f 34//46 113//46 112//46
f 25//8 89//8 88//8
f 33//32 114//32 113//32
f 26//47 88//47 87//47
f 32//48 115//48 114//48
f 27//6 87//6 86//6
f 31//34 116//34 115//34
f 28//49 86//49 85//49
f 30//50 84//50 116//50
f 29//1 85//1 84//1
I'm going to say that glNormalPointer(GL_FLOAT, sizeof(float) * 4,normals); is causing your problems. First off, you only have 3 components in your normals, not four. I bet this is causing glDrawArrays to access out of bounds memory.
Also, because your normals are not walked correctly you could be getting garbage and it would cause some flickering.
Because your normals are tightly packed, just use 0 for the stride.
I want to apply a function f which needs a RandomGen over a list. I tried to generate me therefore a infinite list of RandomGen as you can see below. (just random values as generated by the function "randoms" isn't sufficient, because the needed range of the value depends on the input for f.)
module Test where
import System.Random (getStdGen, RandomGen, randomR, random)
f :: (RandomGen g, Integral a) => g -> a -> Bool
randomGens :: RandomGen g => g -> [g]
randomGens gen =
let (i, gen') = (random gen) :: (Int, g1)
in gen : (repeatGen gen')
Unfortunately the compiler tells me, that it fails
Test.hs:13:26:
Could not deduce (g1 ~ g)
from the context (RandomGen g)
bound by the type signature for
randomGens :: RandomGen g => g -> (g, g)
at Test.hs:11:14-39
or from (RandomGen g1)
bound by an expression type signature: RandomGen g1 => (Int, g1)
at Test.hs:13:19-55
`g1' is a rigid type variable bound by
an expression type signature: RandomGen g1 => (Int, g1)
at Test.hs:13:19
`g' is a rigid type variable bound by
the type signature for randomGens :: RandomGen g => g -> (g, g)
at Test.hs:11:14
In the first argument of `random', namely `gen'
In the expression: random gen :: RandomGen g => (Int, g)
In a pattern binding:
(i, gen') = random gen :: RandomGen g => (Int, g)
Just skipping in the let-binding the type annotation (Int, g1) doesn't work. He needs to have the result-type for the application of "random"
Disregarding for a while whether generating an infinite list of random generators is really the way to go, there exists a function called split in System.Random that can be used to create a new generator instead of calling random on a dummy type and throwing the generated value away. Using split you can implement randomGens like this:
import Data.List (unfoldr)
import System.Random
randomGens :: RandomGen g => g -> [g]
randomGens = unfoldr (Just . split)
However, you should probably just use randomRs which generates an infinite stream of values in the given range.
Quick answer
You can define the function you want as
randomGens :: (RandomGen g) => g -> [g]
randomGens g = let (g0,g1) = split g in g0 : randomGens g1
Slightly longer answer
The above probably isn't the best way to go about applying a function that requires randomness to a list. I might define a helper function to do that
mapRandom :: (RandomGen g) => (g -> a -> b) -> g -> [a] -> (g, [b])
mapRandom _ g [] = (g, [])
mapRandom f g (a:as) = let (_,g1) = next g
in f g a : mapRandom f g1 as
You can then write
>> g <- newStdGen
>> mapRandom f g [1..5]
([False,False,True,False,True], 1839473859 293842934)
Best answer
The function mapRandom looks very messy. That's because we have to mess around with the fiddly details of manually updating the generator. Fortunately, you don't have to do that! The package Control.Monad.Random gives you nice combinators to almost completely abstract away the idea of generators. Say you currently have
f :: (RandomGen g) => g -> Int -> Bool
f g n = let (x,_) = random g in x < n
I would rewrite that to be
f :: (RandomGen g) => Int -> Rand g Bool
f n = do
x <- getRandom
return (x < n)
and just use mapM to map this function over lists. You can run it with
>> gen <- newStdGen
>> runRand (mapM f [1..10]) gen
([False,True,True,False,True], 1838593757 1838473759)
where the first element of the pair is the result of mapping your random function over the list, and the last element is the current value of the generator. Notice that when defining f you don't have to worry about the generator at all - Haskell takes care of updating the generator and generating new random numbers behind the scenes.
The main problem here - compiler can't understand the equality g1 and g (list are always homomorphic!)
It is need to use ScopedTypeVariables extension, like this:
{-# LANGUAGE ScopedTypeVariables #-}
randomGens :: forall g. RandomGen g => g -> [g]
randomGens gen =
let (i, gen') = (random gen) :: RandomGen g => (Int, g)
in gen : (randomGens gen')
We add forall g to point on scope context of g.
As Chris Taylor mention, this function isn't effective, it is need to calculate random number twice - first time to calculate new g and second time to calculate new random number.
So, much nicer to use MonadRand saving new generator numbers in the state.
UPDATED
For simple cases we could use zipWith
randomsMap :: (RandomGen g, Random a) => g -> (a -> b -> c) -> [b] -> [c]
randomsMap g f xs = zipWith f (randoms g) xs
I'm reading the Reasoned Schemer.
I have some intuition about how conde works.
However, I can't find a formal definition of what conde/conda/condu/condi do.
I'm aware of https://www.cs.indiana.edu/~webyrd/ but that seems to have examples rather than definitions.
Is there a formal definition of conde, conda, condi, condu somewhere?
In Prolog's terms,
condA is "soft cut" a.k.a. *->, where A *-> B ; C is like (A, B ; not(A), C), only better ; whereas
condU is "committed choice", a combination of once and a soft cut so that (once(A) *-> B ; false) expresses (A, !, B) (with the cut inside):
condA: A *-> B ; C % soft cut,
% (A , B ; not(A) , C)
condU: once(A) *-> B ; C % committed choice,
% (A , !, B ; not(A) , C)
(with ; meaning "or" and , meaning "and", i.e. disjunction and conjunction of goals, respectively).
In condA, if the goal A succeeds, all the solutions are passed through to the first clause B and no alternative clauses C are tried.
In condU, once/1 allows its argument goal to succeed only once (keeps only one solution, if any).
condE is a simple disjunction of conjunctions, and condI is a disjunction which alternates between the solutions of its constituents, interleaving the streams thereof.
Here's an attempt at faithfully translating the book's code, w/out the logical variables and unification, into 18 lines of Haskell which is mostly a lazy Lisp with syntax.(*) See if this clarifies things:
Sequential stream combination ("mplus" of the book):
(1) [] ++: ys = ys
(2) (x:xs) ++: ys = x : (xs ++: ys)
Alternating stream combination ("mplusI"):
(3) [] ++/ ys = ys
(4) (x:xs) ++/ ys = x : (ys ++/ xs)
Sequential feed ("bind"):
(5) [] >>: g = []
(6) (x:xs) >>: g = g x ++: (xs >>: g)
Alternating feed ("bindI"):
(7) [] >>/ g = []
(8) (x:xs) >>/ g = g x ++/ (xs >>/ g)
"OR" goal combination ("condE"):
(9) (f ||: g) x = f x ++: g x
"Alternating OR" goal combination ("condI"):
(10) (f ||/ g) x = f x ++/ g x
"AND" goal combination ("all"):
(11) (f &&: g) x = f x >>: g
"Alternating AND" goal combination ("allI" of the book):
(12) (f &&/ g) x = f x >>/ g
Special goals true and false (or "success" and "failure"):
(13) true x = [x] -- a sigleton list with the same solution repackaged
(14) false x = [] -- an empty list, meaning the solution is rejected
And why are they called true and false? Because for any goal g we have, e.g.,
(g &&: true) x = g x >>: true = g x >>: (\ x -> [x] ) = g x
(false &&: g) x = false x >>: g = [] >>: g = [] = false x
-- ... etc.
Goals produce streams (possibly empty) of (possibly updated) solutions, given a (possibly partial) solution to a problem.
Re-write rules for all are:
(all) = true
(all g1) = g1
(all g1 g2 g3 ...) = (\x -> g1 x >>: (all g2 g3 ...))
= g1 &&: (g2 &&: (g3 &&: ... ))
(allI g1 g2 g3 ...) = (\x -> g1 x >>/ (allI g2 g3 ...))
= g1 &&/ (g2 &&/ (g3 &&/ ... ))
Re-write rules for condX are:
(condX) = false
(condX (else g1 g2 ...)) = (all g1 g2 ...) = g1 &&: (g2 &&: (...))
(condX (g1 g2 ...)) = (all g1 g2 ...) = g1 &&: (g2 &&: (...))
(condX (g1 g2 ...) (h1 h2 ...) ...) = (ifX g1 (all g2 ...)
(ifX h1 (all h2 ...) (...) ))
To arrive at the final condE and condI's translation, there's no need to implement the book's ifE and ifI, since they reduce further to simple operator combinations, with all the operators considered to be right-associative:
(condE (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ... ) ||: (h1 &&: h2 &&: ...) ||: ...
(condI (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ... ) ||/ (h1 &&: h2 &&: ...) ||/ ...
So there's no need for any special "syntax" in Haskell, plain binary infix operators suffice. Any combination can be used anywhere, with &&/ instead of &&: as needed. But on the other hand condI could also be implemented as a function to accept a collection (list, tree etc.) of goals to be fulfilled, that would use some smart strategy to pick of them one most likely or most needed etc, and not just simple binary alternation as in ||/ operator (or ifI of the book).
Next, the book's condA can be modeled by two new operators, ~~> and ||~, working together. We can use them in a natural way as in e.g.
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ... ||~ gelse
which can intuitively be read as "IF g1 THEN g2 AND ... OR-ELSE IF h1 THEN ... OR-ELSE gelse":
"IF-THEN" goal combination is to produce a "try" goal which must be called with a failure-continuation goal:
(15) (g ~~> h) f x = case g x of [] -> f x ; ys -> ys >>: h
"OR-ELSE" goal combination of a try goal and a simple goal simply calls its try goal with a second, on-failure goal, so it's nothing more than a convenience syntax for automatic grouping of operands:
(16) (g ||~ f) x = g f x
With the "OR-ELSE" ||~ operator given less binding power than the "IF-THEN" ~~> operator and made right-associative too, and ~~> operator having still less binding power than &&: and the like, sensible grouping of the above example is automatically produced as
(g1 ~~> (g2 &&: ...)) ||~ ( (h1 ~~> (h2 &&: ...)) ||~ (... ||~ gelse ...) )
Last goal in an ||~ chain must thus be a simple goal. That's no limitation really, since last clause of condA form is equivalent anyway to simple "AND"-combination of its goals (or simple false can be used just as well).
That's all. We can even have more types of try goals, represented by different kinds of "IF" operators, if we want:
use alternating feed in a successful clause (to model what could've been called condAI, if there were one in the book):
(17) (g ~~>/ h) f x = case g x of [] -> f x ; ys -> ys >>/ h
use the successful solution stream only once to produce the cut effect, to model condU:
(18) (g ~~>! h) f x = case g x of [] -> f x ; (y:_) -> h y
So that, finally, the re-write rules for condA and condU of the book are simply:
(condA (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ...
(condU (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~>! g2 &&: ... ||~ h1 ~~>! h2 &&: ... ||~ ...
(*) which is:
simple juxtaposition is curried function application,
f a b c =~= (((f a) b) c) =~= f(a, b, c)
(\ a -> b ) is lambda function, (lambda (a) b)
foo x = y is shortcut for foo = (\ x -> y )
a ## b = y is shortcut for (##) a b = y, definition of an infix operator ##
parentheses ( ) are just for grouping
[] is the empty list, and
: means cons -- both as a constructor ( lazy, as the whole language is lazy, i.e. call by need ), on the right of = in definitions; and as a destructuring pattern, on the left (or in pattern-matching case expressions).
The Reasoned Schemer covers conda (soft cut) and condu (committed choice). You'll also find explanations of their behavior in William Byrd's excellent dissertation on miniKanren. You've tagged this post as being about core.logic. To be clear core.logic is based on a more recent version of miniKanren than the one presented in The Reasoned Schemer. miniKanren is always interleaves disjunctive goals - condi and the interleaving variants no longer exist. conde is condi now.
By Example, using core.logic:
conde will run every group, succeed if at least one group succeeds, and return all results from all successful groups.
user> (run* [w q]
(conde [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([_0 :second] [1 :first] [2 :first])
conda and condu: both will stop after the first successful group(top to bottom)
conda returns all results from only the first successful group.
user> (run* [w q]
(conda [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first] [2 :first])
condu returns only one result from only the first successful group.
user> (run* [w q]
(condu [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first])
No idea what condi does though.
According to the ISO Prolog core standard control structures such as (,)/2, (;)/2 and (->)/2 are cut transparent. (*->)/2 is not found in the ISO Prolog core standard, but usually Prolog systems implement it also cut transparent.
This means one cannot translate:
once(A) *-> B;C
Into A, !, B; C. Because the later might be embedded in other control structures, and if there are disjunctions among them, these choice points would be also cut away. What on the other hand seems reasonable, to view it as A -> B; C,
known simply as ISO Prolog core standard if-then-else. The thus defined behaviour of the cut, is for example useful to break out of repeat loops, without throwing an exception. The usual programming pattern is more difficult to archive with if-then-else.