[RESOLU] CGPoint d'un UIBezierPath stockés dans un tableau puis utilisé pour le path

busterTheobusterTheo Membre
décembre 2017 modifié dans Xcode et Developer Tools #1

Bonjour,


ce code fonctionne parfaitement :



bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 39.59, y: 1.55))
bezierPath.addCurve(to: CGPoint(x: 56.15, y: 5.39), controlPoint1: CGPoint(x: 46.04, y: 1.48), controlPoint2: CGPoint(x: 51.15, y: 3.68))
bezierPath.addCurve(to: CGPoint(x: 84.45, y: 43.55), controlPoint1: CGPoint(x: 77.02, y: 12.5), controlPoint2: CGPoint(x: 78.52, y: 21.96))
bezierPath.addCurve(to: CGPoint(x: 88.06, y: 62.63), controlPoint1: CGPoint(x: 86.08, y: 49.5), controlPoint2: CGPoint(x: 89.01, y: 53.58))
bezierPath.addCurve(to: CGPoint(x: 76.55, y: 119.65), controlPoint1: CGPoint(x: 86.05, y: 81.99), controlPoint2: CGPoint(x: 93.68, y: 115.36))
bezierPath.addCurve(to: CGPoint(x: 60.43, y: 119.65), controlPoint1: CGPoint(x: 71.18, y: 119.65), controlPoint2: CGPoint(x: 61.91, y: 119.48))
bezierPath.addCurve(to: CGPoint(x: 4.61, y: 108.25), controlPoint1: CGPoint(x: 45.33, y: 121.44), controlPoint2: CGPoint(x: 11.81, y: 121.36))
bezierPath.addCurve(to: CGPoint(x: 0.88, y: 63.51), controlPoint1: CGPoint(x: -1.16, y: 97.76), controlPoint2: CGPoint(x: -0.91, y: 78.34))
bezierPath.addCurve(to: CGPoint(x: 3.29, y: 32.91), controlPoint1: CGPoint(x: 2.13, y: 53.17), controlPoint2: CGPoint(x: 1.08, y: 42.19))
bezierPath.addCurve(to: CGPoint(x: 39.59, y: 1.55), controlPoint1: CGPoint(x: 7.69, y: 14.51), controlPoint2: CGPoint(x: 20.66, y: 5.85))
bezierPath.close()

Et celui-là , non :



var ancre = [(x: CGFloat, y: CGFloat)]()


ancre = [(39.59, 1.55), (56.15, 5.39), (46.04, 1.48), (51.15, 3.68), (84.45, 43.55), (77.02, 12.5), (78.52, 21.96), (88.06, 62.63), (86.08, 49.5), (89.01, 53.58), (76.55, 119.65), (86.05, 81.99), (93.68, 115.36), (60.43, 119.65), (71.18, 119.65), (61.91, 119.48), (4.61, 108.25), (45.33, 121.44), (11.81, 121.36), (0.88, 63.51), (-1.16, 97.76), (-0.91, 78.34), (3.29, 32.91), (2.13, 53.17), (1.08, 42.19), (39.59, 1.55), (7.69, 14.51), (20.66, 5.85)]


bezierPath = UIBezierPath()

bezierPath.move(to: CGPoint(x: ancre[0].x, y: ancre[0].y))

for var i in stride(from: 1, through: ancre.count - 1, by: 3) {
print("i = \(i) , Point : \(ancre[i].x) - \(ancre[i].y) , CP1 : \(ancre[i+1].x) - \(ancre[i+1].y) , CP2 : \(ancre[i+2].x) - \(ancre[i+2].y)")
bezierPath.addCurve(to: CGPoint(x: ancre[i].x, y: ancre[i].y), controlPoint1: CGPoint(x: ancre[i+1].x, y: ancre[i+1].y), controlPoint2: CGPoint(x: ancre[i+2].x, y: ancre[i+2].x))
}

bezierPath.close()

Et voila le résultats des prints :



 


count : 28


i = 1 , Point : 56.15 - 5.39 , CP1 : 46.04 - 1.48 , CP2 : 51.15 - 3.68


i = 4 , Point : 84.45 - 43.55 , CP1 : 77.02 - 12.5 , CP2 : 78.52 - 21.96


i = 7 , Point : 88.06 - 62.63 , CP1 : 86.08 - 49.5 , CP2 : 89.01 - 53.58


i = 10 , Point : 76.55 - 119.65 , CP1 : 86.05 - 81.99 , CP2 : 93.68 - 115.36


i = 13 , Point : 60.43 - 119.65 , CP1 : 71.18 - 119.65 , CP2 : 61.91 - 119.48


i = 16 , Point : 4.61 - 108.25 , CP1 : 45.33 - 121.44 , CP2 : 11.81 - 121.36


i = 19 , Point : 0.88 - 63.51 , CP1 : -1.16 - 97.76 , CP2 : -0.91 - 78.34


i = 22 , Point : 3.29 - 32.91 , CP1 : 2.13 - 53.17 , CP2 : 1.08 - 42.19


i = 25 , Point : 39.59 - 1.55 , CP1 : 7.69 - 14.51 , CP2 : 20.66 - 5.85



 


Là , je suis bluffé, tout a l'air ok, mais le path affiché est n'importe quoi, pourtant tous les points semblent correspondre.


 


J'ai même essayé en remplaçant chaque ligne progressivement :



bezierPath.move(to: CGPoint(x: ancre[0].x, y: ancre[0].y))

Puis :



