• Advertisement

# taz0010

Member

423

277 Neutral

• Rank
Member
1. ## Culling points from a polygon.

I have solved problems very similar to this by using the "Signed triangle area" formula.   http://geomalgorithms.com/a01-_area.html   All you need to do is loop over the points in the shape, and test the triangle at each vertex. i.e. for vertex v, you form the triangle with vertices {v-1, v, v+1}. You know the shape has vertices in a straight line if the triangle area is very close to zero. Unfortunately you can't rely on using an exact comparison against zero when dealing with floating point numbers, so you compare against epsilon (+-0.000001 or whatever suits).
2. ## how to delete two objects that are circularly linked

Are the references actually circular or are you just talking about a node which may belong to multiple entities? To handle the latter you can use a std::shared_ptr wrapper for your node objects. It will automatically count the number of references to the node and call the delete operator when the object containing the last reference is deleted.   Dealing with circular references is much harder. Some approaches are to use weak pointers (std::weak_ptr) to allow an object to know about another without having ownership (i.e. holding the weak reference will not prevent the object from being deleted). If you can't design the solution in this way, there are more elaborate methods where you scan your objects, detect the circular reference and delete objects which are unreachable in the graph. But it's normally much simpler to just not use (strong) circular references at all.
3. ## make an object that is pointing in a direction rotate to point in another direction

You have your old and new direction vectors, so the problem is simply a matter of building the rotation matrix to rotate the first vector onto the second. You use the cross and dot product to get the rotation axis and angle.   Assuming that oldV and newV are normalised: axisOfRotation = crossProduct(oldV, newV).normalise(); // Depending on whether your library requires normalised rotation axes angleOfRotation = arccos(dotProduct(oldV, newV));   Whatever library you're using should have a function that builds a rotation matrix from an axis and angle of rotation, so there's no need to manually code a whole bunch of math.
4. ## Calculating angles of rotation

I'd do it like this: 1) Project the destination vector onto the XZ axis. Do this simply by setting the y component to zero. The projected vector will no longer be normalised. 2) Get the angle between the object's vector and the vector resulting from 1), and rotate around the y axis by this amount. 3) Now you can rotate your object onto the destination vector using the method outlined earlier in this thread (cross product vectors to get rotation axis, dot product to find angle). This will cause the object to point at the destination vector without any undesired rotation along the object's local x axis.
5. ## Bit Flags vs. Boolean

One thing to keep in mind is that accessing bit fields will require the compiler to produce additional bit masking instructions, which will *increase* the memory footprint of your instruction code. If you try to use bit fields as a general rule instead of a situational optimisation, you'll end up with slower code. Also, the alignment issues are subtle. Most types want to align on 4 byte boundaries, so AFAIK if you have a structure containing, say, an integer, and any less than 5 flags, then converting these flags to single bits won't save any space at all.
6. ## Is that way of using constructor really better ?

[quote]Most modern compilers will optimize the trivial stuff. So I only stick important things (large items, parent classes, references, ect...) in the initializer list, as I really don't like them. My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.[/quote] Why is this being voted down? His gripe about the initialiser list order not being the actual initialisation order is perfectly valid. It's intuitive to assume that the variables are going to be initialised in the order that the initialisation code is written - which is exactly the case whenever you initialise something using the equals sign. Also mentioned in this topic, ordering your members for alignment or caching reasons can potentially break your code if one member was initialised using the value of another. And since headers are used, the potential error will not even be visible in the file where the initialisation code is actually written. Personally if I have primitive variables that I need to initialise in a specific order, I'm not going to rely on the class definition order to do it, and that means good old fashioned assignment with the = operator.
7. ## Why is it faster to develop in certain languages over others?

As pointed out, the lack of built in libraries is by far the biggest issue. There's also a fair bit of boilerplate involved in implementing proper "rule of 5" (formally known as the rule of 3...) classes, and the header system is relatively complicated and requires you to jump from source to header file as you're adding new methods. And debugging compiler errors in template classes is potentially a time waster, since they can be *very* cryptic, and usually you're not told which part of the calling code actually triggered the error. c++ does allow you to implement RAII based memory management which is much better than garbage collected implementations when you need to control exactly when you release a resource. It's easy to make mistakes and leak memory building a c++ object, but when correctly implemented, the caller rarely has to worry about managing memory at all.
8. ## Initialize variables out of a loop?

