Libgdx Box2D fixtures that are both sensors and non sensors? - libgdx

Let's say I have Bodies A, B, and C each with one fixture. It is possible to have fixtures A and B interact with each other with one or both being a sensor so no physics interaction occurs, but have both A and B have physics interactions with fixture C? So, A-B = no interaction, A-C = interaction, B-C = interaction

You should look into collision filtering (masking)
By setting up categories and masks for different objects you can control which ones are allowed to interact with each other.
// create categories
final short A = 0x0001; // 0000000000000001 in binary
final short B = 0x0002; // 0000000000000010 in binary
final short C = 0x0004; // 0000000000000100 in binary
// create masks
final short AM = 0x0006 // 0000000000000110 in binary
final short BM = 0x0006 // 0000000000000110 in binary
final short CM = 0x0001 // 0000000000000001 in binary
// apply masks and categories to fixtures
FixtureDef ADef = new FixtureDef();
ADef.filter.categoryBits = A;
ADef.filter.maskBits = AM;

Yes, this is possible using mask bits and category bits. These allow fixtures to only interact with certain other fixtures defined using these bits.
Category bits define the fixtures type, the default being 0.
Mask bits define which categories of fixtures the fixture can interact with.
So, for A and B to interact with C but not with each other, we need to apply the following category bits:
A.filter.categoryBits = 0x0001; //binary: 01
B.filter.categoryBits = 0x0001; //binary: 01
C.filter.categoryBits = 0x0002; //binary: 10
And the following mask bits:
A.filter.maskBits = 0x0002; //binary: 10
B.filter.maskBits = 0x0002; //binary: 10
C.filter.maskBits = 0x0001; //binary: 01
Since A and B are category 0x0001 and C has mask 0x0001, C can interact with A and B. A and B do not contain 0x0001 in their mask so cannot interact with each other.
A more in-depth explanation and example can be found here.

Related

Problem with combining ForwardDiff and PyPlot in Julia 1.0.5

