Using netwire-4.0.7
As the question title says, I'm trying to create a wire that produces positions (moving the position with a certain velocity in each step), "bouncing" off other objects. The simplest example I could think of was moving within a box, like in some screen savers.
I wrote this function as an attempt to do just that (for one axis only):
import Control.Wire
bouncyWire :: Double -> Double -> Double -> Double -> Wire () IO a Double
bouncyWire startPosition startVelocity lowerBound upperBound = proc _ -> do
rec
v <- delay startVelocity -< if p < lowerBound || p > upperBound
then -v else v
p <- integral_ startPosition -< v
returnA -< p
(I actually use it with a different monad, but this code doesn't actually use it and it would overcomplicate the issue here).
Stepping it with a counterSession $ 1/60 however, I get a problem - instead of "bouncing" off the wall, it gets stuck there. I think what happens is that it keeps flipping the velocity v over and over, but I'm not sure why. I think I might be using delay wrong or something.
As Richard Huxton explained, your wire is getting stuck behind the border. One solution is to check that you don't just reverse velocities, you always point them to the right direction. This way, the wire gets always from behind the border. Another solution is to change the position back inside the borders if it gets out. This way, the wire is never perceived to get behind (which is something you usually want to do in games). Combined together it could look like
import Prelude hiding ((.), id)
import Control.Category
import Control.Wire
import Control.Wire.Wire
import Control.Wire.Prefab.Move
bouncyWire :: (Monad m)
=> Double -> Double -> Double -> Double -> Wire () m a Double
bouncyWire startPosition startVelocity lowerBound upperBound =
objPosition <$> object_ update (ObjectState startPosition startVelocity)
. constant (Accelerate 0, ())
where
update _ s#(ObjectState pos vel)
| (pos > upperBound) = ObjectState (2*upperBound - pos) (- abs vel)
| (pos < lowerBound) = ObjectState (2*lowerBound - pos) (abs vel)
| otherwise = s
I'm not very familiar with the arrow notation so I used Category and Applicative notation (composition of wires using .). For this task, object_ is particularly handy. It integrates the velocity and loops internally and all we need to do is to give it a modifying function and extract position from the output.
Ah, a chance to recyle knowledge from my days messing around writing 8-bit games in a mix of BASIC and assembler!
What's probably happening is that the "ball" is getting stuck just the wrong side of the wall due to rounding errors. So - if your wall is at 10.0, the ball oscillates between 11.0001 and 10.0001 with v=-1.0,+1.0,-1.0 etc. Not sure how you'd print the position to check with wires.
From (ancient) memory, you either want to calculate the bounce including any "leftover" vector from the previous step, or just place the ball exactly on the wall before bouncing it.
Related
this is the bouncing ball code. I'm trying to make 'appendFile' run on the update function, so when the ball bounces off the wall, then 'appendFile' will write the px and px values to the file "log.txt"
import Graphics.Gloss
import Graphics.Gloss.Data.ViewPort (ViewPort)
main :: IO ()
main =
simulate
(InWindow "Bouncing ball" (width, height) (50, 50))
white
30
initial
view
update
but I'm having trouble because 'appendFile' only runs on signiture IO. And I don't know how to apply it in a situation like this
update :: ViewPort -> Float -> World -> World
update _ _ World {position = (px, py), velocity = (vx, vy)} =
let
appendFile "Log.txt" ("" ++ show px ++ " " + show py ++ "")
newPx = px + vx
newPy = py + vy
newVx = if newPx >= fromIntegral width || newPx <= 0 then - vx else vx
newVy = if newPy >= fromIntegral height || newPy <= 0 then - vy else vy
in World {position = (newPx, newPy), velocity = (newVx, newVy)}
Haskell is really strict about side effects. Writing to a file is a side effect, and a pure function (like your update) is not allowed to have side effects.
If you merely want to record the data for debugging then you can use the infamous accursed unsafePerformIO, which provides a back door into the IO monad for pure computations. The reason for the "unsafe" bit of the name is that this makes no promises about how often the IO action gets run, or even if it gets run at all.
BUT the code you have above won't actually call appendFile. In fact that is a syntax error; a let introduces values which might be used in the code, but you have no assignment for the result of appendFile.
You would need something more like:
let
... omitted
in seq
(unsafePerformIO $ appendFile "Log.txt" (show px ++ " " ++ show py ++ "\n")
World {position = (newPx, newPy), velocity = (newVx, newVy)}
seq is a magic function which is "strict" in its first argument, so the unsafePerformIO gets evaluated before the new World, even though nothing ever uses the result of that first argument.
However this is a kluge. You should not use unsafePerformIO for production code. It is a lie to the compiler. If you make a habit of it then the compiler will get its revenge, and it will not be pretty.
If this is for production code then you should instead use simulateIO. This takes an update function which returns an IO value, so then you can write update to return an IO World and everyone will be happy.
I'm very new to Haskell so I apologise if this is too basic, or if it makes very little sense. I'm trying to read an image; I can get it to a list of pixel data with the following code:
data Pixel = Pixel {
red :: Integer,
green :: Integer,
blue :: Integer,
alpha :: Integer
} deriving (Show)
getImagePixelArray :: FilePath -> IO (Codec.Picture.Repa.Img RGBA)
getImagePixelArray fp = do
img <- (either error return =<< readImageRGBA fp)
return img
getImagePixelData :: Codec.Picture.Repa.Img RGBA -> [(Word8,Word8,Word8,Word8)]
getImagePixelData img = R.toList (collapseColorChannel img)
rawPixelToPixel :: (Word8,Word8,Word8,Word8) -> Pixel
rawPixelToPixel (r, g, b, a) = Pixel {
red = (toInteger r),
green = (toInteger g),
blue = (toInteger b),
alpha = (toInteger a)
}
main = do
imageData <- getImagePixelArray "./images/image1.png"
let imageRawPixels = getImagePixelData imageData
let asPixels = Prelude.map rawPixelToPixel imageRawPixels
mapM print asPixels
I more or less follow what's going on, but my knowledge of Haskell is still limited, so when it comes to making sense of api documentation, I'm struggling a little.
I really want to be able to parse the positions of the pixels; I understand how to do that if I know the width and height of an image, but I can't figure out how to get the width/height of an image.
I'm making my way through a Haskell course, but I'm also trying to put it to some practical use along the way to help the concepts sink in.
Start with the documentation. None of what you're asking for is obviously available on Img, so where else could it be? There's a related Image type, mentioned in convertImage's documentation - I wonder what that is. As it turns out, it has a width and a height. How can we get an Image from our Img, then? imgToImage will give us a DynamicImage, which has several constructors each containing an Image. Figure out what kind of Image you have inside your DynamicImage, and then ask that Image its dimensions.
Perhaps there is something easier with the other lens-y stuff in that module, but it is not obvious to me, and this approach seems simple enough, if a hassle.
I have a "simple" problem with JAGS that drives me crazy. In essence, consider the following example that works:
x2[i] ~ dnorm(mu[i,1], tau1);
u[i] ~ dnorm(mu[i,2], tau2);
Here, x2 is an observable variable (that is, data), while u is a latent variable. In the example, both are drawn independently from two distinct normal distributions.
However, I want them to be (possibly) dependent, that is, to be drawn from one multivariate normal distribution. So I would like to do:
c(x2[i], u[i]) ~ dmnorm(mu[i,1:2], Omega[1:2,1:2]);
Unfortunately, this doesn't work because this syntax is not correct. However, having tried many different syntaxes, neither of them does work. E.g.,
y[i,1] <- x2[i];
y[i,2] <- u[i];
y[i,1:2] ~ dmnorm(mu[i,1:2], Omega[1:2,1:2]);
leads to the error Node y[1,1:2] overlaps previously defined nodes, what is obvious.
So what can I do? Please, help me, I'm getting mad...
UPDATE: I figured out that I can at least do the following:
(in R:)
p <- 1/(1+exp(-x2));
t <- rep(10000, length(x2));
s <- rbinom(length(x2), t, p2);
(in JAGS:)
nul[i,1] <- 0;
nul[i,2] <- 0;
e[i,1:2] ~ dmnorm(nul[i,1:2], Omega[1:2,1:2]);
u[i] <- mu[i,2] + e[i,2];
x2g[i] <- mu[i,1] + e[i,1];
pg[i] <- 1/(1+exp(-x2g[i]));
s[i] ~ dbin(pg[i], t[i]);
This works (a bit), but looses of course efficiency since an observable variable (x2) is treated as if it was only indirectly observable (through s).
You are defining y twice Once in:
y[i,1] <- x2[i];
y[i,2] <- u[i];
And once in
y[i,1:2] ~ dmnorm(mu[i,1:2], Omega[1:2,1:2]);
You might be able to get away with:
x2[i] <- y[i,1];
Or you might be able to simply write out the regression (after all it is bivariate, so not that difficulty).
You also might get a faster response on the JAGS mailing list (which Martyn Plummer regularly monitors).
You can use the data block as follows:
data{
for(i in 1:length(x2)) {
y[i,1] <- x2[i]
y[i,2] <- u[i]
}
}
model{
for(i in 1:length(x2)) {
y[i,1:2] ~ dmnorm(mu[i,], Tau)
}
# ... definition of mu, Tau, and their prior distribution
}
However, be sure there are no missing values in x2 or u, since a multivariate node cannot be partly observed.
Regards! :)
How does the 'canonize' function (given below, from Ukkonen's paper) work, and in particular, when is the while loop finished? I think the value of p' - k' will always remain less than that of p - k. Am I right or wrong?
procedure canonize(s, (k, p)):
1. if p < k then return (s, k)
2. else
3. find the tk–transition g'(s, (k', p')) = s' from s;
4. while p' − k' <= p − k do
5. k = k + p' − k' + 1;
6. s = s';
7. if k <= p then find the tk–transition g'(s, (k', p')) = s' from s;
8. return (s, k).
What the canonize function does is what is described at the very end of this SA post, where we consider a situation like this:
The situation is this:
The active point is at (red,'d',3), i.e. three characters into the defg edge going out of the red node.
Now we follow a suffix link to the green node. In theory, our active node is now (green,'d',3).
Unfortunately that point does not exist, because the de edge going out of the green node has got only 2 characters. Hence, we apply the canonize function.
It works like this:
The starting character of the edge we are interested in is d. This character is referred to as tk in Ukkonen's notation. So, "finding the tk-edge" means finding the de edge at the green node.
That edge is only two characters in length. I.e. (p' - k') == 2 in Ukkonen's notation. But the original edge had three characters: (p - k) == 3. So <= is true and we enter the loop.
We shorten the edge we are looking for from def to f. This is what the p := p + (k' - p') + 1 step does.
We advance to the state the de edge points to, i.e. the blue state. That is what s := s' does.
Since the remaining part f of the edge is not empty (k <= p), we identify the relevant outgoing edge (that is the fg edge going out of the blue node). This step sets k' and p' to entirely new values, because they now refer to the string fg, and its length (p' - k') will now be 2.
The length of the remaining edge f, (p - k), is now 1, and the length of the candidate edge fg for the new active point, (p' - k'), is 2. Hence the loop condition
while (p' - k') <= (p - k) do
is no longer true, so the loop ends, and indeed the new (and correct) active point is (blue,'f',1).
[Actually, in Ukkonen's notation, the end pointer p of an edge points to the position of the final character of the edge, not the position that follows it. Hence, strictly speaking, (p - k) is 0, not 1, and (p' - k') is 1, not 2. But what matters is not the absolute value of the length, but the relative comparison of the two different lengths.]
A few final notes:
Pointers like p and k refer to positions in the original input text t. That can be quite confusing. For example, the pointers used in the de edge at the green node will refer to some substring de of t, and the pointers used in the fg edge at the blue node will refer to some substring fg of t. Although the string defg must appear as one continuous string somewhere in t, the substring fg might appear in other places, too. So, the pointer k of the fg edge is not necessarily the end pointer p of the de edge plus one.
What counts when we decide whether or not to end the loop is therefore not the absolute positions k or p, but the length (p - k) of the remaining edge compared to the length (p' - k') of the current candidate edge.
In your question, line 4 of the code snippet, there is a typo: It should be k' instead of k;.
I had to change the canonize function because it didn't handle the auxiliary state properly. I added the following code after the 'p < k' if:
if (s == auxiliary)
{
s = root;
k++;
if (p < k)
return;
}
It seems to work now :)
I was looking at this on the Wikipedia Page and was wondering if anyone has a working implementation of this.
I'm trying to learn Haskell, finding it slightly difficult and am working on the Koch Snowflake and Sierpinski Triangle.
Any code or suggestions welcome.
Thanks
For these kind of pictures which have a lot of structure and are scale independent, I would recommend the diagrams package ( http://projects.haskell.org/diagrams/ ), it's really quite a fantastic piece of code, see the following code to generate Koch snowflake written by yours truly in a matter of minutes :
snowflake :: Int -> Trail R2
snowflake n = k <> k # rotateBy (-1/3) <> k # rotateBy (1/3)
where k = koch n
koch :: Int -> Trail R2
koch 0 = P (-1,0) ~~ P (1,0)
koch n = k <> k # rotateBy (1/6) <> k # rotateBy (-1/6) <> k
where k = koch (n-1) # scale (1/3)
Which is almost self-explanatory, most of the magic is in the Monoid instance of Trail which will "concatenate" the trails end to end.
Note : (<>) is an operator for mappend, diagrams defined it in the past but this is now part of base in GHC 7.4 and will probably be included in a future version of the Haskell report, (#) is just the application reversed because diagrams author found it more pleasant to define a diagram then apply its attribute rather than write it in the other direction (so k # rotateBy (1/6) is just rotateBy (1/6) k).
Calculate the points of a triangle centered in the plane.
At each point of the triangle, calculate the points of a triangle one-third its size, and the other way up (flipped along its horizontal middle).
Pass each triangle to step 2, pass the results of that again to step 2, and so on.
Do all that again, upside down.
That should give you a list of (lists of) triangles. Now draw these triangles on the screen to the depth that you think is reasonable.