Background
I am creating a game in which you can control multiple people in a community, so obviously, the people need to be able to move on their own, with their own tasks to accomplish. I used the method described in this post about how to move a mesh / object along a path in Three.js. It worked as you can see below but all the people are moving at different speeds than each other. I don't want this.
Question
How do I make them all move at the same speed? And if you have a better solution on how to move a mesh from point to point then please tell me how.
PS: In the post I linked, I used the "fancy movement" part of the answer.
(In the event the fiddle goes away, the previous answer used a slowly incremented variable with path.getPointAt(position) to move the objects along the path.)
The Curve.getPointAt method takes a value that is a percentage along the curve. Because of this calculation, the distance between points (for example 0 and 0.1) will be different based on the length of the curve.
So if curve1 is 10 units long, and curve2 is 100 units long, then:
curve1.getPointAt(0.1) // vector 1 unit from the start of curve1
curve2.getPointAt(0.1) // vector 10 units from the start of curve2
If you're basing your motion on this, then basically the object moving along curve2 will move 10x as fast as the object moving along curve1.
What you want to do instead is determine how many steps the object should take along a path, given a certain "steps/second" or "steps/frame". This is more aligned to the concept of a real physical velocity, rather than one defined by the length of the path being taken.
Let's say you want to travel at 2 units per frame along curve1 and curve2. Now that you're traveling at a fixed rate, you just need to divide the rate by the total length to get the number of "steps" (or in this case, frames) it will take to reach the end of the path.
2 / 10 = 0.2 // this is the point polling percentage for curve 1
2 / 100 = 0.02 // this is the point polling percentage for curve 2
Now, when you move an object along curve1, you will need to use path.getPointAt(0.2), and for curve2 you will use path.getPointAt(0.02).
Looking ahead a little, you might ask what happens when the math doesn't line up outside a perfect example, and you have extra "partial steps" to make it to the end of the curve. Well, that's up to you to decide how to handle it. You could spend an extra frame to finish the motion, or you could look a step ahead during the movement calculation and decide to just send it to the end.
EDIT: Question has been edited to narrow scope, but I felt it helpful to keep the original information. Look past the conclusion section for edits.
Original Question
Good day everyone! I'd like to learn the logic behind SVG morphing. Just as a quick precursor, I know that there are questions similar to this on Stack Overflow already, but as far as I know this is not a duplicate. If you read a bit further you'll see what I mean.
Why?
I'd like to morph one SVG into another but I need a cross-browser solution. I've found solutions such as GreenSock, but I can't afford their licenses.
What?
In the spirit of an evolving developer, I've decided to expand my horizons a bit and find out how to make a personal, re-usable cross-browser SVG morph solution. Though, before starting I'd like to understand approximately what I'm aiming for.
Details (My main question)
I'm hoping I could get some insight on the logic behind SVG morphing. I.E. How might vertices be matched together and tweened, how might vertices be seamlessly converted from a sharp corner to a bezier curve, what is the math behind these conversions, how might it be possible to morph SVGs of different vertex count (if you happen to have any ideas), how would you prevent vertices from matching to multiple correspondents in the target shape, etc.?
I'm much more interested in the logic, the computer science, the mathematics. If you're willing to point me in the right direction in terms of what built-in Javascript functions I need to use, then I would greatly appreciate that, but it is not necessary. Once I have an idea of the logical direction I need to take, I can easily look up that documentation.
For example sake, making things consistent in responses, what if I wanted to morph a circle into a square? (There are obviously easier ways to do that, but using this just makes it simpler to visualize)
Disclaimers
(1) I'm very well versed in Javascript, its syntax, and intricacies. I've just never dealt with vectors in Javascript, I'm unsure how vertices are targeted and manipulated.
(2) I'm NOT asking for a full, in-depth tutorial on how to accomplish this, I know that's not what any of us are here for. Rather, I'd appreciate a backbone, a push in the right direction, and some insight into the nuances of this process.
TL;DR
What insight could you provide into the logic, science, or mathematics behind morphing from one SVG to another (simple or complex).
Conclusion
Thank you all for any insight you can provide! This is by no means immediately necessary, so please feel free to take your time in responding.
EDIT:
This question was put on hold for being too broad. After revisiting what I wrote, I completely understand. Thus, here is, more specifically, what I'd like help with.
Lets say I have vector A, from illustrator:
<svg id="Layer_1" x="0px" y="0px" width="72px" height="72px" viewBox="0 0 72 72" . . . >
<polygon style="fill:#FFFFFF;" points="72,72 36,72 0,72 0,36 0,0 36,0 72,0 72,36 "/>
</svg>
And vector B:
<svg id="Layer_1" x="0px" y="0px" width="72px" height="72px" viewBox="0 0 72 72" . . .>
<path style="fill:#FFFFFF;" d="M72,36c0,9.941-4.029,18.941-10.544,25.456S45.941,72,36,72c-9.938,0-18.937-4.027-25.451-10.539
C4.031,54.945,0,45.943,0,36c0-9.941,4.029-18.941,10.544-25.456C17.059,4.029,26.059,0,36,0c9.94,0,18.939,4.029,25.455,10.543
C67.971,17.058,72,26.059,72,36z"/>
</svg>
Vector A is a perfect square with 8 evenly spaced vertices, Vector B is a perfect circle with 8 evenly spaced vertices.
If I wanted to morph Vector A into Vector B, how might I go about it in Javascript? I understand that I would have to use a loop and actively move the points to their designated destinations, but, firstly, what would be the best method of targeting and moving the individual vertices? Secondly, what is the best method of determining which position the vertex should move to, and how could that be actively tracked. For something like this where the vertices are perfectly spaced, with multiple points equidistant from a singular target, how would I logically go about matching the correct vertices for the most aesthetic result? Third, in this example I am converting a polygon element into a path element, is that important? and if so how might I get around that obstacle.
Again, I'm most interested in the logic, but specific code is always appreciated. And just to reiterate, I'm not looking for a solution to SVG morphing, those are abundant, I'm hoping to understand the process so that I may recreate it, to expand my development knowledge.
Thank you very much! All input is appreciated.
I created a simple library to merge two images in javascript, however it does not work with SVGs ... but maybe i can still help with few suggestions:
once you have matching points it should be easy:
- lets call points in picture 1 O1 .. Ox (O as origin ;)
- lets call points in picture 2 D1 ...Dx (D as destination)
- lets call the time when we start morphing T1
- and lets call the time when we stop T2 (so T2-T1 is the length of animation)
based on T2 and T1 you can calculate the number of frames you will need to show.
then you can calculate the positions for each frame. basicly the frame at T1 should be picture 1 ... frame at T2 should be picture 2 ... lets call number of frames NF.
for in between frames you need to calculate the new position of your points, lets call them F1_1 ... F1_x (frame one points from 1 to x). Lets call a specific frame Fx (so point in specific frame is Fx_x)
we can then calculate the positions of points for each frame:
F1_x = Fx*(distance from Tx to Px)/NF
to explain .... we take a point from first image and a point from second and calculate the distance between them and split this distance by number of frames we want to show. then for each frame we multiply this distance by frame number.
so now we have our point positions for each of the frames. if its SVG that is probably it already. if its multicolor you might want to mix the colors from image 1 and image 2.
You could do that in the same way as you calculated point positions .... take color at the start ... take color at the end. find the difference, then keep changing in small steps, where number of steps equals number of frames you want to show.
you can take a look at my blogpost (with link to github project) about image morphing library i wrote: http://peter.pisljar.si/#!/en/projects/image_morph_js
however .... to find the matching point it might be a bit more work.
I have a background image that is a speedometer.
I need to point the needle to the correct spot. It does not need to be animated, but I will have to take into consideration where the needle needs to point at in the half circle, based on the value (speed).
I am not looking for an answer, but for some help identifying some jquery libraries that will help me accomplish this.
GSAP (http://www.greensock.com/get-started-js/) is a great library - I know you're not wanting to animate it, but with the library, you get tonnes of transforming options all of which are miles ahead of standard jQuery and CSS3 properties.
In addition to affording you the ability to place your elements in unique positions, you can easily animate them should you ever desire to do so in the future.
As per the speed listening function;
Set an empty JS var (speed)
On key press (arrow key, for example), increase the speed var +1
Listen for changes in the speed var, then adjust up/down the speedometer needle.
I have a very complicated site built on CSS3 that has html elements 3d-transformed, rotated, flipped, flopped and just generally distorted.
I'm trying to figure out the on-screen location of one of these elements and don't see any way to do so. I was wondering if anyone has any ingenious ideas.
Alternatively, if anyone can explain the math behind -webkit-perspective, I can figure out the position as that's the only thing I'm not sure how to model.
Have you tried using getBoundingClientRect()?
I've used it successfully in the past to calculate the dimensions of elements that have been transformed with the transform property.
The problem is, that the CSS3 transformations doesn't actually change the position of the elements in anyway. Of course the browsers "know" that they are repositioned, because it renders them, but this information is not provided back to the DOM/API.
The only thing I can think of, is to calculate the positions based on the transformations yourself, since these are "simple" matrix transformations.
Unfortunately Algebra class has been too long ago, that I can't tell you anymore how to do it - only that it is possible.
Using getBoundingClientRect is a good idea but will only give you the coordinates of the rectangle that contains your shape, not the exact coordinates of the 4 topleft, bottomright, bottomleft, topright corners.
You'd only be able to do this by taking each of those non-transformed coordinates and applying the transform via javascript.
I'm finishing up a drawing application that uses OpenGL ES 2.0 (WebGL) and JS. Things work pretty well unless I draw with very quick movements. See the image below:
This loop was drawn with a smooth motion, but because JS was only able to get mouse readings at specific locations, the result is faceted. This happens to a certain degree in Photoshop if you have mouse smoothing turned off, though obviously much less because PS has the ability to poll at a much higher rate.
So, I would like to implement some mouse smoothing, but I'm concerned about making sure it's very efficient so that it doesn't bog down the actual pixel drawing operations. I was originally thinking about using the mouse locations that JS is able to grab to generate splines and interpolate between readings to give a smoother result. I'm not sure if this is the best approach, though. If it is, how do I make sure I sample the correct locations on the intermediate spline? Most of the spline equations I've found don't have uniformly-distributed values for t = [0, 1].
Any help/guidance/advice would be very appreciated. Thanks!
Catmull-Rom might be a good one to try, if you haven't already.
http://www.mvps.org/directx/articles/catmull/
I'd pick a minimum segment length and divide up segments that are over that into 1+segmentLength/minSegmentLength sub-segments.