Get primitive from AABB tree intersection - intersection
This code contains an AABB Tree which is build using a Polyhedron_3 mesh. It is possible to verify if an intersection occures but not what primitive the intersection hit. How can I retrieve the primitive?
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
const Polyhedron& mesh;
tree(faces(_mesh).first, faces(_mesh).second, _mesh);
boost::optional<Primitive_id> intersection = tree.first_intersected_primitive(ray);
if(intersection)
{
//how to get the primitive?
}
Edit:
faces(mesh, tree);
faces(*mesh, tree);
faces(hit, tree);
faces(*hit, tree);
Does not work too.
Edit2:
CGAL::internal::In_place_list_iterator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > >, std::allocator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > > > > it = *hit;
CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > >::Halfedge_around_facet_circulator ipfacet = it->facet_begin();
Gets you an iterrator and I_Polyhedron_facet.
Cgal is realy missing some documentation.
Here is the solution: Get the iterator around the face verticess primitive_id->facet_begin(); . And then do this.
Ray_intersection hit = tree.first_intersection(rays[this->transformCoordinates(y,x)]);
if(hit)
{
const Point& point = boost::get<Point>(hit->first);
const Primitive_id& primitive_id = boost::get<Primitive_id>(hit->second);
Polyhedron::Halfedge_around_facet_circulator facerunner = primitive_id->facet_begin();
Point p1;
Point p2;
Point p3;
p1 = facerunner->vertex()->point();
facerunner++;
p2 = facerunner->vertex()->point();
facerunner++;
p3 = facerunner->vertex()->point();
Vector v1(p1,p2);
Vector v2(p1,p3);
Vector n = CGAL::cross_product(v1,v2);
n = n/ std::sqrt(n.squared_length());
}
Answer from the cgal mailinglist:
what are you looking for that is not available here:
https://doc.cgal.org/latest/AABB_tree/index.html#title6
Also note that from here:
https://doc.cgal.org/latest/AABB_tree/classCGAL_1_1AABB__face__graph__triangle__primitive.html
you have:
typedef boost::graph_traits< FaceGraph >::face_descriptor Id
From that same page, you see that the graph type is model of FaceGraph:
https://doc.cgal.org/latest/BGL/classFaceGraph.html
Depending on the type of graph chosen, you have access to the precise
documentation of what face_descriptor corresponds to:
https://doc.cgal.org/latest/BGL/group__PkgBGLTraits.html
Then you can refer to the documentation of the class to know how to
iterate over the vertex of the face.
There is even a generic helper function to do it:
for ( boost::graph_traits<Graph>::vertex_descriptor v :
CGAL::vertices_around_face(halfedge(f, g), g))
{
Point_3 p = get(boost::vertex_index, v, g);
}
I'm not saying it is easy to get but reading the doc gives you the
information required. It's not like reading vtk doc where you have
to guess or read the source code to understand things.
Anyway, we are always looking to improve our doc and we'll be soon
having some cross-packages tutorials and one about manipulation of
surface meshes in CGAL will surely be added.
if intersection is not null, then *intersection should be the Primitive_id of the primitive you are looking for.
Related
Why do I get odd 0,0 point in Octave trisurf
I am trying to draw a surface from a file on disk (shown below). But I get an odd additional point at co-ords (0,0). The file appears to be in correct shape to me. I draw the chart from my C# application with a call to Octave .Net. Here is the Octave part of the script: figure (1,'name','Map'); colormap('hot'); t = dlmread('C:\Map3D.csv'); # idx = find(t(:,4) == 4.0);t2 = t(idx,:); tx =t(:,1);ty=t(:,2);tz=t(:,3); tri = delaunay(tx,ty); handle = trisurf(tri,tx,ty,tz);xlabel('Floor');ylabel('HurdleF');zlabel('Sharpe'); waitfor(handle); This script is called from my C# app, with the following , very simple, code snippet: using (var octave = new OctaveContext()) { octave.Execute(script, int.MaxValue); } Can anyone explain if my Octave script is wrong, or the way I have structured the file. Floor,HurdleF,Sharpe,Model 1.40000000,15.00000000,-0.44,xxx1.40_Hrd_15.00 1.40000000,14.00000000,-0.49,xxx1.40_Hrd_14.00 1.40000000,13.00000000,-0.19,xxx1.40_Hrd_13.00 1.40000000,12.00000000,-0.41,xxx1.40_Hrd_12.00 1.40000000,11.00000000,0.42,xxx1.40_Hrd_11.00 1.40000000,10.00000000,0.17,xxx1.40_Hrd_10.00 1.40000000,9.00000000,0.28,xxx1.40_Hrd_9.00 1.40000000,8.00000000,0.49,xxx1.40_Hrd_8.00 1.40000000,7.00000000,0.45,xxx1.40_Hrd_7.00 1.40000000,6.00000000,0.79,xxx1.40_Hrd_6.00 1.40000000,5.00000000,0.56,xxx1.40_Hrd_5.00 1.40000000,4.00000000,1.76,xxx1.40_Hrd_4.00 1.30000000,15.00000000,-0.46,xxx1.30_Hrd_15.00 1.30000000,14.00000000,-0.55,xxx1.30_Hrd_14.00 1.30000000,13.00000000,-0.24,xxx1.30_Hrd_13.00 1.30000000,12.00000000,0.35,xxx1.30_Hrd_12.00 1.30000000,11.00000000,0.08,xxx1.30_Hrd_11.00 1.30000000,10.00000000,0.63,xxx1.30_Hrd_10.00 1.30000000,9.00000000,0.83,xxx1.30_Hrd_9.00 1.30000000,8.00000000,0.21,xxx1.30_Hrd_8.00 1.30000000,7.00000000,0.55,xxx1.30_Hrd_7.00 1.30000000,6.00000000,0.63,xxx1.30_Hrd_6.00 1.30000000,5.00000000,0.93,xxx1.30_Hrd_5.00 1.30000000,4.00000000,2.50,xxx1.30_Hrd_4.00 1.20000000,15.00000000,-0.40,xxx1.20_Hrd_15.00 1.20000000,14.00000000,-0.69,xxx1.20_Hrd_14.00 1.20000000,13.00000000,0.23,xxx1.20_Hrd_13.00 1.20000000,12.00000000,0.56,xxx1.20_Hrd_12.00 1.20000000,11.00000000,0.22,xxx1.20_Hrd_11.00 1.20000000,10.00000000,0.56,xxx1.20_Hrd_10.00 1.20000000,9.00000000,0.79,xxx1.20_Hrd_9.00 1.20000000,8.00000000,0.20,xxx1.20_Hrd_8.00 1.20000000,7.00000000,1.09,xxx1.20_Hrd_7.00 1.20000000,6.00000000,0.99,xxx1.20_Hrd_6.00 1.20000000,5.00000000,1.66,xxx1.20_Hrd_5.00 1.20000000,4.00000000,2.23,xxx1.20_Hrd_4.00 1.10000000,15.00000000,-0.31,xxx1.10_Hrd_15.00 1.10000000,14.00000000,-0.18,xxx1.10_Hrd_14.00 1.10000000,13.00000000,0.24,xxx1.10_Hrd_13.00 1.10000000,12.00000000,0.70,xxx1.10_Hrd_12.00 1.10000000,11.00000000,0.31,xxx1.10_Hrd_11.00 1.10000000,10.00000000,0.76,xxx1.10_Hrd_10.00 1.10000000,9.00000000,1.24,xxx1.10_Hrd_9.00 1.10000000,8.00000000,0.94,xxx1.10_Hrd_8.00 1.10000000,7.00000000,1.09,xxx1.10_Hrd_7.00 1.10000000,6.00000000,1.53,xxx1.10_Hrd_6.00 1.10000000,5.00000000,2.41,xxx1.10_Hrd_5.00 1.10000000,4.00000000,2.16,xxx1.10_Hrd_4.00 1.00000000,15.00000000,-0.41,xxx1.00_Hrd_15.00 1.00000000,14.00000000,-0.24,xxx1.00_Hrd_14.00 1.00000000,13.00000000,0.33,xxx1.00_Hrd_13.00 1.00000000,12.00000000,0.18,xxx1.00_Hrd_12.00 1.00000000,11.00000000,0.61,xxx1.00_Hrd_11.00 1.00000000,10.00000000,0.96,xxx1.00_Hrd_10.00 1.00000000,9.00000000,1.75,xxx1.00_Hrd_9.00 1.00000000,8.00000000,0.74,xxx1.00_Hrd_8.00 1.00000000,7.00000000,1.63,xxx1.00_Hrd_7.00 1.00000000,6.00000000,2.12,xxx1.00_Hrd_6.00 1.00000000,5.00000000,2.73,xxx1.00_Hrd_5.00 1.00000000,4.00000000,2.03,xxx1.00_Hrd_4.00 0.90000000,15.00000000,-0.42,xxx0.90_Hrd_15.00 0.90000000,14.00000000,-0.37,xxx0.90_Hrd_14.00 0.90000000,13.00000000,0.58,xxx0.90_Hrd_13.00 0.90000000,12.00000000,0.03,xxx0.90_Hrd_12.00 0.90000000,11.00000000,0.68,xxx0.90_Hrd_11.00 0.90000000,10.00000000,0.79,xxx0.90_Hrd_10.00 0.90000000,9.00000000,1.54,xxx0.90_Hrd_9.00 0.90000000,8.00000000,0.82,xxx0.90_Hrd_8.00 0.90000000,7.00000000,1.81,xxx0.90_Hrd_7.00 0.90000000,6.00000000,2.33,xxx0.90_Hrd_6.00 0.90000000,5.00000000,2.99,xxx0.90_Hrd_5.00 0.90000000,4.00000000,1.71,xxx0.90_Hrd_4.00 0.80000000,15.00000000,-0.46,xxx0.80_Hrd_15.00 0.80000000,14.00000000,-0.26,xxx0.80_Hrd_14.00 0.80000000,13.00000000,0.55,xxx0.80_Hrd_13.00 0.80000000,12.00000000,0.07,xxx0.80_Hrd_12.00 0.80000000,11.00000000,0.65,xxx0.80_Hrd_11.00 0.80000000,10.00000000,1.08,xxx0.80_Hrd_10.00 0.80000000,9.00000000,1.27,xxx0.80_Hrd_9.00 0.80000000,8.00000000,1.12,xxx0.80_Hrd_8.00 0.80000000,7.00000000,1.98,xxx0.80_Hrd_7.00 0.80000000,6.00000000,2.62,xxx0.80_Hrd_6.00 0.80000000,5.00000000,3.35,xxx0.80_Hrd_5.00 0.80000000,4.00000000,1.27,xxx0.80_Hrd_4.00 0.70000000,15.00000000,-0.56,xxx0.70_Hrd_15.00 0.70000000,14.00000000,-0.33,xxx0.70_Hrd_14.00 0.70000000,13.00000000,0.24,xxx0.70_Hrd_13.00 0.70000000,12.00000000,-0.22,xxx0.70_Hrd_12.00 0.70000000,11.00000000,0.74,xxx0.70_Hrd_11.00 0.70000000,10.00000000,1.19,xxx0.70_Hrd_10.00 0.70000000,9.00000000,1.24,xxx0.70_Hrd_9.00 0.70000000,8.00000000,1.14,xxx0.70_Hrd_8.00 0.70000000,7.00000000,2.26,xxx0.70_Hrd_7.00 0.70000000,6.00000000,2.70,xxx0.70_Hrd_6.00 0.70000000,5.00000000,3.52,xxx0.70_Hrd_5.00 0.70000000,4.00000000,1.05,xxx0.70_Hrd_4.00 0.60000000,15.00000000,-0.50,xxx0.60_Hrd_15.00 0.60000000,14.00000000,-0.60,xxx0.60_Hrd_14.00 0.60000000,13.00000000,0.11,xxx0.60_Hrd_13.00 0.60000000,12.00000000,-0.16,xxx0.60_Hrd_12.00 0.60000000,11.00000000,0.73,xxx0.60_Hrd_11.00 0.60000000,10.00000000,1.08,xxx0.60_Hrd_10.00 0.60000000,9.00000000,1.31,xxx0.60_Hrd_9.00 0.60000000,8.00000000,1.38,xxx0.60_Hrd_8.00 0.60000000,7.00000000,2.24,xxx0.60_Hrd_7.00 0.60000000,6.00000000,2.89,xxx0.60_Hrd_6.00 0.60000000,5.00000000,3.50,xxx0.60_Hrd_5.00 0.60000000,4.00000000,1.11,xxx0.60_Hrd_4.00 0.50000000,15.00000000,-0.40,xxx0.50_Hrd_15.00 0.50000000,14.00000000,-0.37,xxx0.50_Hrd_14.00 0.50000000,13.00000000,0.13,xxx0.50_Hrd_13.00 0.50000000,12.00000000,-0.11,xxx0.50_Hrd_12.00 0.50000000,11.00000000,0.61,xxx0.50_Hrd_11.00 0.50000000,10.00000000,0.92,xxx0.50_Hrd_10.00 0.50000000,9.00000000,1.41,xxx0.50_Hrd_9.00 0.50000000,8.00000000,1.39,xxx0.50_Hrd_8.00 0.50000000,7.00000000,2.19,xxx0.50_Hrd_7.00 0.50000000,6.00000000,2.80,xxx0.50_Hrd_6.00 0.50000000,5.00000000,3.41,xxx0.50_Hrd_5.00 0.50000000,4.00000000,1.05,xxx0.50_Hrd_4.00 0.40000000,15.00000000,-0.25,xxx0.40_Hrd_15.00 0.40000000,14.00000000,-0.44,xxx0.40_Hrd_14.00 0.40000000,13.00000000,0.02,xxx0.40_Hrd_13.00 0.40000000,12.00000000,0.00,xxx0.40_Hrd_12.00 0.40000000,11.00000000,0.69,xxx0.40_Hrd_11.00 0.40000000,10.00000000,0.67,xxx0.40_Hrd_10.00 0.40000000,9.00000000,1.02,xxx0.40_Hrd_9.00 0.40000000,8.00000000,1.29,xxx0.40_Hrd_8.00 0.40000000,7.00000000,2.17,xxx0.40_Hrd_7.00 0.40000000,6.00000000,2.88,xxx0.40_Hrd_6.00 0.40000000,5.00000000,3.19,xxx0.40_Hrd_5.00 0.40000000,4.00000000,0.98,xxx0.40_Hrd_4.00 0.30000000,15.00000000,-0.02,xxx0.30_Hrd_15.00 0.30000000,14.00000000,-0.36,xxx0.30_Hrd_14.00 0.30000000,13.00000000,-0.26,xxx0.30_Hrd_13.00 0.30000000,12.00000000,-0.11,xxx0.30_Hrd_12.00 0.30000000,11.00000000,0.50,xxx0.30_Hrd_11.00 0.30000000,10.00000000,0.50,xxx0.30_Hrd_10.00 0.30000000,9.00000000,1.01,xxx0.30_Hrd_9.00 0.30000000,8.00000000,1.28,xxx0.30_Hrd_8.00 0.30000000,7.00000000,2.11,xxx0.30_Hrd_7.00 0.30000000,6.00000000,2.89,xxx0.30_Hrd_6.00 0.30000000,5.00000000,3.16,xxx0.30_Hrd_5.00 0.30000000,4.00000000,0.95,xxx0.30_Hrd_4.00
What's happening dlmread() is reading the file in as numeric data and returning a numeric matrix. It doesn't recognize the text in your header line, so it silently converts that row to all zeros. (IMHO this is a design flaw in dlmread.) Remove the header line. How to debug this So, you've got some zeros in your plot that you didn't expect to be there? Check for zeros in your input data: ixZerosX = find(tx == 0) ixZerosY = find(ty == 0) ixZerosZ = find(tz == 0) The semicolons are omitted intentionally there to get Octave to automatically display the results. Better yet, since doubles are an approximate type, and the values might be close to but not actually zero, do a "near zero" search: threshold = 0.1; ixZerosX = find(abs(tx) < threshold) ixZerosY = find(abs(ty) < threshold) ixZerosZ = find(abs(tz) < threshold)
Randomly selecting an object property
I guess a step back is in order. My original question is at the bottom of this post for reference. I am writing a word guessing game and wanted a way to: 1. Given a word length of 2 - 10 characters, randomly generate a valid english word to guess 2.given a 2 - 10 character guess, ensure that it is a valid english word. I created a vector of 9 objects, one for each word length and dynamically created 172000 property/ value pairs using the words from a word list to name the properties and setting their value to true. The inner loop is: for (i = 0; i < _WordCount[wordLength] - 2; i) { _WordsList[wordLength]["" + _WordsVector[wordLength][i++]] = true; } To validate a word , the following lookup returns true if valid: function Validate(key:String):Boolean { return _WordsList[key.length - 2][key] } I transferred them from a vector to objects to take advantage of the hash take lookup of the properties. Haven't looked at how much memory this all takes but it's been a useful learning exercise. I just wasn't sure how best to randomly choose a property from one of the objects. I was thinking of validating whatever method I chose by generating 1000 000 words and analyzing the statistics of the distribution. So I suppose my question should really first be am I better off using some other approach such as keeping the lists in vectors and doing a search each time ? Original question Newbie first question: I read a thread that said that traversal order in a for.. in is determined by a hash table and appears random. I'm looking for a good way to randomly select a property in an object. Would the first element in a for .. in traversing the properties, or perhaps the random nth element in the iteration be truly random. I'd like to ensure that there is approximately an equal probability of accessing a given property. The Objects have between approximately 100 and 20000 properties. Other approaches ? thanks.
Looking at the scenario you described in your edited question, I'd suggest using a Vector.<String> and your map object. You can store all your keys in the vector and map them in the object, then you can select a random numeric key in the vector and use the result as a key in the map object. To make it clear, take a look at this simple example: var keys:Vector.<String> = new Vector.<String>(); var map:Object = { }; function add(key:String, value:*):void { keys.push(key); map[key] = value; } function getRandom():* { var randomKey = keys[int(Math.random() * keys.length)]; return map[randomKey]; } And you can use it like this: add("a", "x"); add("b", "y"); add("c", "z"); var radomValue:* = getRandom(); Using Object instead of String Instead of storing the strings you can store objects that have the string inside of them, something like: public class Word { public var value:String; public var length:int; public function Word(value:String) { this.value = value; this.length = value.length; } } Use this object as value instead of the string, but you need to change your map object to be a Dictionary: var map:Dictionary = new Dictionary(); function add(key:Word, value:*):void { keys.push(key); map[key] = value; } This way you won't duplicate every word (but will have a little class overhead).
How do I set a function to a variable in MATLAB
As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function. Here is my code, before I go on: function [ Ts ] = BisectionRoot( fun,a,b,TolMax ) %This function finds the value of Ts by finding the root of a given function within a given range to a given %tolerance, using the Bisection Method. Fa = fun(a); Fb = fun(b); if Fa * Fb > 0 disp('Error: The function has no roots in between the given bounds') else xNS = (a + b)/2; toli = abs((b-a)/2); FxNS = fun(xns); if FxNS == 0 Ts = xNS; break end if toli , TolMax Ts = xNS; break end if fun(a) * FxNS < 0 b = xNS; else a = xNS; end end Ts end The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this) My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem: F = # (x) 8-4.5*(x-sin(x)) But when I try doing that, I get the error, Error: Unexpected MATLAB operator. If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book: fun = 8 - 4.5*(x - sin(x)) a = 2 b = 3 TolMax = .001 The answer the get in the book for using those is 2.430664. I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question): fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#" F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9" Use fun = #(x) 8 - 4.5*(x - sin(x)) Then you would call your function like this: fun = #(x) 8 - 4.5*(x - sin(x)); a = 2; b = 3; TolMax = .001; root = BisectionRoot( fun,a,b,TolMax ); To debug (which you will need to do), use the debugger. The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack. Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor. dbquit quits debug mode dbclear all clears all break points
1050 Cannot assign to a non-reference value as3
I'm having some trouble with the error "1050: Cannot assign to a non-reference value." I'm still fairly new to coding, and so being unable to fix this error is frustrating, any help will be greatly appreciated. var PracticeDummyHealth:int=50 var PlayerAttack:int=20; public function PlayerAttackFunction(){ if(PracticeDummyHealth>0){ PracticeDummyHealth-PlayerAttack=PracticeDummyHealth; } }
An grammar construct which is not a Property/Variable name is on the left of the = assignment operator: // expression = expression PracticeDummyHealth-PlayerAttack=PracticeDummyHealth; // which makes as much sense to ActionScript as .. it's not an equation solver :) // 100 - 50 = 100 Compare with this valid code: // variable = new_value PracticeDummyHealth = PracticeDummyHealth - PlayerAttack; // or PracticeDummyHealth -= PlayerAttack; Note that a "reference" (read: Property/Variable name) appears on the left of the = (or compound -=) in both of these cases. This terminology comes from the specification which deals with l-values and it is slightly unfortunate it doesn't yield a nicer error message here.
How to find specific value in a large object in node.js?
Actually I've parsed a website using htmlparser and I would like to find a specific value inside the parsed object, for example, a string "$199", and keep tracking that element(by periodic parsing) to see the value is still "$199" or has changed. And after some painful stupid searching using my eyes, I found the that string is located at somewhere like this: price = handler.dom[3].children[3].children[3].children[5].children[1]. children[3].children[3].children[5].children[0].children[0].raw; So I'd like to know whether there are methods which are less painful? Thanks!
A tree based recursive search would probably be easiest to get the node you're interested in. I've not used htmlparser and the documentation seems a little thin, so this is just an example to get you started and is not tested: function getElement(el,val) { if (el.children && el.children.length > 0) { for (var i = 0, l = el.children.length; i<l; i++) { var r = getElement(el.children[i],val); if (r) return r; } } else { if (el.raw == val) { return el; } } return null; } Call getElement(handler.dom[3],'$199') and it'll go through all the children recursively until it finds an element without an children and then compares it's raw value with '$199'. Note this is a straight comparison, you might want to swap this for a regexp or similar?