In Julia 1.0.5, I have a function f(x::Vector{<:Real}), defined as
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
The signature is like this, because I would like to use it with the ForwardDiff package, and it works with it just fine. I give the function to ForwardDiff.gradient, and everything works like a charm.
However, I would also like to do some visualizations with PyPlot, using this same function f. Namely, I would like to draw its contour with contourf. For this purpose, I have constructed two vectors X::Vector{<:Real} and Y::Vector{<:Real}, and would like to call the same function f with them to produce the contour.
However, making the call f.([X, Y]) is not broadcasting the vectors as I would like, as I get the error
LoadError: MethodError: no method matching (::getfield(Main, Symbol("#f#1044")))(::Int64)
Closest candidates are:
f(!Matched::Array{#s25,1} where #s25<:Real)
This of course prevents me from using the contourf function, as it needs the values of f on a 2D-grid.
Do I need to define an entirely different f(x::Vector{<:Real}, y::Vector{<:Real}) to be able to plot the contour as I would like, or is there an alternative where I can avoid this?
this problem can be resolved by the power of multiple dispatch:
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
f(x::Real,y::Real) = f([x,y])
nx = 10
ny = 20
X = rand(nx) #mesh of x points
Y = rand(ny) #mesh of y points
Z = f.(transpose(X),Y) #nx x ny matrix
for the two argument gradient:
two_point_gradient(f,x,y) = ForwardDiff.gradient(f,[x,y])
G = two_point_gradient.(f,transpose(X),Y) #returns a vector of gradients, where G[i..] = gradient(f,X[i..],Y[i...])

actionscript 3 - random object selection

So I want a unit to be able to randomly target a player unit or a players allies.
I have all ally ships stored in an array and the player is on the stage separately.
Here is the code for the bullet creation, with the irrelevant stuff removed.
private function createBullet(): void {
var rand = allies[Math.floor(Math.random()*allies.length)];
_endX = rand.x
_endY = rand.y
}
With the code above I can make them target random ally ships, but I also want it to include the player ship (_player) when randomly selecting a target, but I cant add the player to the ally array so Im not really sure what to do.
When you multiply a random number by length of array, add plus one to length.
If generated index is equal to the allies length, this means that "rand" is _player.
var randomIndex:int = Math.floor(Math.random() * (allies.length + 1));
var rand:*;
if (randomIndex == allies.length - 1)
rand = _player;
else
rand = allies[randomIndex];
...

how to see/extract model flows evolution when solve a model in a Scilab function?

I wrote the Lotka Voterra model (prey-predator) as a Scilab function and solved it with ODE. My problem is that I want to see the flows evolution. I found a solution by including flows in the resolution (in the script below only for one) but it’s really “heavy”. Anyone has a better solution?
//parameters
x=[0.04,0.005,0.3,0.2]
n = x(1);//birth rate of prey
c = x(2);//capture rate
e = x(3);//energy from capture
m = x(4);//death rate or predator
Tmax=100; // maximum time of simulation
dt=0.01; // step of time
t=0:dt:Tmax; //simulation time definition
Ci = [20,30,0]'; //initial conditions (including for 1 flow)
//Lotka Volterra model
function [dy]=LV(t, y, n, c, e, m)
GrowthP = n * y(1)
IngestC = c * y(1) * y(2)
MortC = m * y(2)
dy(1) = GrowthP - IngestC
dy(2) = IngestC * e - MortC
dy(3) = IngestC //here one flow in ode
endfunction
//resolution
sol=ode(Ci,0,t,LV)
//dataframe creation to stock data
soldef=zeros(3,10001);
//for the line 3 and form 2 to the last data it take the value,
//remove the one of the previous time step and store it in soldef
for i = 2:length(sol(3,:))
soldef(3,i)=sol(3,i)-sol(3,i-1);
end
//complete the dataframe with the stock
soldef(1:2,:)=sol(1:2,:)
Thanks for the interest and the time you give to my problem (and sorry for my English)
If you want animated display of your results, you can use the code below to plot more and more data on a graph:
[row,col]=size(soldef);
scf(0);
clf(0);
plot2d(soldef(:,1:2)',rect=[0,0,col,max(soldef)]); //plot first 2 points
en=gce(); //handle of the graphic entities
for i=3:col //plot more and more points
en.children(1).data=[1:i;soldef(3,1:i)]'; //update data matrices
en.children(2).data=[1:i;soldef(2,1:i)]';
en.children(3).data=[1:i;soldef(1,1:i)]';
//you can save the frames here...
xpause(1e4); //wait some time if amination is too fast
end
If you save all the graphs (with e.g.xs2gif()), with an external application (google for "gif maker") you can even make a .gif animation of your results to embedd in a webpage or presentation.

Can't read Exif info for some photos

I'm making photo renaming tool on Adobe AIR and has encountered a problem with reading EXIF info for some pictures. Those pictures do not vary from many others whose EXIF i can read and have been taken at the same time on the same camera.
I tried to use both exif reading libs: Exif Extractor and ExifInfo by shichiseki. And both of them can't read it.
I anylized the code of ExifInfo lib and found out that it returns null because those particluar photos don't have some unsigned byte (returned by ByteArray.readUnsignedByte() method).
The oddity is that Windows' Explorer shows exif info as in general like for other pictures.
UPDATE:
i've just found the reason of losing those unsigned bytes. These are the photos to which i added keywords in Windows Explorer. So they still have exif info but lose those damn bytes.
UPDATE 2:
Further research showed that normal picture (without tags) has unsigned bytes as follows:
b = 255
b = 216
b = 255
b = 224
b = 255
b = 225
b = 69
b = 120
b = 105
b = 102
b = 0
b = 0
And tagged one:
b = 255
b = 216
b = 255
b = 224
b = 255
b = 238
So it return false on that last "238" byte, which i guess, doesn't equal to one of [0xff, 0xe1].
Some pictures that Exif can't be read do not comply to other byte rules, stated as constants in ExifInfo class:
private const SOI_MAKER:Array = [0xff, 0xd8];
private const JFIF_MAKER:Array = [0xff, 0xe0];
private const APP1_MAKER:Array = [0xff, 0xe1];
private const EXIF_HEADER:Array = [0x45, 0x78, 0x69, 0x66, 0x00, 0x00];
UPDATE 3:
My next try was shifting position of picture ByteArray's stream for 14 bytes (the place where needed 255 and 225 unsigned bytes reside) and it solved the problem.
So i edited a bit of the main class ExifInfo.as (shichiseki's lib) from
if ( !hasAPP1Maker(stream)) {
return false;
}
to:
if ( !hasAPP1Maker(stream)) {
stream.position += 14;
if ( !hasAPP1Maker(stream)) {
stream.position -= 14;
return false;
}
}
I don't actually understand why and what i really did. Just traced unsigned bytes for such pictures from 0 to 255 and found those bytes for APP1_MAKER constant a little further in a stream. So it works. Hope may help someone.

Overlapping line segments in 2D space

I need to find whether two lines overlap each other. I have the intersection code which returns 0, if two lines are parallel. But then I need to know if these two parallel lines overlap.
Edit:
A C B D
-----------------------------------------------
Line 1: A-B
Line 2: C-D
I need to find if Line 1 overlaps Line 2, but both lines can have a slope > 0.
You can compare to find if there is no over lap. you will have less comparisons in this way thus very efficient. Do following comparisons
D < A
B < C
If either case is true the lines are not overlapping. otherwise there must an overlap.
You will make least number of comparisons to determine if they are not overlapping. Otherwise there will be more comparisons to make.
Since you know they're both parallel, then just check whether line segment CD contains either of the endpoints of the first line (point A and point B).
For two co-linear line segments that are not necessarily axis-aligned:
Sort the vertices in clockwise order around the origin.
The lines overlap if the ordered vertices alternate between the two segments, e.g. Line1.Point1, Line2.Point1, Line1.Point2, Line2.Point2.
It is sufficient to calculate the areas of triangles ACB and CBD. If the area is 0, then the points are collinear, and if both areas are zero then the lines are overlapping.
You can calculate the area of a triangle ABC by this formula:
2*Area(ABC)= (bx – ax)(cy – ay) – (cx – ax)(by – ay);
Line equation is direction of line in infinite, by finding slope or intercept you wont be able do anything with them(even though horizontal line doesn't have slope), i suggest use point on line.
so AB is your line [(x,y),(x,y)] and C is on of the point (x,y) and then you need to check if point on the line.
Check Point On a Line
We are given two line segments
AB = line segment from (Ax,Ay) to (Bx,By)
CD = line segment from (Cx,Cy) to (Dx,Dy)
with the same slope.
Order the endpoints E1 < E2 < E3 < E4 such that Ei,x ≤ Ei+1,x and Ei,y ≤ Ei+1,y if Ei,x = Ei+1,x
If E1 and E2 are from different segments, the overlap is the segment from E2 to E3.
There are some degenerate cases:
A < B = C < D
A < C = D < B
A < B = C = D
A = B = C = D
These result in a single point of intersection. I'm not sure if any of those can occur in your system, but if so you'll have to decide whether or not you consider that "overlap" and add special case checks.
The characteristic of two segments of being in the same lines is called collinearity and can be tested calculating the area of the 2 triangles formed by one segment endpoints and, respectively, the endpoints of the other segment. If the area is zero or close to zero below a threshold the segments are collinear.
public static bool AreSegmentsCollinear(Segment a, Segment b, double epsilon)
{
return IsPointCollinear(a, b.Left, epsilon) && IsPointCollinear(a, b.Right, epsilon);
}
public static bool IsPointCollinear(Segment a, Vector2D p, double epsilon)
{
return Math.Abs(GetSignedTriangleArea2(a, p)) <= epsilon;
}
/// <returns>The squared signed area of the triangle formed with endpoints
/// of segment a and point p</returns>
public static double GetSignedTriangleArea2(Segment a, Vector2D p)
{
return (p - a.Left) ^ (a.Right - a.Left);
}
/// <summary>Cross product of vectors in 2D space. NB: it returns a
/// magnitude (scalar), not a vector</summary>
/// <returns>The area of the parallelogram formed with u, v as the edges</returns>
public static Double operator ^(Vector2D u, Vector2D v)
{
return u.X * v.Y - u.Y * v.X;
}
Just to be clear since there seems to be some confusion in the answers, the question being asked is as follows. Given two 2D line segments A and B how do I determine if both of the following are true:
A and B are colinear.
A and B intersect.
Note that there are tolerances involved in both questions i.e. how close to parallel and how near each other do A and B need to be to be considered colinear? How much do they need to overlap to be considered overlapping?
I think to handle such tolerances robustly the best algorithm is to treat the line segments as thin rectangles, where the thickness of the rectangles is a tolerance parameter t1. Let t2 be another tolerance parameter on slopes that are considered parallel. Then the algorithm becomes
If the slope of A and the slope of B are not within t2 of each other return false. To handle vertical lines cleanly, slope can be represented as a unit vector and the test can be on whether the Euclidean distance between the two unit vectors is smaller than t2.
Represent A and B as (non-axis-aligned) rectangles R1 and R2. Where R1 encloses A in the obvious way, i.e. it is length(A) + t1 units long and is t1 units wide with A centered inside it, and R2 analogously encloses B.
Determine if R1 and R2 intersect each other. This can be done relatively efficiently by treating each rectangle as the union of two triangles and testing for triangle-triangle intersections across all combinations of A triangles and B triangles. If there is an intersection return true; otherwise return false.
With lines l1 and l2 given in the following form [x1, y1, x2, y2] the following python code will give the intersection for collinear line segments with any slope.
intersection = line_intersect(l1, l2)
def line_intersect(l1, l2):
"""Find the intersection of two line segments"""
x1, y1, x2, y2 = l1
x3, y3, x4, y4 = l2
x_inter = component_intersect(x1, x2, x3, x4)
y_inter = component_intersect(y1, y2, y3, y4)
return math.sqrt(x_inter**2 + y_inter**2)
def component_intersect(c1, c2, c3, c4):
"""Calculate intersection in one dimension/component"""
# find left endpoints
cl1 = min(c1, c2)
cl2 = min(c3, c4)
# find right endpoints
cr1 = max(c1, c2)
cr2 = max(c3, c4)
# find endpoints of intersection
c_inter_l = max(cl1, cl2)
c_inter_r = min(cr1, cr2)
# calcuate intersection
c_inter = c_inter_r - c_inter_l
c_inter = max(c_inter, 0)
return c_inter