# Slicing a body

This topic is 2779 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey, I'm using Farseer physics engine and would like to be able to slice a body into two pieces. What would be the best way of doing this in Silverlight? It's similar to the 'Cut the rope' game where you slice the rope and it cuts at that place. Any suggestions on what technique I should use? Thanks for any help

##### Share on other sites
i think you want to make two dffrent models from one model splitted by a plane

so there: from nvidia portal engine

procedure AddVertex(const x: t3dpoint; var res: TPolygon);
begin

// Append a vertex to a polygon.
if (res.Count = 0) or
(magnitude(vectors_substract_v1minusv2(x, res.V[res.Count-1])) > 0.01) then
begin
INC(res.Count);
res.V[res.Count-1] := x;
end;

end;

function ClipEdge(const v1, v2: t3dpoint; const plane: t3dpoint): t3dpoint;
var
v: t3dpoint;
t: Single;
begin

// Clip a line segment to a plane, return the new end point.
v := vectors_substract_v1minusv2(v2, v1);
// t := -sdotPlaneVecDist(plane, v1) / iloczynskalarny3d(plane, v);

end;

function dotVecScalarMult3(v: TDotVector3; s: Single): TDotVector3;
begin

Result.x := v.x * s;
Result.y := v.y * s;
Result.z := v.z * s;

end;

function ClipPoly(const poly: TPolygon; const plane: t3dpoint): TPolygon;
var
a, b: t3dpoint;
count, i: Integer;
da, db: Integer;
clipped: TPolygon;
begin

// Clip a polygon to a plane.
count := poly.Count;
clipped.Count := 0;

for i := 0 to count - 1 do
begin
a := poly.V;
b := poly.V[(i+1) mod count];

da := classifyapointagainstaplane(a,plane,getplaned(plane,a));
db := classifyapointagainstaplane(b,plane,getplaned(plane,b));

if da < 1 then
begin
if db = 1 then AddVertex(ClipEdge(a, b, plane), clipped);
end
else if db = -1 then
begin
end;
end;

Result := clipped;
result.normal := poly.normal;
end;

[/quote]

but in other words

const float SPECIAL_FEAUTRE = 0.00000001; //wtf ;u called epsilon

const int isOnPlane = 0;
const int isFront = 1;
const int isBack = -1;

int __fastcall classifyapointagainstaplane(t3dpoint point,t3dpoint normal,float distance)
{
float costam;
int result;
costam = dotproduct(point,normal)+distance;
if (costam > 0) result = isFront;
if (costam < 0) result = isBack;
if (betweenorequal(-SPECIAL_FEAUTRE,SPECIAL_FEAUTRE,costam) == true) result = isOnPlane;

return result;
}

[/quote]

so we have model- models have vertices the vertices represent polygons the polygons have sides

heres a function that i made years ago actually i didnt finish this function at all

void __fastcall TachoGLModel::SplitByPlane(int delete_side, t3dpoint split_normal, float split_distance,t3dpoint point_on_split_plane)
{
int i;
bool found=false;
int BASE_SIDE;
int j;
t3dpoint vline[2];

t3dpoint C[2];
int SPLIT_COUNT=0;
int cnt=0;
LIGHT_TRAIL NEW_FACE;

for (i = 0; i < VBO_BE.Length; i++) {
found = false;

for (j = VBO_BE.INDEX_START+1; j < VBO_BE.INDEX_START+VBO_BE.length; j++) {
BASE_SIDE = classifyapointagainstaplane(VBO_V[j-1],split_normal,split_distance);
if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != delete_side ) cnt = cnt + 1;

if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != BASE_SIDE) {
vline[0] = VBO_V[j-1];
vline[1] = VBO_V[j];
C[SPLIT_COUNT] = PUNKT_PRZECIECIA_ODCINEK_PLASZCZYZNA(split_normal,point_on_split_plane,vline);
SPLIT_COUNT = SPLIT_COUNT + 1;

}
}//eof for j

SPLIT_COUNT = 0;
NEW_FACE.set_length(cnt+2);
cnt = -1;

for (j = VBO_BE.INDEX_START+1; j < VBO_BE.INDEX_START+VBO_BE.length; j++) {
BASE_SIDE = classifyapointagainstaplane(VBO_V[j-1],split_normal,split_distance);
if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != delete_side ) { cnt = cnt + 1; NEW_FACE[cnt] = VBO_V[j]; }

if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != BASE_SIDE) {

cnt = cnt + 1; NEW_FACE[cnt] = C[SPLIT_COUNT];

SPLIT_COUNT = SPLIT_COUNT + 1;

}
}//eof for j

Replace_Face(NEW_FACE,i);
//REPLACE FACE

//nie dokonczone

}

}

[/quote]

and again in other words:

go through all faces (polygons ) in a mesh:

test where they are ( front or back of split plane)

if tehe is at least one vertex that is different from BASE_SIDE (note that base side is a side for first vertex in face)

