I'm trying to get the XY coordinates of a moving sprite in SmileBASIC, and I can't figure it out. I have the single variable returned from SPCHK, but when I print it, I get a single number '4' constantly as the sprite moves. How do I get each bit?
From the documentation:
Return Values for SPCHK
|b00| XY-coordinates (1), #CHKXY
|b01| Z-coordinates (2), #CHKZ
|b02| UV-coordinates (4), #CHKUV
|b03| Definition number (8), #CHKI
|b04| Rotation (16), #CHKR
|b05| Magnification XY (32), #CHKS
|b06| Display color (64), #CHKC
|b07| Variable (128), #CHKV
For each bit, a target is assigned (If 0 is assigned for all bits, animation is being stopped)
SPCHK only tells you which properties are currently being animated, not their values.
To get the actual position, you can use SPOFS id OUT x,y
Example:
SPSET 0,17
SPANIM 0,"XY",-10,100,100
WAIT 5
SPOFS 0 OUT X,Y
?X,Y 'should be 50,50
Related
Write a function called connectTheDots that takes in a list of tuples as its input and an optional color input as well. The default color value should be black. Each tuple is a coordinate pair (x, y) for a turtle. The function will have the turtle trace out a picture by starting at the first coordinate and then moving to each coordinate in turn.
Your function should do the following:
a. Create a turtle, setting the turtle’s color and speed appropriately
b. Check if the input list is empty: if it is empty then nothing else should happen!
c. Without leaving a line behind, move the turtle to the first location given in the list. Then start leaving a line again. Note: recall how to pull values out of a list, and also know that the goto method can take a single (x, y) tuple as its input: myTurtle.goto( (25, 25) ) will move myTurtle to x = 25 and y = 25.
d. After the turtle is at the starting coordinate, move it to each coordinate in the list in turn.
This is what I have been able to do so far:
def connectTheDots(list1, color ="black"):
myTurtle = turtle.Turtle()
myTurtle.speed(1)
myTurtle.goto(list1[0])
for x,y in list1[1:]: #I'm unsure if this is correct
myTurtle.goto(x,y)
You have most of what you need but are probably making it more complicated than needed and are missing some small details.
For step "a" you need to explicitly set the color (you passed it in just fine). You are probably better off using a symbolic speed instead of a numeric one.
For step "b", if you have a proper for ... in loop, you don't need to explicitly check if the list is empty as the loop won't run if it is. Your splitting off the first item myTurtle.goto(list1[0]) works against you here as there may not be one, causing an IndexError.
For step "c" you need to add another command. Turtles start life in the center of the screen with their pens down. You need to raise the pen up after creating your turtle. But you don't need to explicitly move to the starting position, let your loop handle that.
The trick we'll use for step "c" and step "d" is to put the pen down after the goto() in the loop. The first time, this actually puts the pen down, after that, it's a harmless no-op:
import turtle
def connectTheDots(coordinates, color="black"):
myTurtle = turtle.Turtle()
myTurtle.speed("slowest")
myTurtle.color(color)
myTurtle.penup()
for coordinate in coordinates:
myTurtle.goto(coordinate)
myTurtle.pendown() # redundant after first iteration
dots = ((34, 56), (100, 240), (230, 105), (34, 56))
connectTheDots(dots, "green")
turtle.done()
If it bothers you that we're putting the pen down unnecessarily in the loop, then we can replace myTurtle.pendown() with:
if not myTurtle.isdown():
myTurtle.pendown()
I have 3 related questions for plots in spatstat:
How do I label the segment of a linnet. for example just the id of the element
How do I label co-variate attached to segment of linnet on a plot
How to control width of an segment of linnet in a plot based on: a covariate or for example I want the thickness of the segment proportional to number of points realized on that segment from a point process on a network. So if a process generates 10 points on a line segment and 5 points on second segment, I would like to plot first segment twice wider than second segment.
I found examples in the book - Spatial Point Patterns - but they indicate use of image or kernel density to control the width of a segment. I am using linfun for a inhomogenous process and I did not find a method to color or control line width in my plot or to label the plot.
An example of small square:
library(spatstat)
v<-ppp(x=c(50,100,100,50), y=c(50,50,100,100),c(0,150), c(0,150)) #vertices
edg<-matrix(c(1,2,3,4,2,3,4,1), ncol=2) #edges
L<-linnet(v, edges=edg) #create a linnet
z<-c(11,22,33,44) # create covariate
Zfun <- linfun(function(x,y,seg,tp) { seg }, L)
plot(Zfun)
# I added some marks
marks(x) <- runif(npoints(x), 3, 4)
Thank you
You can do everything by creating a suitable function of class linfun.
As an example, take the network L <- simplenet.
For question 1:
f <- linfun(function(x,y,seg,tp) { seg }, L)
plot(f)
The function f returns the segment ID number of the segment containing the specified point. This number runs from 1 to nsegments(L).
For question 2, suppose you have a vector Z giving the value of a covariate for each segment of the network (assuming the covariate value is constant on each segment). I'll take the example Z <- runif(nsegments(L)). Then
g <- linfun(function(x,y,seg,tp) { Z[seg] }, L)
plot(g)
For question 3,
plot(g, style="width")
See help(plot.linfun) and help(plot.linim) (basically plot.linfun converts the function to a pixel image, and then calls plot.linim).
I created a bar with display.newRect() and it's okey to create this rectangle by giving zero value to height parameter. Afterwards, I wrote increaseBar and decreaseBar functions. However, after increasing height, I tried to decrease it but height attribute of the object doesn't accept zero in assignment. Why is that?
I also checked with this simple code and same thing happens:
foo = display.newRect(200,100,30,50)
foo.height=0
It won't work with corona SDK. So, if you want to make the height to be zero, assign it to a value near zero.
eg:
foo.height = 0.001
or
foo.height = 0.01
Keep Coding....................... :)
I have a graph with zoom features. My main observation was that the x-axis updated its scale based on my current zoom level. I wanted the y-axis to do this too, so enabled zoom.y(y) , the undesired side affect being that now the user can zoom out in all directions, even into negative values "below" the graph.
http://jsfiddle.net/ericps/xJ3Ke/5/
var zoom = d3.behavior.zoom().scaleExtent([0.2, 5])
.on("zoom", draw); doesn't seem to really take the y-axis into account. And the user can still drag the chart anywhere in any direction to infinity.
One idea I thought of was independent of having zoom.y(y) enabled, and simply requires redrawing the y-axis based on what it is in the currently visible range. Like some kind of redraw based on the position of the X axis only. I don't want up and down scrolling at all now, only left and right
aside from commenting out //zoom.y(y) how would this be done? Insight appreciated.
All you need to do is update the y scale domain in your draw method.
The zoom function will modify the associated scales and set their domain to simulate a zoom. So you can get your x visible data bounds by doing x.invert(0) and x.invert(width), for example. If you converted your data to use Date's instead of strings then this is what I would suggest you use to filter, it woudl probably be more efficient.
As it is though, you can still use the x scale to filter to your visible data, find the y-axis extents of those values, and set your y scales domain to match accordingly. And in fact you can do all this in just a few lines (in your zoom update callback):
var yExtent = d3.extent(data.filter(function(d) {
var dt = x(d.date);
return dt > 0 && dt < width;
}), function(d) { return d.value; });
y.domain(yExtent).nice();
You can try it out here
To better explain what is going on:
The zoom behaviour listens to mouse events and modifies the range of the associated scales.
The scales are used by the axes which draw them as lines with ticks, and the scales are also used by the data associated with your paths and areas as you've set them up in callbacks.
So when the zoom changes it fires a callback and the basic method is what you had:
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
we redraw the x- and y- axes with the newly updated domains and we redraw (recompute) the area and the line - also with the newly domained x- and y- scales.
So to get the behaviour you wanted we take away the default zoom behaviour on the y scale and instead we will modify the y scales domain ourselves whenever we get a zoom or pan: conveniently we already have a callback for those actions because of the zoom behaviour.
The first step to compute our y scale's domain is to figure out which data values are visible. The x axis has been configured to output to a range of 0 to width and the zoom behaviour has updated the x scale's domain so that only a subset of the original domain outputs to this range. So we use the javascript array's filter method to pull out only those data objects whose mapping puts them in our visible range:
data.filter(function(d) {
var dt = x(d.date);
return dt > 0 && dt < width;
}
Then we use the handy d3 extent method to return the min and max values in an array. But because our array is all objects we need an accessor function so that the extents method has some numbers to actually compare (this is a common pattern in D3)
d3.extents(filteredData, function(d) { return d.value; });
So now we know the min and max values for all the data points that are drawn given our current x scale. The last bit is then just to set the y scale's domain and continue as normal!
y.domain(yExtent).nice();
The nice method I found in the api because it's the kind of thing you want a scale to do and d3 often does things for you that you want to do.
A great tutorial for figuring out some of this stuff is: http://alignedleft.com/tutorials/
It is worth stepping through even the parts you think you know already.
I have code that needs to render regions of my object differently depending on their location. I am trying to use a colour map to define these regions.
The problem is when I sample from my colour map, I get collisions. Ie, two regions with different colours in the colourmap get the same value returned from the sampler.
I've tried various formats of my colour map. I set the colours for each region to be "5" apart in each case;
Indexed colour
RGB, RGBA: region 1 will have RGB 5%,5%,5%. region 2 will have RGB 10%,10%,10% and so on.
HSV Greyscale: region 1 will have HSV 0,0,5%. region 2 will have HSV 0,0,10% and so on.
(Values selected in The Gimp)
The tex2D sampler returns a value [0..1].
[ I then intend to derive an int array index from region. Code to do with that is unrelated, so has been removed from the question ]
float region = tex2D(gColourmapSampler,In.UV).x;
Sampling the "5%" colour gave a "region" of 0.05098 in hlsl.
From this I assume the 5% represents 5/100*255, or 12.75, which is rounded to 13 when stored in the texture. (Reasoning: 0.05098 * 255 ~= 13)
By this logic, the 50% should be stored as 127.5.
Sampled, I get 0.50196 which implies it was stored as 128.
the 70% should be stored as 178.5.
Sampled, I get 0.698039, which implies it was stored as 178.
What rounding is going on here?
(127.5 becomes 128, 178.5 becomes 178 ?!)
Edit: OK,
http://en.wikipedia.org/wiki/Bankers_rounding#Round_half_to_even
Apparently this is "banker's rounding". I have no idea why this is being used, but it solves my problem. Apparently, it's a Gimp issue.
I am using Shader Model 2 and FX Composer. This is my sampler declaration;
//Colour map
texture gColourmapTexture <
string ResourceName = "Globe_Colourmap_Regions_Greyscale.png";
string ResourceType = "2D";
>;
sampler2D gColourmapSampler : register(s1) = sampler_state {
Texture = <gColourmapTexture>;
#if DIRECT3D_VERSION >= 0xa00
Filter = MIN_MAG_MIP_LINEAR;
#else /* DIRECT3D_VERSION < 0xa00 */
MinFilter = Linear;
MipFilter = Linear;
MagFilter = Linear;
#endif /* DIRECT3D_VERSION */
AddressU = Clamp;
AddressV = Clamp;
};
I never used HLSL, but I did use GLSL a while back (and I must admit it's terribly far in my head).
One issue I had with textures is that 0 is not the first pixel. 1 is not the second one. 0 is the edge of the texture and 1 is the right edge of the first pixel. The values get interpolated automatically and that can cause serious trouble if what you need is precision like when applying a lookup table rather than applying a normal texture. You need to aim for the middle of the pixel, so asking for [0.5,0.5], [1.5,0.5] rather than [0,0], [1, 0] and so on.
At least, that's the way it was in GLSL.
Beware: region in levels[region] is rounded down. When you see 5 % in your image editor, the actual value in the texture 8b representation is 5/100*255 = 12.75, which may be either 12 or 13. If it is 12, the rounding down will hit you. If you want rounding to nearest, you need to change this to levels[region+0.5].
Another similar thing (already written by Louis-Philippe) which might hit you is texture coordinates rounding rules. You always need to hit a spot in the texel so that you are not in between of two texels, otherwise the result is ill-defined (you may get any of two randomly) and some of your source texels may disapper while other duplicate. Those rules are different for bilinar and point sampling, you may need to add half of texel size when sampling to compensate for this.
GIMP uses banker's rounding. Apparently.
This threw out my code to derive region indicies.