[quote]The compiler can surely deduce that the value of Length is immutable, even if only because there is no assignment anywhere to the array or any element of the array [and thus the array itself can be treated as immutable in that context]. Whether this is being done, it's hard to say, especially given the current setup.[/quote] The reason the compiler isn't optimising out the call is because there's no guarantee that the value isn't being changed by another thread. Other compilers might optimise more aggressively and rely on the programmer to use the proper keywords (volatile) on all objects used in multithreading, but VS does not. I'm not 100% sure of the situation in C#, but in c++ under VS, levels of indirection are not cached at all. If you access a->b->c multiple times, you pay for the dereferences each time. This might be different if you create everything on the stack and don't use dynamic allocation at all, however. I prefer to write my loops like this: for (int i = 0, len = x.Length; i < len; ++i) { // actions } This should produce optimal code while avoiding the need to waste lines on declarations. Of course the effort is only of benefit 1% of the time (premature optimisation and all), but if you get in the habit of writing all loops like that, you're not wasting any time.
9. ## How far do you go to encapsulate?

Providing a function to return a const reference to the widget collection is the level of encapsulation I usually settle on. Controlling changes to the underlying container by requiring people to use your implementation of addWidget() rather than vector push_back(), is likely to mitigate most of the problems you'd face when changing your implementation in the future. Most of the time classes containing collections will perform some logic behind the scenes when the user adds or removes something, so not exposing a mutable collection object is just thinking ahead. But really, you can skip all the headache and just use a map. Expose find, insert and delete methods, and bidirectional iterators for traversal. If you provide the flexibility of maps from the beginning, you don't have to worry about breaking the implementation if you find out you need them in the future. Plus there are several avenues of optimisation of this structure without breaking the interface, should the situation warrant. (You could switch to hash_maps, etc)
10. ## Placing random points on map

Start by adding points randomly to the terrain, and then gradually remove points until you achieve the desired density. You can use spatial hashing techniques to divide your region up into equal sized squares, allowing you to query the points in a square and it's neighbours very quickly. Then you can take all the points within a fixed distance of the query point, and replace them with a single point whose position is the average of it's neighbours. Increase the threshold distance if the points in question are on water. Depending on how you tweak it, you might end up with no points being closer than a certain distance. Or if you prefer, you could randomly decide whether to merge points, in order to allow points to occasionally be close together, but not often.
11. ## Bind single-threaded apps to a single core

What's the preferred method of dealing with the "QPC on old dual core machines" problem? Do developers simply ignore the issue? I was one of the unlucky people to experience the bug and it was definitiely present in several big name titles I played. Is it safe to conclude that QPC is fixed on modern (all quad core and above) platforms?
12. ## Factorial Recursion

Considering that your average recursive function with a stack growth of log(n) is likely to only overflow some point after the universe reaches maximum entropy, I wouldn't be too worried about it. And this is only possible with algorithms implemented in a way where the upper bound isn't simply a function of the datatype size. (i.e. 2^32 or 2^64 max values for a comparison sort). Stack size is a compiler option you can control anyhow.
13. ## Ultra-Fast 2D AABB Overlap Test

Branch elimination usually results in a performance hit rather than gains on modern CPUs. For this reason, writing branchless code sometimes results in the compiler restructuring the code and putting the branches right back in there! This is the case when you deliberately use & rather than && in conditional statements. You should also consider that this particular operation (AABB collision) may have an extremely high branch prediction rate. Also, reinterpret casting between float and integer can drastically impact performance as the compiler/CPU has to copy the value to memory in between the move between floating point and integer registers. The only thing that really works is using SSE to vectorise (perform 4 tests at a time).
14. ## c++ : Deleting object (not just its pointer) from vector

You always need to read the documentation to make sure you aren't causing memory leaks when using API functions. Functions with "create" in their name typically allocate memory, and functions with "get" sometimes increment reference counts. The documentation will tell you if you need to call the corresponding "free" or "release" functions.
15. ## boost::shared_ptr suitable for iphone games?

As far as I know, Objective-C's reference counting scheme is intrusive, but shared_ptr allocates from the heap. Considering that c++ objects are potentially MUCH faster than their Objective-C ounterparts, I wouldn't worry about the overhead of storing the reference count separate from the object.
• Advertisement