2010-05-24 30 views
10

Necesito dibujar un arco usando GraphicsPath y tener puntos inicial, mediano y final. El arco debe pasar sobre ellos.C# Drawing Arc con 3 puntos

Probé .DrawCurve y .DrawBezier pero el resultado no es exactamente un arco.

¿Qué puedo hacer?

SOLUCIÓN:

Después de un par de horas de escritura de código logré dibujar lo que quería con este algoritmo (dar 3 puntos a, b, c y un camino GraphicsPath):

double d = 2 * (a.X - c.X) * (c.Y - b.Y) + 2 * (b.X - c.X) * (a.Y - c.Y); 
double m1 = (Math.Pow(a.X, 2) - Math.Pow(c.X, 2) + Math.Pow(a.Y, 2) - Math.Pow(c.Y, 2)); 
double m2 = (Math.Pow(c.X, 2) - Math.Pow(b.X, 2) + Math.Pow(c.Y, 2) - Math.Pow(b.Y, 2)); 
double nx = m1 * (c.Y - b.Y) + m2 * (c.Y - a.Y); 
double ny = m1 * (b.X - c.X) + m2 * (a.X - c.X); 
double cx = nx/d; 
double cy = ny/d; 
double dx = cx - a.X; 
double dy = cy - a.Y; 
double distance = Math.Sqrt(dx * dx + dy * dy); 
Vector va = new Vector(a.X - cx, a.Y - cy); 
Vector vb = new Vector(b.X - cx, b.Y - cy); 
Vector vc = new Vector(c.X - cx, c.Y - cy); 
Vector xaxis = new Vector(1, 0); 
float startAngle = (float)Vector.AngleBetween(xaxis, va); 
float sweepAngle = (float)(Vector.AngleBetween(va, vb) + Vector.AngleBetween(vb, vc)); 
path.AddArc(
    (float)(cx - distance), (float)(cy - distance), 
    (float)(distance * 2), (float)(distance * 2), 
    startAngle, sweepAngle); 
+1

¿te refieres a un arco circular, o harás cualquier arco? –

+0

circular, me olvidé de agregar que – Keeper

Respuesta

6

me gustaría utilizar DrawArc() según lo sugerido por ANC_Michael. Para encontrar un arco que pase por 3 puntos, debe calcular el circumcircle del triángulo formado por los puntos.

Una vez que tenga circuncircle, calcule un cuadro delimitador para el círculo a usar con DrawArc usando las dimensiones mínima/máxima (centro +/- radio). Ahora calcule sus ángulos de inicio y finalización traduciendo los puntos para que el circunferencia circunscrita al origen (traduzca por -circumcenter) y tome el producto de puntos de los vectores inicial y final normalizados con el eje X:

double startAngle = Math.Acos(VectorToLeftPoint.Dot(XAxis)); 
double stopAngle = Math.Acos(VectorToRightPoint.Dot(XAxis)); 

Tenga en cuenta que DrawArc espera ángulos en el sentido de las agujas del reloj desde el eje X, por lo que debe agregar Math.PI si el vector calculado está por encima del eje x. Eso debería ser suficiente información para llamar al DrawArc().

Editar: Este método encontrará un circular arco y no necesariamente el arco 'mejor ajuste' dependiendo de su comportamiento de punto final esperado.

0

¿Has probado el método DrawArc y ver si puedes manipular tus 3 puntos de alguna manera?

quizá

Pen blackPen= new Pen(Color.Black, 3); 
// Create rectangle to bound ellipse. 
Rectangle rect = new Rectangle(initial x, initial y, final x, median y); 
// Create start and sweep angles on ellipse. 
float startAngle = 0F; 
float sweepAngle = 270.0F; 
// Draw arc to screen. 
e.Graphics.DrawArc(blackPen, rect, startAngle, sweepAngle); 

http://msdn.microsoft.com/en-us/library/system.drawing.graphics.drawarc%28VS.71%29.aspx

+0

no tengo los ángulos y no sé cómo calcularlos y los puntos pueden estar en cualquier lugar (se exportan de AutoMap 3D en FDO dentro de Oracle) – Keeper