2017-10-18 3 views
1

Ce que je suis en train de faire:mise à l'échelle uniforme sur la matrice de points autour du point C++ moyenne

1. échelle uniformément un tableau de points autour d'un point. 2. Un point doit être un point moyen de tableau de points.

Le code ci-dessous, semble fonctionner, mais je ne sais pas si c'est la bonne façon de le faire.

Je sais que la mise à l'échelle uniforme consiste simplement à multiplier les points par une certaine valeur, mais c'est une mise à l'échelle sur un point 0,0,0, comment le faire autour du point moyen?

Le code peut être subdivisé par étapes suivantes:

  1. Obtenez le point moyen du tableau de points, en additionnant toutes les positions et en divisant par un certain nombre de points.
  2. Le ratio est la valeur d'échelle
  3. Ensuite, je soustractive le vecteur pour obtenir un vecteur pointant du point au point moyen.
  4. Je normalise que le vecteur (je reçois vecteur unité)
  5. Puis-je ajouter que vecteur normalisé au point courant multiplié par (1 - rapport) * 0,5

Ce dernier bit 5ème point a été totalement de la vérification totale longueur de la valeur. Tous les exemples que j'ai donnés auparavant utilisaient des matrices en mathématiques, et je ne pouvais vraiment pas lire les opérations matricielles.

Est-ce la méthode d'échelle uniforme correcte, si ce n'est pas vous pourriez signaler ce que je fais mal?

//Get center of a curve 
    //That is average of all points 


    MatMxN curveCenter = MatMxN::Zero(2, 1); //This is just 1 vector/point with x and y coordinates 

    for (int i = 0; i < n; i++) 
     curveCenter += points.col(i); 

    curveCenter /= n; 

    //Scaling value 
    float ratio = 1.3; 

    //Get vector pointing to center and move by ratio 
    for (int i = 0; i < n; i++) { 
     MatMxN vector = curveCenter - points.col(i); 
     MatMxN unit = vector.normalized(); 
     points.col(i) += unit*(1 - ratio)*0.5; //points.col(i) this is point in array 
    } 
+0

La mise à l'échelle uniforme d'un point dans l'espace est une transformation semi-linéaire. Il suffit de multiplier tout le composant du point dans l'espace pour le même facteur d'échelle. Si vous voulez aussi centrer l'origine du cadre de référence au centre de masse du nuage de points, vous calculez la moyenne le long des coordonnées. Il est semi-linéaire car après avoir mis à l'échelle la métrique (module par exemple) sur le vecteur est modifiée (par le facteur d'échelle): 'points.col (i) * = ratio' est tout ce dont vous avez besoin. –

+1

Je pense que vous devez définir quel point sera le centre de la mise à l'échelle. Centre de la boîte englobante? Le centre de masse? En bas à gauche du cadre de délimitation? Un des points? – Galik

+0

Votre description n'est pas claire, donc personne n'a d'aide pour travailler si votre approche atteint. Point 2: quel ratio? Qu'avez-vous l'intention de mettre à l'échelle? Point 3: quels vecteurs soustrayez-vous? Que voulez-vous dire par "longueur totale de la valeur"? D'une manière générale, une mise à l'échelle uniforme nécessite de sélectionner un centre quelconque et d'ajuster d'autres points par rapport à celui-ci. Votre description ne transmet rien de pareil pour moi. – Peter

Répondre

2

Pour échelle de points à l'aide d'un point central spécifique (autre que), procédez comme suit:

  1. centre Soustraire du point MatMxN vector = points.col(i) - curveCenter;
  2. Multiplier vecteur par mise à l'échelle facteur vector *= ratio
  3. Ajouter un centre au vecteur mis à l'échelle pour obtenir un nouveau point points.col(i) = vector + curveCenter

Cette approche peut être résolue en quelque chose de similaire à votre formule. Appelons le centre C, le point à mettre à l'échelle P0, le point mis à l'échelle P1 et le facteur d'échelle s.Les 3 étapes ci-dessus peuvent être écrites comme:

v0 = P0 - C 
v1 = s * v0 
P1 = v1 + C 

=>

P1 = s * P0 + C * (1 - s) 

Maintenant, nous définissons P1 = P0 + x pour certains x:

P0 + x = s * P0 + C * (1 - s) 

=>

x = s * P0 + C * (1 - s) - P0 
    = C * (1 - s) - P0 * (1 - s) 
    = (C - P0) * (1 - s) 

Alors tu pdate pourrait être écrit comme suit au lieu d'utiliser les 3 étapes mentionnées:

MatMxN vector = curveCenter - points.col(i); 
points.col(i) += vector * (1 - ratio); 

Cependant, je préfère écrire les soustractions en sens inverse, car il est plus proche des étapes originales et plus facile à comprendre par intuition:

MatMxN vector = points.col(i) - curveCenter; 
points.col(i) += vector * (ratio - 1); 

Je ne sais pas où vous avez trouvé les idées normaliser et *0.5.