bezierPath.addCurve(to: CGPoint(x: ancre[1].x, y: ancre[1].y), controlPoint1: CGPoint(x: ancre[2].x, y: ancre[2].y), controlPoint2: CGPoint(x: ancre[3].x, y: ancre[3].y))

Et ainsi de suite, mais je préfèrerai faire ça avec une boucle...


 


Merci d'avance.


Réponses

  • LarmeLarme Membre
    décembre 2017 modifié #2

    controlPoint2: CGPoint(x: ancre[i+2].x, y: ancre[i+2].x)


    =>


    controlPoint2: CGPoint(x: ancre[i+2].x, y: ancre[i+2].y)


    ?


  • :o  Merci, mais je dois être bigleux, je comprend pas


  • ah, vu merci, quel oe“il


  • J'ai édité et mis en gras + rouge la différence.


  • j'ai honte


  • busterTheobusterTheo Membre
    décembre 2017 modifié #7

    Bon ben désolé pour le dérangement.


    Je ne sais pas pourquoi, mais je me suis bloqué sur l'idée débile que on ne pouvait faire cela avec un array. ça sent un peu le dépit.. Encore merci


  • LarmeLarme Membre
    décembre 2017 modifié #8

    Je ne suis pas fan des tuples, mais voici comme j'aurais fait:

     



    for var i in stride(from: 1, through: ancre.count - 1, by: 3) {
       let point = CGPoint(x: ancre[i].x, y: ancre[i].y)
       let controlPoint1 = CGPoint(x: ancre[i+1].x, y: ancre[i+1].y)
       let controlPoint2 = CGPoint(x: ancre[i+2].x, y: ancre[i+2].y)
      print("i = \(i), Point: \(NSStringFromCGPoint(point)) CP1: \(NSStringFromCGPoint(controlPoint1)) CP2: \(NSStringFromCGPoint(controlPoint2))")
      //ou à  la limite en reprenant ton code:
        //print("i = \(i) , Point : \(point.x) - \(point.y) , CP1 : \(controlPoint1.x) - \(controlPoint1.y) , CP2 : \(controlPoint2.x) - \(controlPoint2.y)")
        bezierPath.addCurve(to: point, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
    }

    J'assigne mes variables, je regarde leurs valeurs, et j'en déduis si j'ai une erreur que c'est la construction d'un point qui foire ou non.


    Parce que ce que tu printais et faisais n'étais pas la même chose. Alors certes, dans mon cas avec NSStringFromCGPoint(), je peux mettre la mauvaise variable, mais j'ai "moins" de choses à  vérifier, car j'ai changé le nombre de vérifications en plusieurs étapes et moins d'élements par étapes :


    - Le CGPoint est-il bon.


    - Le CGPoint est-il utilisé au bon endroit.


  • Ben pour me faire pardonner, pour ceux qui cherchent des trucs là -dessus, voici le lien où se trouve le code qui me permet de récupérer les actions du path. Bravo à  lui.


     


    Du genre :



    case .addCurveToPoint:
    arrayPoints.append(element.points[0])
    arrayPoints.append(element.points[1])
    arrayPoints.append(element.points[2])

    Mais surtout la première partie où je ne comprend strictement rien.



    func forEach( body: @convention(block) (CGPathElement) -> Void) {
    typealias Body = @convention(block) (CGPathElement) -> Void

    ETC
  • CéroceCéroce Membre, Modérateur


    ah, vu merci, quel oe“il




    C'est une déduction. Si le print est correct, alors c'est le passage des paramètres qui est foireux.


  •  


     


    Je ne suis pas fan des tuples, mais voici comme j'aurais fait:

    Merci pour ce judicieux conseil.




  •  


    Ben pour me faire pardonner, pour ceux qui cherchent des trucs là -dessus, voici le lien où se trouve le code qui me permet de récupérer les actions du path. Bravo à  lui.


     


    Du genre :



    case .addCurveToPoint:
    arrayPoints.append(element.points[0])
    arrayPoints.append(element.points[1])
    arrayPoints.append(element.points[2])

    Mais surtout la première partie où je ne comprend strictement rien.



    func forEach( body: @convention(block) (CGPathElement) -> Void) {
    typealias Body = @convention(block) (CGPathElement) -> Void

    ETC




    C'est la traduction Swift de https://stackoverflow.com/questions/3051760/how-to-get-a-list-of-points-from-a-uibezierpath

    En bref, il s'agit d'itérer sur les points d'un Path. 


    Ce n'est pas aussi évident que cela au premier abord, car ce n'est pas un simple array de points, mais tu peux avoir des paramètres comme tu le vois en faisant une courbe qu'il y a besoin de points supplémentaires.


    Le code Objective-C est plus "simple" à  comprendre, la version en Swift est plus Swifty et semble faire plus de choses "toute seule".

  • Ah ok, merci.


  • Hey, comment ça se fait que ça reconnait :



    case .addCurveToPoint:

    alors que j'ai :



    bezierPath.addCurve(to: CGPoint(x: 0.88, y: 63.51), controlPoint1: CGPoint(x: -1.16, y: 97.76), controlPoint2: CGPoint(x: -0.91, y: 78.34))

    par exemple....


     


     


    En gros ça lit "addCurveToPoint" quand il y a "addCurve".


    Bizarre


  • CéroceCéroce Membre, Modérateur

    Si tu regardes bien le code, .addCurveToPoint est un case de l'enum CGPathElementType.


    D'un point de vue implémentation, il y a donc peu de rapport avec la méthode UIBezierPath.addCurve(to:controlPoint1:controlPoint2).


Connectez-vous ou Inscrivez-vous pour répondre.