we must split this face

now compare

two sides from wrong vertex:

ONE_SIDE = vectorAB( VERTS[ WRONG_INDEX], VERTS[WRONG_INDEX + 1]);

SECOND_SIDE = vectorAB( VERTS[ WRONG_INDEX], VERTS[WRONG_INDEX - 1]);

if WRONG_INDEX is 0 then wrong_index - 1 equals to tle last face vert

if wrong_index is the last face vert then wrong__index +1 is the first face index = 0

then you calculate point of intersection between line and plane:

there are many wasy to do iit and i dont have the simpliest code for doing that but i dont care

t3dpoint __fastcall PUNKT_PRZECIECIA_ODCINEK_PLASZCZYZNA(t3dpoint vNormal,t3dpoint pointonplane,
t3dpoint vLine[2])
{
const Extended MATCH_FACTOR = 0.9999999999;

t3dpoint vIntersection;// : t3dpoint;
Extended originDistance;
Extended distance1;
Extended distance2;
double m_magnitude;// : Double;
t3dpoint vPoint;// : t3dpoint;
t3dpoint vLineDir;// : t3dpoint;
Extended Numerator;// : Extended;
Extended Denominator;// : Extended;
Extended dist;// : Extended;
Extended Angle,tempangle;// : Extended;
t3dpoint vA, vB;// : t3dpoint;
int I;
Extended dotProduct;// : Extended;
Extended vectorsMagnitude;// : Extended;

t3dpoint result;

originDistance = 0;
distance1 = 0;
distance2 = 0;
vPoint.x = 0;
vPoint.y = 0;
vPoint.z = 0;

vLineDir.x = 0;
vLineDir.y = 0;
vLineDir.z = 0;

Numerator = 0.0;
Denominator = 0.0;
dist = 0.0;
Angle = 0.0;

originDistance = -1 * ((vNormal.x * pointonplane.x) +
(vNormal.y * pointonplane.y) +
(vNormal.z * pointonplane.z));

distance1 = ((vNormal.x * vLine[0].x) +
(vNormal.y * vLine[0].y) +
(vNormal.z * vLine[0].z)) + originDistance;

distance2 = ((vNormal.x * vLine[1].x) +
(vNormal.y * vLine[1].y) +
(vNormal.z * vLine[1].z)) + originDistance;

if(distance1 * distance2 >= 0) {
t3dpoint r; //linia nie przebija plaszczyzny
r.x = 1.0f; r.y = 1.0f; r.z = 1.0f;
return r;
}

vLineDir.x = vLine[1].x - vLine[0].x;
vLineDir.y = vLine[1].y - vLine[0].y;
vLineDir.z = vLine[1].z - vLine[0].z;

m_magnitude = sqrt((vLineDir.x * vLineDir.x) +
(vLineDir.y * vLineDir.y) +
(vLineDir.z * vLineDir.z) );

if (m_magnitude == 0.0) m_magnitude = 1.0f;

vLineDir.x = vLineDir.x/m_magnitude;
vLineDir.y = vLineDir.y/m_magnitude;
vLineDir.z = vLineDir.z/m_magnitude;

Numerator = -1 * (vNormal.x * vLine[0].x +
vNormal.y * vLine[0].y +
vNormal.z * vLine[0].z + originDistance);

Denominator = ( (vNormal.x * vLineDir.x) + (vNormal.y * vLineDir.y) + (vNormal.z * vLineDir.z) );

if( Denominator == 0.0) {

vIntersection = vLine[0];
return vIntersection;
} else {

dist = Numerator / Denominator;

vPoint.x = (vLine[0].x + (vLineDir.x * dist));
vPoint.y = (vLine[0].y + (vLineDir.y * dist));
vPoint.z = (vLine[0].z + (vLineDir.z * dist));

result.x = vPoint.x; // Return the intersection point
result.y = vPoint.y;
result.z = vPoint.z;

}

return result;

}

[/quote]

after calc this point you should create a new face .....

hope ihelped lol

##### Share on other sites
Thanks. I understand some of it, and have managed to get intersection points. The hard part is using this in Silverlight as I can't seem to render the fixture to a UIElement. Btw, this is 2D.

##### Share on other sites
for me its harder to explain this in 2d because of equation y=ax+b when whe have prependicular line to OX line ( there is one X and infinite Y )

for those equation lets try and use vertex.z = 0 then for any normal or vertex or plane equation

##### Share on other sites
I've managed to get Farseer to take care of most of the intersection points and such. But the resulting vertices of each new body has to someone be displayed as an UIElement. This is what's now tripping me up

##### Share on other sites
sorry cant help you at this stage i dont know ms silversight (but i have installed it lol) and farser

##### Share on other sites
lol don't think I haven't tried! Trying to find how to create a UIElement for a given fixture and attach it.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5
khawk
11

• 9
• 9
• 11
• 11
• 23
• ### Forum Statistics

• Total Topics
633677
• Total Posts
3013281
×