CP = cross product
A = target
src = object bumping
srcT2aT2aL = src's T to a's T to a's L
TriangleCollide(var/atom/A,var/BUMPED=FALSE,var/Dir2Move)
if(istype(src,/turf/Collision/Triangle/)) return FALSE //leave until finished debuging
var/a_p1_x = abs(A.true_x - (A.maxWidth - A.GetPoint("T",TRUE)))
var/a_p1_y = abs(A.true_y - (A.maxHeight - A.GetPoint("T",FALSE)))
var/a_p2_x = abs(A.true_x - (A.maxWidth - A.GetPoint("L",TRUE)))
var/a_p2_y = abs(A.true_y - (A.maxHeight - A.GetPoint("L",FALSE)))
var/a_p3_x = abs(A.true_x - (A.maxWidth - A.GetPoint("R",TRUE)))
var/a_p3_y = abs(A.true_y - (A.maxHeight - A.GetPoint("R",FALSE)))
var/src_p1_x = abs(src.true_x - (src.maxWidth - src.GetPoint("T",TRUE)))
var/src_p1_y = abs(src.true_y - (src.maxHeight - src.GetPoint("T",FALSE)))
var/src_p2_x = abs(src.true_x - (src.maxWidth - src.GetPoint("L",TRUE)))
var/src_p2_y = abs(src.true_y - (src.maxHeight - src.GetPoint("L",FALSE)))
var/src_p3_x = abs(src.true_x - (src.maxWidth - src.GetPoint("R",TRUE)))
var/src_p3_y = abs(src.true_y - (src.maxHeight - src.GetPoint("R",FALSE)))
//get the vectors, find the length of the vectors, normalize the vectors, then take their cross product
//if the cross product signs are equal, then the point is inside the triangle
var/srcT2aT_X=src_p1_x-a_p1_x //srcT to aT (X)
var/srcT2aT_Y=src_p1_y-a_p1_y
var/srcT2aL_X=src_p1_x-a_p2_x
var/srcT2aL_Y=src_p1_y-a_p2_y
var/srcT2aR_X=src_p1_x-a_p3_x
var/srcT2aR_Y=src_p1_y-a_p3_y
var/aT2aL_X=a_p1_x-a_p2_x
var/aT2aL_Y=a_p1_y-a_p2_y
var/aT2aR_X=a_p1_x-a_p3_x
var/aT2aR_Y=a_p1_y-a_p3_y
var/aL2aR_X=a_p2_x-a_p3_x
var/aL2aR_Y=a_p2_y-a_p3_y
//srcT vars
var/magSrcT2aT = sqrt((srcT2aT_X * srcT2aT_X) + (srcT2aT_Y * srcT2aT_Y) + 1) //sqrt((ax * ax) + (ay * ay) + (az * az))
var/magSrcT2aL = sqrt((srcT2aL_X * srcT2aL_X) + (srcT2aL_Y * srcT2aL_Y) + 1)
var/magSrcT2aR = sqrt((srcT2aR_X * srcT2aR_X) + (srcT2aR_Y * srcT2aR_Y) + 1)
var/magAT2aL = sqrt((aT2aL_X * aT2aL_X) + (aT2aL_Y * aT2aL_Y) + 1)
var/magAT2aR = sqrt((aT2aR_X * aT2aR_X) + (aT2aR_Y * aT2aR_Y) + 1)
var/magAL2aR = sqrt((aL2aR_X * aL2aR_X) + (aL2aR_Y * aL2aR_Y) + 1)
var/normSrcT2aT_X = srcT2aT_X/magSrcT2aT // a/|a|
var/normSrcT2aT_Y = srcT2aT_Y/magSrcT2aT
var/normSrcT2aL_X = srcT2aL_X/magSrcT2aL
var/normSrcT2aL_Y = srcT2aL_Y/magSrcT2aL
var/normSrcT2aR_X = srcT2aR_X/magSrcT2aR
var/normSrcT2aR_Y = srcT2aR_Y/magSrcT2aR
var/normAT2aL_X = aT2aL_X/magAT2aL
var/normAT2aL_Y = aT2aL_Y/magAT2aL
var/normAT2aR_X = aT2aR_X/magAT2aR
var/normAT2aR_Y = aT2aR_Y/magAT2aR
var/normAL2aR_X = aL2aR_X/magAL2aR
var/normAL2aR_Y = aL2aR_Y/magAL2aR
//srcT cross product vars
var/CP_srcT2aT2aL = (((normSrcT2aT_Y - normAT2aL_Y) - (normSrcT2aT_X - normAT2aL_X)) + ((normSrcT2aT_X*normAT2aL_Y) - (normSrcT2aT_Y*normAT2aL_X))) //(AyBz-AzBy)i -(AxBz-AzBx)j +(AxBy-AyBx)k //cross product with srcT to aT (using normalized vectors)
world<<"CP_srcT2aT2aL=[CP_srcT2aT2aL]"
var/CP_srcT2aT2aR = (((normSrcT2aT_Y - normAT2aR_Y) - (normSrcT2aT_X - normAT2aR_X)) + ((normSrcT2aT_X*normAT2aR_Y) - (normSrcT2aT_Y*normAT2aR_X)))
world<<"CP_srcT2aT2aR=[CP_srcT2aT2aR]"
var/CP_srcT2aL2aR = (((normSrcT2aT_Y - normAL2aR_Y) - (normSrcT2aT_X - normAL2aR_X)) + ((normSrcT2aT_X*normAL2aR_Y) - (normSrcT2aT_Y*normAL2aR_X)))
world<<"CP_srcT2aL2aR=[CP_srcT2aL2aR]"
//end srcT cross product vars
//end srcT vars
I've found that most explanations for the cross product available on the internet are fairly scant in terms of accurate depiction of its components. As for the same side method, I'm supposing that I have to check if each cross product has the same sign in order for the the collision to return true. I could be completely wrong on this though, as it's been hard to dig up solid information on the subject.
I can't seem to get the sign of the cross-products to be the same at the correct time, if I drop below A with src the cross products tend to go negative, if I go above they tend to go positive.
I've been trying to figure out a triangle collision detection system using only 3 vertices and avoiding the sum of angles method for a very long time now, and would really appreciate some help.
I'll upload the executable or email it on request.
It helps if you consider the points of the triangle around in a clockwise motion; so we take points T, R and L in that order in your scheme.
Call the point you want to test "P". We denote a vector from "T" to "P" as TP, etc.
We can calculate the components of TP thus:
TP.x = P.x - T.x
TP.y = P.y - T.y
To test if P is inside the triangle TRL, we calculate the cross product of the vector for each side with the vector from the triangle vertex to P.
To calculate the cross products:
cT = TRxTP
cR = RLxRP
cL = LTxLP
Since these vectors are planar (z=0), the x- and y- components of the cross product will be zero, and we need only calculate the z-component in each case. Also, there is no need to normalize the vectors:
For example:
cT = (R.x-T.x)*(P.y-T.y) - (R.y-T.y)*(P.x-T.x)
is the z-component of the first cross product.
Now, if cT and cR and cL are all positive, the point P is inside the triangle TRL. If any are negative, the point is outside the triangle. If zero, the point is inline with one of the sided.