PDA

View Full Version : Any mathmatical??



M109uk
07-05-2005, 01:47 AM
Hi all,

Im trying to subdivide a face depending on its smallest size,
for example i have a face along the X and Z axis with a Width of 10 and a Depth of 4, so this will then be divided in to 10 faces each 2x2...

I'v been trying to work this out for the past few days and is really starting to bake my head :?

Does any one have any suggestions how i can do this?
Thanx

M109uk
09-05-2005, 12:54 AM
I think i have managed to get it to do what i want, i havnt fully tested it yet, but i have got it working on 3 different sized faces and has worked well :)

If anyones intrested:

// TVertex3f = Array [0..2] Of Single;
// TVertices = Array [0..3] Of TVertex3f;


function FacePlane(const Face: TVertices): Integer;
var
i: Integer;
Min,Max: TVertex3f;
begin
Min := Face[0];
Max := Face[0];
For i := 1 To 3 Do
Begin
If Min[0] > Face[i,0] Then Min := Face[i,0];
If Min[1] > Face[i,1] Then Min := Face[i,1];
If Min[2] > Face[i,2] Then Min := Face[i,2];

If Max[0] < Face[i,0] Then Max := Face[i,0];
If Max[1] < Face[i,1] Then Max := Face[i,1];
If Max[2] < Face[i,2] Then Max := Face[i,2];
End;

If Min[0] = Max[0] Then Result := FACEAXIS_YZ Else
If Min[1] = Max[1] Then Result := FACEAXIS_XZ Else
Result := FACEAXIS_XY;
end;


function FaceSize(const Face: TVertices): TVertex3f;
var
i: Integer;
Min,Max: TVertex3f;
begin
Min := Face[0];
Max := Face[0];
For i := 1 To 3 Do
Begin
If Min[0] > Face[i,0] Then Min := Face[i,0];
If Min[1] > Face[i,1] Then Min := Face[i,1];
If Min[2] > Face[i,2] Then Min := Face[i,2];

If Max[0] < Face[i,0] Then Max := Face[i,0];
If Max[1] < Face[i,1] Then Max := Face[i,1];
If Max[2] < Face[i,2] Then Max := Face[i,2];
End;

If Min[0] = Max[0] Then Result := Vertex3f(0, Max[1]-Min[1], Max[2]-Min[2]) Else
If Min[1] = Max[1] Then Result := Vertex3f(Max[0]-Min[0], 0, Max[2]-Min[2]) Else
Result := Vertex3f(Max[0]-Min[0], Max[1]-Min[1], 0);
end;


function canTile(const TileSize,Width: Single; var Loops: Integer): Boolean;
var
i: Single;
begin
Result := False;
i := 0;
Loops := 0;
While i < Width Do
Begin
i := i+TileSize;
Inc(Loops);
End;
Result := (i = Width);
end;


// Min: This is the smallest tile size allowed (min * min)
// Max: This is the largest tile size allowed (max * max)
function GetTileSize(Face: TVertices; Min: Single = 0.1; Max: Single = 16): Single;
var
i,W,H,nW,nH: Single;
Loops: Integer;
begin
Case FacePlane(Face) Of
FACEAXIS_XY: Begin
W := FaceSize(Face)[0];
H := FaceSize(Face)[1];
End;
FACEAXIS_XZ: Begin
W := FaceSize(Face)[0];
H := FaceSize(Face)[2];
End;
FACEAXIS_YZ: Begin
W := FaceSize(Face)[2];
H := FaceSize(Face)[1];
End;
End;

If (H=W) And (H<Max) Then Result := H Else
Begin
If H = W Then
Begin
nW := W;
While Not canTile(nW, nH, Loops) Do nW := RoundTo(nW-0.1, -2);
If canTile(nW, nH, Loops) Then Result := nW;
End;
Exit;
End;

If nH < nW The
Begin
If nH < Min Then nH := Min;
If nH > Max Then nH := Max;
While (Not canTile(nH, nW, Loops)) Or (Not canTile(nH, H, Loops)) Do
nH := RoundTo(nH-0.1, -2);
If canTile(nH, nW, Loops) Then
Begin
Result := nH;
Exit;
End;
End Else
If nW < nH Then
Begin
If nW < Min Then nW := Min;
If nW > Max Then nW := Max;
While (Not canTile(nW, nH, Loops)) Or (Not canTile(nW, W, Loops)) Do
nW := RoundTo(nW-0.1, -2);
If canTile(nW, nH, Loops) Then
Begin
Result := nW;
Exit;
End;
End;
end;



procedure SubdivideFace(Face: TVertices);
var
hLoops,wLoops,X,Y: Integer;
TileSize: Single;
Pos: TVertex3f;
begin
TileSize := GetTileSize(Face, 0.1, 16);
canTile(TileSize, W, wLoops);
canTile(TileSize, H, hLoops);
Pos := Face[0]; // Sets the starting position of the new faces

For X := 0 To wLoops-1 Do
Begin
For Y := 0 To hLoops-1 Do
Begin
// Create a new face at Position 'Pos' with the size of 'TileSize'
Pos[1] := Pos[1]+TileSize;
End;
Pos[1] := Face[0,1];
Pos[0] := Pos[0]+TileSize;
End;
end;


The code isnt really clean yet, but if anyone has any suggestions on a better way please let me know :D

Thanks