domingo, 6 de abril de 2008

TAREA No4

TAREA:4
6-ABRIL-2008
Algoritmo de Cyrus-Beck
CÓDIGO:
internal sealed class CyrusBeckClipping : IClippingAlgorithm {
private List _clipArea = new List();
private List _normals = new List();

public IEnumerable GetBoundingPolygon() {
return _clipArea;
}

public void SetBoundingRectangle(Vector2 start, Vector2 end) {
_clipArea.Clear();

_clipArea.Add(start);
_clipArea.Add(new Vector2(end.X, start.Y));
_clipArea.Add(end);
_clipArea.Add(new Vector2(start.X, end.Y));

computeNormals();
}

public void SetBoundingPolygon(IEnumerable points) {
_clipArea.Clear();
_clipArea.AddRange(points);
computeNormals();
}

private void computeNormals() {
_normals.Clear();

for (int i = 0; i < _clipArea.Count - 1; i++) {
Vector2 direction = _clipArea[i + 1] - _clipArea[i];
direction.Normalize();

_normals.Add(new Vector2(-direction.Y, direction.X));
}

{
Vector2 direction = _clipArea[0] - _clipArea[_clipArea.Count - 1];
direction.Normalize();

_normals.Add(new Vector2(-direction.Y, direction.X));
}
}

public bool ClipLine(ref Line line) {
Vector2 P = line.End - line.Start;
float tMinimum = 0, tMaximum = 1;
const float epsilon = 0.0001f;

for (int i = 0; i < _clipArea.Count; i++) {
Vector2 F = _clipArea[i];
Vector2 N = _normals[i];
Vector2 Q = line.Start - F;

float Pn = Vector2.DotProduct(P, N);
float Qn = Vector2.DotProduct(Q, N);

if (Pn <> -epsilon) {
if (Qn < 0) return false;
}
else {
float computedT = -Qn / Pn;
if (Pn < 0) {
if (computedT < tMinimum)
return false;
if (computedT < tMaximum)
tMaximum = computedT;
}
else {
if (computedT > tMaximum)
return false;
if (computedT > tMinimum)
tMinimum = computedT;
}
}
}

if (tMinimum < tMaximum) {
if (tMaximum < 1)
line.End = line.Start + tMaximum * P;

if (tMinimum > 0)
line.Start = line.Start + tMinimum * P;
}
else return false;

return true;
}

public ClippingCapabilities Capabilities {
get {
return ClippingCapabilities.ConvexWindow
ClippingCapabilities.RectangleWindow;
}
}

public override string ToString() {
return "Cyrus-Beck algorithm";
}
}
// This code was implemented by Grishul Eugeny as part of preparation
// to exam in ITMO university
El algoritmo de Cyrus-Beck es un algoritmo de recorte entre líneas y polígonos convexos. De forma similar al también utiliza aristas extendidas. Se puede adaptar muy fácilmente entre rayos y polígonos convexos o segmentos y polígonos convexos.

No hay comentarios: