
@nicola.palumbo has joined the channel

Ideally, I want to write @defproc[(flip-horiz [p painter?]) painter?]
. The problem is that painter?
is actually not a thing. Rather, a painter is an alias of a function that consumes a frame?
and produces a frame?
. What’s the best way to document this?
My options seem to be:
@defproc[(flip-horiz [p (-> frame? frame?)]) (-> frame? frame?)]
: I don’t like this. It’s super unreadable.@defproc[(flip-horiz [p procedure?]) procedure?]
: I also don’t like this as it’s very imprecise.(define painter? (-> frame? frame?))
and then documentpainter?
andflip-horiz
(in terms ofpainter?
).
Which is the best? And is there a better way?

I vaguely recalled something about -l
and user-scope packages, but had to check the raco exe
docs… Assuming that “rsound” is installed as a user-scope package, try --exf -U
as flags to raco exe
.

@sorawee Option 3 is probably best, but you should name it painter/c
instead of painter?
, since it is a higher-order contract and not a predicate. Another alternative is to @deftech
the word “painter” somewhere in your document and then use #, @tech{painter}
(or #,(tech "painter")
or IIRC @#,painter{tech}
) as the “contract” on the argument and result. But defining and documenting painter/c
is better.

Thanks!


sighs

I wish those questions had reasonable answers. But R7RS just specifies too little.

Part of the answer is #!r7rs
, right?

and another part of the answer is include

and a third part is “give up on portable scheme code”

@robby @stamourv the northwestern current snapshots are all broken links: https://plt.eecs.northwestern.edu/snapshots/current/

I don’t think @stamourv is involved in that.

ok, I wasn’t sure. Just ping Robby next time?

sure. I’m investigating

Looks like the rsync mysteriously failed last night.

No disks appear to be full.

from the sending side:

2019/03/18 16:34:34 [42315] rsync: connection unexpectedly closed (66896 bytes received so far) [sender]
2019/03/18 16:34:34 [42315] rsync error: unexplained error (code 255) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52/rsync/io.c(453) [sender=2.6.9]

it should be doing today’s rsync soon, so I guess the best course is to just let things go and check back in, in a few hours.

Northwestern is making a transition from being an EECS department to being two departments (CS and ECE) and so that might lead to things getting a bit wonky here and there.

Not sure if that’s what happened here, tho.

oh, it might actually still be a few hours. I see that today’s build hasn’t started the docs yet (altho yesterday’s started them at some point in the 7am hour (it is nearly 10am here))

If things go wrong again today, I’ll involve our tech staff (who run the machine that the rsync (that failed) connects to).

Thanks for letting mek now.

@samth R7RS doesn’t specify #!r7rs
, either, only R6RS specifies #!r6rs
.

damn

It’s hopeless.

ok, switching fully to my third thought

@ben, @robby: Indeed.

@fharvell has joined the channel

I started on a R7RS Large Red Edition package, but I don’t know if I have the patience of @lexi.lambda to deal with tech support for it.

Tech support for R7RS small is easy. The answer to almost every issue is “sorry, R7RS doesn’t specify that”. :)

Also if I wasn’t really going to use it the only point would be for 100% completion (and engineering challenge) sake.

Question about pict and bounding boxes and curves: I have the following function, that’s supposed to draw a filled dot, and an arrow coming down to the right and bending in to point to the left: (require (prefix-in p: pict))
(define (right-curve height)
(define rad 5)
(define dot (p:disk (* 2 rad) #:color "black" #:draw-border? #f))
(define tip (p:blank))
(define img (p:pin-over dot rad height tip))
(p:frame (p:panorama
(p:pin-arrow-line (* 2 rad) img dot p:cc-find tip p:cc-find
#:start-angle (* pi 7/4) #:end-angle pi
#:color "red"))))
(right-curve 50)
When I run this code in DrR, though, the resulting image (a) takes up twice as much height at the repl as the frame itself does, and (b) the frame is cropped in tightly to the disk and the arrowhead, but the curve is clipped, despite calling panorama
to enlarge the bounding box. I’m not too concerned about the REPL weirdness (unless it causes the picture to behave badly in scribble later, but that’s a problem for later). But is there any way for me to ensure that the bounding box of the pict is automatically enlarged to include the curvy line? Or failing that, is there an alternative to pin-arrow-line
that gives me bezier curves and arrowheads?

I’ve found the metapict/bez
library, which intrigues me, but I’d love it if I didn’t have to compute the control points myself :wink:

You can use curve
from MetaPict to compute the control points.

Example: (curve p1 .. p2 .. pt3 .. pt4) will draw a “nice” curve through the points.

replace one of the .. with — to get a straight line between two of the points.

If the curve needs to enter or leave a point in a particular direction, you can do:

(curve direction-to-enter p1 direction-to-leave .. p2 …)

The enter and leave directions are optional everywhere.

what’s the syntax for directions? are they angles (deg or rad), or keywords, or…?

The directions are represented as vectors using a vec
structure.

E.g. (vec 1 0) will be the east direction.

ah, ok, cool

up left right down are predefined

There is also a function that takes a number of degrees and return a unit vector in that direction.

I don’t understand why panorama
isn’t taking the line into account

my guess is that the line isn’t actually represented as a sub-pict

but that behavior seems like a bug

@samth, is the code snippet I have above producing the same clipping output for you?

yes

if you just have one particular image, you can fix it with inset

but in general this seems not-good

looking at pict-lib/pict/private/main.rkt pin-curve*
, seems like it’s just building a dc-path%
and directly sending move-to
and curve-to
messages

doesn’t seem like there’s a pict
structure being created for the curve itself

@soegaard2 so that gets me part of the way there… looks like metapict will give me picts, so that’s relatively easy to compose with other picts. last bit of the puzzle: how do I draw arrowheads of a given size, and how do I shorten the bezier curve to give room for the arrowhead at the end of it?

yeah that was my guess

#lang racket
(require metapict)
(define p (pt 0 1))
(define q (pt 0 0))
(draw (fill (circle p 0.1))
(color "red"
(draw-arrow (curve p .. left q))))

The function draw-arrow
will draw the curve with an arrow in the end.

Does draw-arrow
produce a pict that I can combine with other picts? And, can I customize the arrowhead itself?

(Looking at the metapict docs, but most of the links are broken/incomplete, so I haven’t figured it out yet myself)

Yes. draw-arrow returns a pict.


for different arrow heads and the parameters that can be tweaked.

And I agree - the documentation is not done.

no worries — thanks for the help so far :slightly_smiling_face:

The idea is that the settings are done using the parameters beginning at line 24.

Normally I don’t need to change anything but the arrow head length using ahlength.

Well - if you only need to change the settings for a single arrow, than use the keywords. See line 161.

cool, ok. when using draw-arrow
, does it place the arrow so that the tip of the arrowhead is the anchor point of the curve, or the inner notch is? (IIRC, in tikz, you can control this because, naturally, everything is tweakable in tikz…and I don’t remember what the defaults were)

It places the arrow head on the anchor point (not the notch).

yay :slightly_smiling_face:

Also … If you curve is say a circle, you can get your arrow head to “bend”. (I think - I can’t remember if I changed my mind)

Oh. And if you just need to the bezier control points, then just use curve
which basically is a struct holding a list of bez
structures.

well, with only the control points, I won’t get the right bounding box (unless I compute it myself…) I’m hoping that curve
implicitly gets it right for me, because of subdivision

Is there a way to avoid using the window
as my bounding box, and pick whatever is tightest on the actual drawing?

(i.e. the equivalent of panorama?)

looks up panaroma


I haven’t anything built-in. But I think it ought to be doable.

I have a bez-large-bounding-box
which computes an approximate (may be too large) bounding box.

And sfont has a bezier-bounding-box which could be used.

Also a dc-path has a (send a-dc-path get-bounding-box) method.

Hello, all: I’m currently writing an indentation checker for teaching language files. I’d like to be able to take a file, run the DrRacket autoindenter on it, then diff the files, but I don’t think I can invoke that functionality in a convenient way. My alternate strategy is to read through the syntax objects, and calculate what the expected indentation(s) should be. Unfortunately, I can’t find how many lines a syntax object spans in a nice way. Anyone have advice?

@justin.hu to figure out the lines spanned, you need to look at the syntax-span
and then see if there are newlines in the actual bytes

which I agree doesn’t seem nice

Drat…. Anyone know how to invoke the DrRacket indenter?

You ought to be able to run the indenter automatically, but I don’t know how easily


@blerner The sfont code does compute the proper bounding box for a Bezier curve. So given a curve (a list of Bezier curves) we need to compute the bounding box for each and then combine them.

But this gives the bounding box in virtual coordinates. When the curve is drawn the pen size etc will affect the real bounding box.

I am not sure how to deal with that.

worst case, just inflate the box by half the pen width? (That’s ignoring pen-cap details, but I’m ok with that for now)

@justin.hu here: #lang racket
(require framework)
(define (indent s)
(define t (new racket:text%))
(send t insert s)
(send t tabify-all)
(send t get-text))
(indent "(lambda (x)\nx)")

Thanks.

@blerner Yeah - ought to work.

But it will still result in a bounding box for a single curve only.

The draw
operation simply draws stuff on top of a pict.

Or rather it constructs a pict.

So … maybe panorama works on the result?

Nope. Wishfull thinking.

MetaPict of course sets the bounding box - so panorama doesn’t have a chance.

well, but then you can cheat, and say (inset (inset the-metapict (- the-pict-bounding-box) ...) the-metapict-bounding-box ...)
, so that maybe you can force the bounding box to be what you want, so that panorama gets the right info?

I’m fine with producing a floating pict that I need to combine with an existing pict myself

@samth is there a pict function that’s the opposite of ghost
, that says “draw this pict but pretend it has a zero-size bbox”?

@blerner a cheap-trick ive used for that before:
(let ([x (blank)])
(refocus (ht-append x the-pict) x))

hehe

that makes total sense

I was going to suggest inset
with negative values, but that’s better.

@mflatt any thoughts on the issue of lines and panorama that @blerner has?

No ideas. As you’ve worked out, pin-arrow-line
doesn’t add information that panorama
can use.

Today’s build worked :)

@soegaard2 I gotta step away from the computer for a little while, but istm that https://docs.racket-lang.org/metapict/index.html?q=metapict#%28part._ref-draw-and-fill%29 doesn’t quite play nicely with the rest of the pict ecosystem. Instead of using curve-pict-width
and curve-pict-height
parameters, I think you can compute the correct bbox of the curve, in logical coordinates, and add onto it any decorations like arrowheads. Then things like panorama
and inset
and clip
will all behave “the same way” as they do on other picts.

In my case, since I happen to know something algebraic about the control points of my curve, I can figure out that (point-at c 0.5)
is an extremal point of the curve, so I can figure out my bounding box for now on my own. But because draw-arrow
doesn’t actually add a pict for the arrowhead, it gets clipped away… fortunately, that won’t matter for my overall image, but in general, it’s slightly awkward.

ooooo fun, I got racket
to segfault

oh, one of the libraries I’m using is doing unsafe stuff internally.

that’s less exciting.

is there a way to get scribble to spit out SVGs instead of PNGs?

oh, duh. --help

Another question about picts: Suppose I just use the standard (arrowhead 10 0)
pict. I get an arrowhead, no biggie. If I frame
it, I get a tightly fitting box. If I use @florence’s trick above (using cc-superimpose
instead, to get things centered), and say (frame (smash (arrowhead 10 0)))
, I get an empty pict: pict-width
returns 0. If I try to rotate it, though, things go wrong. Specifically, if I try (pict-width (panorama (smash (rotate (arrowhead 10 0) pi))))
, I get a width of 20. Huh? Without the rotate, I get a width of 10 as expected…

Pict bounding boxes are rectangles. So if you rotate by 45 degrees (that’s what pi is right? I never remember…) the width should be the length of the diagonal, not the length of the side

pi is 180 degrees

Oh…whelp back to basic trig for me

(also, if it were 45 degrees, I’d wind up with a width of 10*sqrt(2) = 14.1… :wink: )

(fwiw I can trigger this without smash, just using panorama and rotate)

ok, so that’s a useful simplification.

OK, that worked!