2009-05-08 22 views
18

He realizado una ruta de curva cuádruple usando el método CGPathAddQuadCurveToPoint. Tengo el camino perfecto. Pero, quiero saber todos los puntos de coordenadas que participan en la ruta.Cómo puedo obtener todos los puntos en la curva CGPath o la curva cuádruple

¿Hay alguna manera de recuperar todos los puntos de coordenadas en una ruta?

Si no tiene otra solución para recuperar matemáticamente todos los puntos de una curva.

Gracias de antemano, Vamshi

+0

Aquí ... http://stackoverflow.com/questions/4854035/how-do-i-detect-a-touch-on-a-uibezierpath-and-move-a-ball-along-that/ 4855932 # 4855932 – Fattie

Respuesta

0

Una curva cuadrática es sólo eso - una curva. Es imposible obtener una lista de todos puntos porque hay infinitos puntos y no es un segmento de línea simple.

Consulte Getting Information about Quartz Paths para obtener una lista de las funciones que puede utilizar para consultar un objeto CGPath. Desafortunadamente, parece que la información más útil que obtendrás es con CGPathContainsPoint(), que solo te dice si un punto dado está contenido dentro del área de la ruta.

+0

Gracias por la respuesta .. He usado CGPathContainsPoint(). Para usar este método, definitivamente necesitamos que nuestro camino esté cerrado. Pero, en mi caso, si cierro el camino, no obtendré el camino esperado. Si queremos encontrar todos los puntos entre dos puntos (se convierte en una línea recta), entonces hay una solución usando las ecuaciones matemáticas. ¿Hay alguna solución para las curvas usando ecuaciones matemáticas o cualquier algoritmo –

1

Si desea trabajar en los elementos moveto, lineto y curveto de la ruta, use CGPathApply. Le pasa un puntero a una función en su programa y llama a esa función una vez por elemento de la ruta.

Desafortunadamente, no hay forma de pedir simplemente cada elemento como el que hay con AppKit's NSBezierPath. La función es la única forma.

Si desea determinar cada píxel intersectado por la ruta, lástima, eso no es práctico, y ni siquiera puedo pensar por qué querría esa información. Algunos contextos, como PDF contexts, ni siquiera tienen píxeles; en esos casos, cualquier pregunta que implique píxeles es un non sequitur.

0

Si no tiene alguna otra solución para recuperar matemáticamente todos los puntos de una curva.

¿Para qué los necesita, es decir, qué problema está tratando de resolver? Si se trata de intersecar dos curvas, puedes hacer esto matemáticamente. Simplemente establece las dos ecuaciones de curva iguales entre sí y resuelve lo desconocido.

+0

Gracias por la respuesta .. Tengo un problema en el que quiero mover un objeto (por ejemplo, persona) en la ruta. Puedo usar CAKeyFrameAnimation para resolver mi problema donde necesita la duración. Pero, no tengo duración en mi caso. Mientras el objeto se está moviendo, tengo que hacer otras operaciones sobre objetos como saltar o retroceder, etc. Por lo tanto, si conozco todos los puntos en el camino, puedo hacer que se mueva sobre los puntos que satisfarán mis requerimientos. –

+0

No entiendo el problema por completo, pero quizás hacer su ruta basada en el tiempo lo ayude a resolver esto. Es decir, en t = 0, la ecuación de ruta pone el objeto en (x0, y0). En t = 1, la ruta pone el objeto en (x1, y1). Etcétera. Entonces, no necesita recordar todos los puntos, sino simplemente calcular el (xi, yi) para el punto de tiempo t = i. –

0

Supongo que está buscando algo equivalente a la clase Java2D FlatteningPathIterator. Por ejemplo, el path.getPathIterator(null, 1.0) de Java2D devuelve un iterador de solo segmentos 'lineTo' incluso si la ruta original tenía curveTo y quadTo, el argumento doble controla la 'flatness', lo que le proporciona una manera fácil de calcular cualquier punto de la curva. Estoy buscando lo mismo en Cocoa, pero no he encontrado nada. Si encuentras una solución, házmelo saber. Existen implementaciones de curvas alrededor (por ejemplo, http://sourceforge.net/projects/curves/) que pueden trasladarse, pero siempre existe el riesgo de que si no utiliza el mismo algoritmo que Cocoa, puede haber errores entre su interpolación y el acariciado NSBezierPath/CGPath.

14

Puede hacerlo utilizando la rutina de la biblioteca wykobi C++ para las curvas de bezier cúbicas. La biblioteca de Wykobi también admite curvas cuadradas de Bezier.

Por supuesto, como alguien señaló que no desea todos los puntos (aunque no es imposible, solo llevaría un tiempo infinito :).Wykobi hace que sea fácil obtener un cierto número de puntos: si su inicio, c1, c2 y puntos finales (donde c1, c2 son los puntos de control) son exactamente los mismos que los dados a CGContextAddCurveToPoint, entonces los puntos quedarán perfectamente en la línea dibujada por gráficos centrales, para que pueda hacer cosas como dibujar un patrón en varios puntos de la ruta.

Ver: http://www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi

Además, después de que empecé a usar wykobi He oído que hay un parecido tal vez incluso mejor biblioteca, que forma parte de Boost, pero no han comprobado todavía.

Creé un C++ Class WPoint como un puente entre los puntos de wykobi y los CGPoints (¡C++ divertido!). Aquí hay algo de código (sin WPoint, pero se puede imaginar que es exactamente el mismo diseño que un CGPoint así que si lo hace el reparto derecha se puede convertir fácilmente

 NSMutableArray* result = [[NSMutableArray alloc] init]; 
     wykobi::cubic_bezier<CGFloat,2> bezier; 
     bezier[0] = (WPoint)p1; // start point, in CG we did a CGMoveToPoint 
     bezier[1] = (WPoint)b1i; // control 1 
     bezier[2] = (WPoint)b2i; // control 2 
     bezier[3] = (WPoint)p2; // end point 

     std::vector<WPoint> point_list; 
     int numPoints = p2.dist(p3) * pointDensity; 
     // *** here's the magic *** 
     wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints); 

     for (int i=0; i<numPoints; i++) { 
      CGPoint p = (CGPoint)(point_list[i]); 
      [result addObject:[NSValue valueWithCGPoint:p]]; 
     } 

// result has your points! 

Aquí hay un enlace a la biblioteca de geometría Boost:. http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html

2

uso CGContextSetLineDash

El propósito de esta función es crear una línea de puntos, pero se puede utilizar para obtener segmentos más pequeños. punto de partida de cada segmento puede ser tratado como puntos.

CGSize bbSize = CGPathGetBoundingBox(path).size; 
UIGraphicsBeginImageContext(bbSize); 
CGContextRef ctx = UIGraphicsGetCurrentContext(); 
CGContextSetLineWidth(ctx, 1.0); 
CGContextAddPath(ctx, path); 
CGContextSetLineDash(ctx, phase, lengths, count); 
CGContextReplacePathWithStrokedPath(ctx); 
result = CGContextCopyPath(ctx); 
UIGraphicsEndImageContext(); 
+0

Esto me ayudó. También necesitaba usar CGApplyPath para sacar los puntos de los elementos ... Todavía tengo que afinar algo, pero esto funciona bastante bien. Al sintonizar quiero probar diferentes configuraciones del parámetro 'lengths'. – Jonny

+1

¿Por qué no utilizar 'CGPathCreateCopyByDashingPath'? – Ilya

Cuestiones relacionadas