13 Replies Latest reply: Jan 26, 2014 8:45 AM by W_J_T RSS

    Math.cos Math.sin = Math.HELP

    W_J_T Community Member

      Hello Everyone,

       

      I was hoping to create a JS script to move objects away from common center based upon their current position. I was thinking to use a single selected path item as the center based on its position x/y and width/height. Using this reference point the script would then move away all other path items from this center point based on a desired amount and with uniform increments given their current location from this center. I was thinking cos and sin would be my friend in this case, however they seem to have become my foe instead. ;-)

       

      Does this sound doable? What am I missing, doing wrong, misinterpreting? Below is a non-working attempt, I can't seem to sort things out, perhaps I was close and missed it or maybe I am super way off and its more complex than I thought. However at this point I am confused across my various failed attempts this only being one of them.

       

      Thanks in advance for any assistance and sanity anyone can provide.

       

       

      // Example failed code, nonworking concept
      var docID = app.activeDocument;
      var s0 = docID.selection[0];
      pID = docID.pathItems;
      var xn, yn;
      var stepNum = 20;
      for (var i = 0; i < pID.length; i++) {
          var p = pID[i];
          var dx = ((s0.position[0] + s0.width) / 2 - (p.position[0] + p.width) / 2);
          var dy = ((s0.position[1] + s0.height) / 2 - (p.position[1] + p.height) / 2);
          xn = Math.cos(Number(dx) * Math.PI / 180)+stepNum;
          yn = Math.sin(Number(dy) * Math.PI / 180)+stepNum;
          var moveMatrix = app.getTranslationMatrix(xn, yn);
          p.transform(moveMatrix);
          stepNum+=stepNum;
      }
      
        • 1. Re: Math.cos Math.sin = Math.HELP
          Franck Payen CommunityMVP

          Sounds "doable", although a picture of your expected result would be welcome, since i don't really understand the stepNum's increasing variable.

           

          What i understand is you're trying to make polar moves from one element.

           

          Does this picture reflect what you have in mind ?

          Ai-Scripting-Forum.png

          Because it sounds more like a math issue than something impossible

          • 2. Re: Math.cos Math.sin = Math.HELP
            Franck Payen CommunityMVP

            By the way, it sounds more like a problem for Thales than sin cos (lengths divided by a parallel have equal ratios)

             

            Ai-Scripting-Forum-Thales.png

             

            say :

             

            Origin is the center of your selected object s0

             

            dX0 and dY0 are the actual distance of this pathItem from the origin

             

            var dx0 = (p.position[0] + p.width / 2) - (s0.position[0] + s0.width / 2);

            var dy0 = (p.position[1] + p.height / 2) - (s0.position[1] + s0.height / 2);

             

            dX1 and dY1 are the distance of this triangle from the origin

             

            Knowing dx0/dx1 = dy0/dy1 = s0P0/s0P1

            i suppose your StepNum determines the s0P0/s0P1 value…

             

            (if i understood you well)

            • 3. Re: Math.cos Math.sin = Math.HELP
              CarlosCanto Community Member

              Hi W_J_T, here's one way to do what I think you want to do, I commented out the step increment so all items will "explode" the same distance, not sure if that's what you need.

               

              first I'd move the calculation of the Selected object's center out of the loop, you only need to make the math once.

              also, (s0.position[0] + s0.width) / 2  has a problem, it will not give you the center, check below

              // calculate Selection center position
              var cx = s0.position[0] + s0.width/2;
              var cy = s0.position[1] + s0.height/2;
              

               

              then we're going to loop thru all items and calculate their center

                      // calculate pathItem's center position
                      var px = p.position[0] + p.width/2;
                      var py = p.position[1] + p.height/2;
              

               

              we're going to skip calculating the distance from the selection's center to each item's center, we don't need it for this method, other methods could use this info.

               

              now, your actual question about Sin/Cos

              xn = Math.cos(Number(dx) * Math.PI / 180)+stepNum;

              sin(angle) and cos(angle) expect angles in Radians, you are not providing any angles in the formula above. We need to calculate the angle between Selection's center and each path's center

                      // get the angle formed between selection's center and current path's center
                      var angle = get2pointAngle ([cx,cy], [px,py]);
              

               

              once we have the angle we can apply it to our "Explosion" variable, I'm assuming is stepNum, and get its x and y distance it needs to move away from selection

                      // the distance to move is "stepNum" in the same direction as the angle found previously, get x and y vectors
                      var dx = stepNum*Math.cos(angle);// distance x 
                      var dy = stepNum*Math.sin(angle);// distance y
              

               

              all is left to do is move the paths, here's the whole thing

              // Explosion, AKA move all items away from selection
              // carlos canto
              // http://forums.adobe.com/thread/1382853?tstart=0
              
              
              var docID = app.activeDocument;
              var s0 = docID.selection[0];
              pID = docID.pathItems;
              
              
              var stepNum = 20; // this is the distance to "explode"
              
              
              // calculate Selection center position
              var cx = s0.position[0] + s0.width/2;
              var cy = s0.position[1] + s0.height/2;
              
              
              for (var i = 0; i < pID.length; i++) {
                  var p = pID[i];
                  
                  // skip selected item
                  if (!p.selected) {
                      // calculate pathItem's center position
                      var px = p.position[0] + p.width/2;
                      var py = p.position[1] + p.height/2;
                      
                      // get the angle formed between selection's center and current path's center
                      var angle = get2pointAngle ([cx,cy], [px,py]);
                      
                      // the distance to move is "stepNum" in the same direction as the angle found previously, get x and y vectors
                      var dx = stepNum*Math.cos(angle);// distance x 
                      var dy = stepNum*Math.sin(angle);// distance y
                      
                      var moveMatrix = app.getTranslationMatrix(dx, dy);
                      p.transform(moveMatrix);
                      //stepNum+=stepNum;
                  }
              }
              
              
              // return the angle from p1 to p2 in Radians. p1 is the origin, p2 rotates around p1
              function get2pointAngle(p1, p2) {
                  var angl = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]);
                  if (angl<0) {   // atan2 returns angles from 0 to Pi, if angle is negative it means is over 180 deg or over Pi, add 360 deg or 2Pi, to get the absolute Positive angle from 0-360 deg
                      angl = angl + 2*Math.PI;
                  }
                return angl; 
              }
              
              • 4. Re: Math.cos Math.sin = Math.HELP
                pixxxel schubser Community Member

                @W_J_T,

                at first I did not understand your question.

                 

                 

                That made it a bit clearer for me (I hope so).

                CarlosCanto wrote:

                 

                Hi W_J_T, here's one way to do what I think you want to do, I commented out the step increment so all items will "explode" the same distance, not sure if that's what you need.

                 

                 

                Perhaps this thread is the answer for you:

                http://forums.adobe.com/message/3158311#3158311

                • 5. Re: Math.cos Math.sin = Math.HELP
                  W_J_T Community Member

                  First off thanks so much to everyone for the valued input and feedback, thanks so much. Sorry for any confusion that my description and failed code attempt gave.

                  Franck Payen wrote:

                   

                  Because it sounds more like a math issue than something impossible

                   

                  Thanks for your input Franck, I agree its certainly a math issue and more of a lack there of on my part for sure.

                  I think the concepts and thoughts you posted are indeed on the right track, thank you for the detailed thoughts and feedback.

                  pixxxel schubser wrote:

                   

                  Perhaps this thread is the answer for you:

                  http://forums.adobe.com/message/3158311#3158311

                   

                  Hi pixxxel schubser, thanks for the link, I have seen that in the past and was aware of it and noticed also that it had some similarities for this concept.

                  CarlosCanto wrote:

                   

                  Hi W_J_T, here's one way to do what I think you want to do, I commented out the step increment so all items will "explode" the same distance, not sure if that's what you need.

                   

                  Greetings CarlosCanto, yes explode or disperse from a common center is what I was after. Thanks so much for your detailed code explanation and example, I think its on track to what I was after, thank you so much. It also appears a lot more involved than I had anticipated (ha ha) I really appreciate your knowledge as always. Regarding the step increment I was hoping to step the movement given the objects distance from the origin. I tried adding it back in such as: step += .2 // etc, with varied results. It seems like the code disperses things differently based on there distance, postion  and already inherent rotation, some interesting results. I think you're pretty much spot on unless you have some additional thoughts or suggestion on properly implementing a step amount? Thanks Carlos.

                   

                  ---

                   

                  Thanks again everyone for all the great input, thoughts, knowledge and assistance, wonderful stuff everyone thank you!

                  (I will certainly mark everything helpful and correct from all of you after any possible further feedback. Thanks again everyone, great stuff.

                  • 6. Re: Math.cos Math.sin = Math.HELP
                    CarlosCanto Community Member

                    Regarding the step increment I was hoping to step the movement given the objects distance from the origin. I tried adding it back in such as: step += .2 // etc, with varied results. It seems like the code disperses things differently based on there distance

                    for that you need to create an "explodeRatio" variable that would decrement/increment the "explosion" distance. Close objects would "explode" more than far away objects

                     

                    for example you can decide that objects in a 20 pts radius from the selection center would "explode" the full distance (20 pts), so your Ratio would need to equal 1.

                     

                    // for close objects

                    var explode = 20;

                    var distance = 20; // distance from selection center to object center

                    var explodeRatio = explode/distance; // 20/20=1

                    var objectExplode = explode*explodeRatio; // 20*1=20, move 20 in its own direction

                     

                    // for far objects

                    var explode = 20;

                    var distance = 100; // distance from selection center to object center

                    var explodeRatio = explode/distance; // 20/100=0.2

                    var objectExplode = explode*explodeRatio; // 20*0.2=4, move 4 in its own direction

                    • 7. Re: Math.cos Math.sin = Math.HELP
                      W_J_T Community Member

                      CarlosCanto wrote:

                       

                      for that you need to create an "explodeRatio" variable that would decrement/increment the "explosion" distance. Close objects would "explode" more than far away objects

                       

                      Thanks so much CarlosCanto for the additional information. So I assume past this new variable(s) that there is further math that needs to be in place with the bulk of the code to implement it and get this differentiation (near/far) and stepped approach? Sorry for my lack of full understanding of things, I appreciate your assistance and help.

                      • 8. Re: Math.cos Math.sin = Math.HELP
                        CarlosCanto Community Member

                        I made the Math for you and created the variables too, you just need to incorporate that into my previous post

                        • 9. Re: Math.cos Math.sin = Math.HELP
                          W_J_T Community Member

                          Sorry Carlos, I guess I am just not following and I am still confused as to how those variables get implemented into the previous code, am I just replacing stepNum with explodeRatio or objectExplode? Ugh.., I apologize for having such disconnect here properly understanding things, sorry to be such a burden at this point.

                          • 10. Re: Math.cos Math.sin = Math.HELP
                            CarlosCanto Community Member

                            no problem, try this

                            explode.PNG

                             

                            // Explosion, AKA move all items away from selection
                            // carlos canto
                            // http://forums.adobe.com/thread/1382853?tstart=0
                            
                            
                            var docID = app.activeDocument;
                            var s0 = docID.selection[0];
                            pID = docID.pathItems;
                            
                            
                            var stepNum = 40; // this is the distance to "explode"
                            
                            
                            // calculate Selection center position
                            var cx = s0.position[0] + s0.width/2;
                            var cy = s0.position[1] + s0.height/2;
                            
                            
                            for (var i = 0; i < pID.length; i++) {
                                var p = pID[i];
                            
                                // skip selected item
                                if (!p.selected) {
                                    // calculate pathItem's center position
                                    var px = p.position[0] + p.width/2;
                                    var py = p.position[1] + p.height/2;
                            
                                    // get the angle formed between selection's center and current path's center & their distance
                                    var angle = get2pointAngle ([cx,cy], [px,py]);
                                    var distance = get2pointDistance ([cx,cy], [px,py]);
                            
                            
                                    var explodeRatio = stepNum/distance; // this can be built in any way you want, the longer the distance the lower the Ratio
                                    var objectExplode = stepNum*explodeRatio;
                            
                            
                                    // the distance to move is "stepNum" in the same direction as the angle found previously, get x and y vectors
                                    var dx = objectExplode*Math.cos(angle);// distance x 
                                    var dy = objectExplode*Math.sin(angle);// distance y
                            
                                    var moveMatrix = app.getTranslationMatrix(dx, dy);
                                    p.transform(moveMatrix);
                                    //stepNum+=stepNum;
                                }
                            }
                            
                            
                            // return the angle from p1 to p2 in Radians. p1 is the origin, p2 rotates around p1
                            function get2pointAngle(p1, p2) {
                                var angl = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]);
                                if (angl<0) {   // atan2 returns angles from 0 to Pi, if angle is negative it means is over 180 deg or over Pi, add 360 deg or 2Pi, to get the absolute Positive angle from 0-360 deg
                                    angl = angl + 2*Math.PI;
                                }
                              return angl; 
                            }
                            
                            
                            // return the distance from p1 to p2
                            function get2pointDistance(p1, p2) {
                              return Math.sqrt ((Math.pow (p1[0]-p2[0], 2) + Math.pow (p1[1]-p2[1], 2)));
                            }
                            
                            • 11. Re: Math.cos Math.sin = Math.HELP
                              W_J_T Community Member

                              Thanks so much CarlosCanto for your continued involvement and knowledge sharing. Hey, you said there wasn't any more math but you added an entire function, ha ha just kidding. ;-)

                              CarlosCanto wrote:

                               

                              var explodeRatio = stepNum/distance; // this can be built in any way you want, the longer the distance the lower the Ratio

                               

                              Would you mind explaining that further: "built in any way"? For example, resulting then in various outcomes? For example Is it possible to reverse things so things far explode and things near don't? Or another example would be implode by contrast. Any input or feedback is welcome, but if your tired of it or me just say so. ;-) Thanks so much CarlosCanto, your awesome man.

                               

                              ----------

                               

                              EDIT: I went ahead and marked various posts correct and helpful. Carlos you must have got tired of my inquiries (ha, ha) thanks for your patience and willingness to assist. Thanks for all your help and to everyone whom was gracious enough to provide feedback, thanks so much everyone, its greatly appreciated. Thank you.

                              • 12. Re: Math.cos Math.sin = Math.HELP
                                CarlosCanto Community Member
                                Would you mind explaining that further

                                 

                                the idea is to create a number that changes the actual amount to "explode" based on the distance.

                                 

                                to "implode", we just need to reverse the direction of the explosion by multiplying our ratio by -1...I used -5 for a more dramatic effect

                                change the script above to this values

                                var stepNum = 40; // 3
                                
                                var explodeRatio = -5*stepNum/distance; // 3 implode
                                
                                var objectExplode = stepNum*explodeRatio; // 3 implode
                                

                                explode4.PNG

                                 

                                ...just play with this values, change them around to your heart's content, get creative

                                var stepNum = 500; // 2
                                
                                var explodeRatio = distance/stepNum; // 2
                                
                                var objectExplode = stepNum*Math.pow (explodeRatio, 3); // 2
                                

                                explode3.PNG

                                explode2.PNG

                                • 13. Re: Math.cos Math.sin = Math.HELP
                                  W_J_T Community Member

                                  Thanks so much CarlosCanto for all your help and knowledge sharing as always. Now if only I had a script that could download your brain to my computer and txt editor.