![]() |
Rick's b.log - 2023/01/20 |
It is the 10th of April 2025 You are 3.134.117.239, pleased to meet you! |
|
mailto:
blog -at- heyrick -dot- eu
Well, not chaos. There was work to do, and I had to train some of the others in what I do so they can replace me if I'm away. I think the idea is that we all know each other's jobs so we can mix and match as appropriate.
But for somebody used to having a very definitive schedule, it was chaos.
I was summoned to have a discussion with my boss on Thursday - a week on the flip side of the event horizon.
I get the impression that this all happened above her, and quite likely for exactly the reason I think.
I've asked that other committee members (who are more on my side here) don't agitate anything right now. I am, obviously, somewhat miffed at how it all went down, but it has and that's that. Let's see how this all plays out.
Remember that I believe in the concept of things happening for a reason? I'll be buggered if I know (or can think of) the reason for this change, but like I said, let's see how it goes.
As for the week? I hurt. Doing the industrial washing up is exercising a whole different set of muscles to wiping tables and scrubbing toilets. But this is to be expected. I will, however, have to stop trying to pick up a dozen baking trays at once. It was no big deal when I started here and was 35. I'm less than a year to half a decade of crustiness, and I'm really not up to flexing like that.
Until I got to the roundabout in the town before work. If you've been watching my videos, it's the one where the van tried to cut in front of me.
I was doing something like 15kph, because I like to go around the roundabout properly rather than driving over it like everybody else.
That's when it became clear that my back end was swinging around faster than the front.
So... in a toy car doing a speed barely faster than a run, I drifted a tiny roundabout.
Feel free to laugh.
I didn't hit anything, and it was over before I had any time to even think about how to respond. The car behind me, however, saw this and slammed on the brakes. And, yeah, that didn't quite go as planned.
He/she didn't hit anything either, but had to reverse and slowly turn to be heading in the right direction.
The road from that roundabout to the big one before the supermarket, maybe a kilometre or so? Total skating rink. I could feel the car shuddering as the wheels made and unmade contact. As it was a straight line, we (myself and the car behind) did it at about 25. It was a 50 zone.
As I came to the big roundabout, a jam sandwich went whizzing by, blues flashing but no siren. I'm guessing somebody had a worse morning than the two of us.
It's supposed to be subzero in the morning until Wednesday, but there's no rain forecast so hopefully the moments of sun will keep things dry so there's no more ice.
Then it's supposed to be a high of 14 for two days, which seems like either an anomaly or an apology.
I wasn't going to be around to deal with this, so I went to the La Poste website, and elected to pay the import duties on-line.
€5.
This was broken down as €3 for the actual import duty (20% of the cost of the item plus shipping, rounded up to a whole euro amount), plus a fee of €2 for "handling".
First of all, what the actual hell are they doing applying tax to the shipping charge?
But secondly, and more importantly, why did my post person quote me €11? The website itself made it quite clear that by paying on-line, I would economise €6. And I did.
But, wait, this amount is set by and paid to the government. It's import duty, with a small handling charge added on top. So what justifies trying to charge more than double if I don't do it on-line?
The rule is clear. If the postperson comes along with a parcel with import duty, to say no - keep it, I'll pay the duty on-line, you can bring it out in a couple of days.
Which is absolutely ridiculous.
Anyway, nothing came on Wednesday. I left a message for the postie to say that the tax had been paid. She left me a message to say she had spoken to her boss and she thinks I made an error as it was for €11, not €5, and as such the duty hasn't been marked as paid.
As it turns out, the duty was marked as unpaid because it took until 1pm the following day for it to be processed. What, is it done by hand?
My postie left her mobile number, so I sent a few text messages for a discussion that was increasingly surreal. Eventually I took a photo of the note that had the phone number and sent that by MMS.
The reply... I was speaking to somebody completely different at the other end of the country. My postie had written her number down incorrectly.
I apologised profusely, and the woman I was talking to said she hopes I get it sorted - import duty is a nightmare.
I wasn't expecting it on Thursday. I mean, everybody was on strike, right?
It arrived Thursday.
I had ordered something else, from the UK this time. There was no import duty as the item had already been taxed and it was a reciprocal agreement, which I guess Canada doesn't have.
It left somewhere near Leeds, went to Hinkley (as in, the nuclear reactor in Somerset?), then to Paris, then to Rennes, and finally out to me. It took three days. Pretty impressed by the speed of that.
Anyway, I went to the track and trace and it said that my only options were to have it delivered or to pick it up from the depot in Rennes. I couldn't ask for it to be left at my local supermarket.
I ticked a box to give permission for the parcel to be left, and to be left without signature and that I'd accept the risk of that.
The driver allegedly passed, discovered I wasn't home, and didn't deliver the parcel as I was absent.
Thankfully he didn't take it back to the depot. He left it at a supermarket in a town twenty miles away. The place it was left is, actually, our "sub-head" town because... it's complicated and the French are very territorial. But it's bloody annoying because if I look to have Amazon leave anything at a pickup point, they suggest this place because of how French administration works, and don't ever offer to leave parcels in the closer town where I work because... FFS.
Anyway, there would be a receipt. I say allegedly because I went home to pick up the little slip that was left in the letterbox... except there was no slip. So I'm not sure whether the driver even bothered to turn up, or just looked at the long driveway and thought "sod this" and marked me as being absent.
I went to the supermarket anyway (a journey twice as long as cutting across directly from work) and handed over my (French) ID card. Well, Residency Permit. It had my name, address, and an up to date photo to demonstrate that the government attests that the lifeform standing in front of the person is supposed to be wandering around.
Thankfully the person at the service desk looked it up by address and went and fetched it. Nothing to sign, only scan the code and call it delivered.
So the rule is clear. Just don't order stuff from overseas.
Which, knowing how protectionist the government can be, is probably exactly the intended idea. Pffft.
With a known count of 48 rapes, he's one of the worst sex offenders in modern British history. All the more egregious that he was a serving officer of the Met, which led others (police and prosecutors) to tell the woman that claims like this against a police officer wouldn't be believed. Especially as he threatened to plant drugs in one person's car, with a "who are they going to believe?" question.
He's going to be sentenced, and may well go behind bars for a long time. Really, six foot deep is where he belongs.
However the continual rancid stories about the Met suggests that perhaps the best idea is to disband it completely and rebuild it from the beginning with an entirely new workforce taken from around the country. Former Met officers can move to other police positions, and hopefully it'll break up any comraderie as well as shaking out the bad people (of which there may be over a thousand).
There is something horribly broken within the Met, and it looks like either Cressida Dick was complicit or sleepwalking through the job.
Either way, when an entire gender has justifiable reason to fear the police, pathetic platitudes won't cut it. Time to rip and retry.
I gave you code for rotating the vectors to any arbitrary angle. So it wasn't hard to plug this into the program to actually do this according to the keys pressed, which provides rotation. We move 0.05 radians, which is about 2.8°.
Then to check the location of a map reference with an offset added, and if it's an empty tile, to do the move. This provides forward and backward movement.
There is no attempt at throttling or maintaining a steady rate of movement. It's just the bare bones to have a map that you can actually move around in.
Five versions of the program are provided in the archive. Listed in order of effective speed (as I wandered around the map):
|
† - built from a source that uses ColourTrans_SetGCOL to set the colours as ABC still doesn't support the GCOL r,g,b form.
Now, all you're missing is the programs (Zip, 16,442 bytes).
I'm just going to dump the entire commented source here. The changes are described, and shouldn't be too hard to work out. Though, I would imagine this might just be a step too far for a BBC Master version. ☺
REM >raycast2 REM REM Rick's simple ray-caster, version 2 REM * Added movement (rotation and foreward/backward) REM REM https://heyrick.eu/blog/index.php?diary=20230120 REM REM Basic demonstration of principle REM REM The principle is as described by Lode Vandevenne at REM https://lodev.org/cgtutor/raycasting.html REM REM What's worth noting here is that we do *NOT* REM work in degrees like a normal ray-caster, so REM the code that follows is rather more compact REM than you may see in other places, but it does REM require competent floating point maths support. REM ON ERROR PROCerror REM 640x480 in 256 colours; it's VGA so REM everything ought to support this. MODE 28 REM The physical size of the screen width% = 640 height% = 480 REM Set up triple buffering SYS "XOS_ReadModeVariable", -1, 7 TO ,, scrsize% scrwant% = scrsize% * 3 SYS "XOS_ReadDynamicArea", 2 TO , scrcurr% screxpa% = scrwant% - scrcurr% : REM How much to enlarge by IF ( screxpa% > 0 ) THEN SYS "XOS_ChangeDynamicArea", 2, screxpa% TO ; f% IF (f% AND 1) THEN ERROR 123, "Not enough screen memory" ENDIF REM Set up other screen stuff SYS "Hourglass_Smash" MOUSE OFF SYS "OS_RemoveCursors" SYS "OS_Byte", 114, 0 : REM Shadow modes bank% = 1 PROCswitchbank REM The size of the 2D map REM Let's keep it simple for now mapx% = 16 mapy% = 8 DIM map%(mapx%, mapy%) FOR loopy% = 7 TO 0 STEP -1 FOR loopx% = 0 TO 15 READ map%(loopx%, loopy%) NEXT NEXT REM 0 = Empty REM 1 = Red square REM 2 = Green square REM 3 = Blue square DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 DATA 1,0,0,0,3,3,0,0,0,0,0,0,0,0,0,1 DATA 1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,3,0,0,0,1,0,2,0,0,0,0,1 DATA 1,0,3,0,0,0,3,0,1,0,0,0,0,0,0,1 DATA 1,0,0,0,2,0,0,0,0,0,3,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 DATA 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 REM /|\ REM | REM Viewer is here, fourth row up. looking to the LEFT. REM Note that as of now, it's lots of floating point maths REM Where in the map does the viewer start? ourx = 14 oury = 4 REM Looking to the left xdir = -1 ydir = 0 REM The projection plane, in 2D REM This MUST be perpendicular to the direction. xproj = 0 yproj = 0.65 REM yproj being 0.65 above corresponds to a field of view of REM about 65 degrees, which is a good value for a old style REM squarish screen, such as the VGA mode used here. REM If using a 16:9 display, you'll need a wider field of view REM because of the extra width. Try 0.85 which equals a field of REM view of about 80 degrees. REM REM To convert the above value into degrees for a viewing angle: REM value = 0.65 REM PRINT ((ATN(value / 1) * 2) / PI) * 180 REM (this converts the value into radians, and then into degrees) REM REM A loop to repeatedly draw according to defined location and angle timeout% = TIME + 100 fcnt% = 0 fps% = 0 WHILE TRUE PROCswitchbank CLS REM Draw the floor GCOL 48, 48, 48 : REM Dark grey RECTANGLE FILL 0, 0, (width% << 1), height% REM And now the ceiling GCOL 98, 98, 98 : REM Lighter grey RECTANGLE FILL 0, height%, (width% << 1), height% REM Now, cast rays for each scrcol across the screen, starting from the left. FOR scrcol% = 0 TO (width% - 1) REM Let's do the easy inits first. REM For now, let's look to see what map location we are in. mapx% = ourx mapy% = oury REM We use an integer here in order to lose the fractional part, REM as in this case we don't care how far along in any position REM the viewer is, only which block matches where the viewer is. REM These two values represent the distance from our current REM (exact) location to the next square boundary. This is REM updated as we step along. xedge = 0 yedge = 0 REM The step values are -1 if it's a negative step, or 1 if it's a REM positive step. Initially zero as the stepping hasn't been set up. xstep% = 0 ystep% = 0 REM Has a wall been hit? wallhit% = FALSE REM Which side was hit? FALSE for an X side, TRUE for a Y side side% = 0 REM This will be the distance to the actual wall that we're going REM to draw on the screen. towall = 0 REM Now for the freaky maths REM Calculate our angle offset for the desired screen column. REM This goes from -1 on the left, to 0 in the middle, to 1 on the right. angle = (2.0 * (scrcol% / width%)) - 1 REM Now set up two rays. Remember when we are talking about X and Y REM we are talking about the GRID that represents the array that our REM map is in. It isn't X,Y on the screen, or in some 3D space, it REM is the imaginary X,Y divisions between array elements. REM Or, to put it more simply, imagine that you have written the REM contents map% on a piece of squared paper like you used in maths REM class. The horizontal lines are your X positions, and the vertical REM lines are your Y positions. xray = xdir + (xproj * angle) yray = ydir + (yproj * angle) REM Now we work out how far we must step from one square edge to REM the next. Since the rays travel in a straight line, we only REM need to calculate this once. IF (xray <> 0) THEN xdelta = ABS(1 / xray) ELSE xdelta = 12345678 IF (yray <> 0) THEN ydelta = ABS(1 / yray) ELSE ydelta = 12345678 REM To explain the above a little better, the actual calculation REM would be: REM xdelta = SQR(1 + (yray * yray) / (xray * xray)) REM but because we already did some of this calculation when sorting REM out xray/Y above, and we're only interested in the RATIO REM between the X and the Y, all of this can be simplified down to REM simply dividing 1 by the ray distance. REM Now we work out which stepping to use, and our initial distance REM to the edge of the current square. IF ( xray < 0 ) THEN REM We're moving leftwards in the map xstep% = -1 xdist = ( ourx - mapx% ) * xdelta ELSE REM We're moving rightwards in the map xstep% = 1 xdist = ( (mapx% + 1) - ourx ) * xdelta ENDIF IF ( yray < 0 ) THEN REM We're moving downwards in the map ystep% = -1 ydist = ( oury - mapy% ) * ydelta ELSE REM We're moving upwards in the map ystep% = 1 ydist = ( (mapy% + 1) - oury ) * ydelta ENDIF REM Now look for a wall WHILE ( wallhit% = FALSE ) IF ( xdist < ydist ) THEN REM The next X boundary is closer, so let's step to it mapx% += xstep% xdist += xdelta side% = FALSE ELSE REM The next Y boundary is closer, so let's step to it mapy% += ystep% ydist += ydelta side% = TRUE ENDIF REM Was something hit? IF ( map%(mapx%, mapy%) <> 0 ) THEN wallhit% = TRUE ENDWHILE REM Do you see how the two rays worked here? They are both REM being cast together at the same time, and we're simply REM stepping to look at whichever happens to be the closest. REM Now that we know that something has been hit, we can work REM out the wall distance. This is easy, we simply subtract the REM delta that we stepped over from the accumulated distance to REM the next side. IF side% = FALSE THEN REM It's an X boundary towall = xdist - xdelta ELSE REM It's a Y boundary towall = ydist - ydelta ENDIF IF (towall = 0) THEN towall = 1 REM Now we have the wall distance, work out how big this line should be drawsize% = height% / towall REM Now work out the lowest and highest pixel to actually draw on REM the screen; clipping it if it goes off the screen. drawbot% = (-drawsize% / 2) + (height% / 2) IF ( drawbot% < 0 ) THEN drawbot% = 0 drawtop% = ( drawsize% / 2) + (height% / 2) IF ( drawtop% >= height% ) THEN drawtop% = ( height% - 1) REM Now work out what colours we want col% = 127 IF (side% = FALSE) THEN col% += 128 CASE map%(mapx%, mapy%) OF WHEN 1 : GCOL col%, 0, 0 : REM Red WHEN 2 : GCOL 0, col%, 0 : REM Green WHEN 3 : GCOL 0, 0, col% : REM Blue ENDCASE REM And, finally, draw the line, with correction between REM OS units and pixels for MODE 28. MOVE (scrcol% << 1), (drawbot% << 1) DRAW (scrcol% << 1), (drawtop% << 1) NEXT REM FPS tracking fcnt% += 1 IF ( TIME >= timeout% ) THEN timeout% = TIME + 100 fps% = fcnt% fcnt% = 0 ENDIF REM A screen has been drawn, so now handle keypresses REM Esc . . . . . . . Quit ;) REM Left / Right . . . Rotate REM Up . . . . . . . . Forwards REM Down . . . . . . . Backwards REM F . . . . . . . . Show FPS REM S . . . . . . . . Screenshot REM LEFT or RIGHT IF ( FNkey(25) ) OR ( FNkey(121) ) THEN IF FNkey(25) THEN rot = 0.05 ELSE rot = -0.05 oldx = xdir xdir = (xdir * COS(rot)) - (ydir * SIN(rot)) ydir = (oldx * SIN(rot)) + (ydir * COS(rot)) oldx = xproj xproj = (xproj * COS(rot)) - (yproj * SIN(rot)) yproj = (oldx * SIN(rot)) + (yproj * COS(rot)) ENDIF REM UP IF ( FNkey(57) ) THEN IF ( map%(ourx + (xdir * 0.1), oury) = 0 ) THEN ourx += xdir * 0.1 IF ( map%(ourx, oury + (ydir * 0.1)) = 0 ) THEN oury += ydir * 0.1 ENDIF REM Down IF ( FNkey(41) ) THEN IF ( map%(ourx - (xdir * 0.1), oury) = 0 ) THEN ourx -= xdir * 0.1 IF ( map%(ourx, oury - (ydir * 0.1)) = 0 ) THEN oury -= ydir * 0.1 ENDIF REM F(PS) IF ( FNkey(67) ) THEN PRINTTAB(0,0);STR$(fps%)+" fps" ENDIF REM S for a Screenshot IF ( FNkey(81) ) THEN OSCLI("ScreenSave $._3dscene"+MID$(TIME$,17,2)+MID$(TIME$,20,2)+MID$(TIME$,23,2)) ENDIF ENDWHILE END : DEFPROCerror REM If we abort with shadow modes set up, RISC OS will poop its nappy REM So this restores the screen state back to what it was on entry VDU 4 PROCdrawbank(0) PROCshowbank(0) SYS "OS_Byte", 114, 1 : REM Non-shadow SYS "ColourTrans_SetTextColour", &00000000, (1<<7) : REM Background SYS "ColourTrans_SetTextColour", &FFFFFF00, 0 : REM Foreground PRINTTAB(0,0);REPORT$+" at "+STR$(ERL) END ENDPROC : DEFPROCdrawbank(w%) REM What screen bank are we drawing to? SYS "XOS_Byte", 112, w% ENDPROC : DEFPROCshowbank(w%) REM What screen bank is the user looking at? SYS "XOS_Byte", 113, w% ENDPROC : DEFPROCswitchbank REM Furtle with the screen banks WAIT PROCshowbank(bank%) bank% = (bank% MOD 3) + 1 PROCdrawbank(bank%) ENDPROC : DEFFNkey(k%) REM Returns TRUE if the nominated key is pressed, else FALSE SYS "OS_Byte", 121, (k% EOR &80) TO , r% IF r% = &FF THEN =TRUE =FALSE
Have fun!
By the way - If you're trying this and wondering why it suddenly speeds up when there are lots of boxes on-screen (which is sort of the opposite to what you'd expect), fridge brilliance is that it's because there's actually less needing to step through the rays before we register a hit, so the code is doing less work the more boxes are on screen.
No comments yet...
© 2023 Rick Murray |
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted. RIPA notice: No consent is given for interception of page transmission. |