Draw an arrow in racket - scheme

How to draw an arrow in a frame in racket (DrRacket)? For example between two objects: a circle and a rectangle obtained by:
(send dc draw-ellipse 50 50 30 30) and (send dc draw-rectangle 200 200 30 6)

You can use picts to do such things.
First, you define your picts.
(define pict-a (rectangle 40 40))
(define pict-b (circle 40))
Then you combine them to be able to use rc-find or lc-find, which are the procedures that will help you connect those picts.
(define combined (hc-append 200 pict-a pict-b))
Finally
> (pin-arrows-line 30 combined
pict-a rc-find
pict-b lc-find
#:start-angle (/ pi 11)
#:end-angle (- (/ pi 11))
#:solid? #f)
Will produce this:
You can find more information in the docs! Tell us if that solved your problem!

What kind of arrows?
For simple arrows use draw-line directly.
For bended arrows use draw-spline.
Use a filled triangle as a simple arrow head.
If you need a prettier arrow head shape,
one option is to adapt the arrow shape from MetaPict.
You can find other examples of arrows in MetaPict's documentation.
An example with a non-straight arrow which shows how to draw a state machine with MetaPict.

Related

How to set frame's background in Racket?

How to set frame's background in Racket? I want to change the background color of a window (for usability purposes) while still being able to place other controls in that window (and keep them fully functional).
Currently I don't see a possibility for this. I tried adding a canvas and changing its background color (which works for the canvas itself), but the canvas pushes out other controls due to the GUI toolkit's geometry management.
It would be nice also to have a way to change colors of other controls (buttons, etc.).
I didn't find anything for frame, but color of button, check-box or message can be changed, if you use bitmap in field label in their constructor. You can use some image from your PC or create that bitmap programmatically:
(require racket/gui/base)
(define frame (new frame%
(label "Example")
(width 500)
(height 500)))
(define button-bg (make-object bitmap% 100 50))
(define dc (new bitmap-dc% (bitmap button-bg)))
(send dc set-brush "green" 'solid)
(send dc set-pen "black" 3 'solid)
(send dc draw-rectangle 0 0 100 50)
(send dc draw-text "Click Me!" 20 0)
(define b (new button%
(parent frame)
(label button-bg)))
(send frame show #t)
The GUI is cross platform - and some platforms do not support changing the background color.
https://lists.racket-lang.org/users/archive/2012-February/050626.html

Racket GUI, drawing text vertically, issues with "angle" argument

I'm using the Racket GUI to write text in the window of my program.
Until now I only needed to draw text horizontally. But now I would also want to write text vertically. I saw in the documentation we can give an "angle" argument when we send the message "draw-text" to the drawing context.
Here's my little function to draw text :
(define (draw-text text fontsize x y color [rotate-angle 0.0])
(when (string? color)
(set! color (send the-color-database find-color color)))
(send bitmap-dc set-font (make-object font% fontsize 'default))
(send bitmap-dc set-text-foreground color)
(send bitmap-dc draw-text text x y [angle rotate-angle])
(update-callback))
But when I call the "draw-text" procedure with example given an angle of 90° (so that the text would be vertically) it doesn't change anything.
It's just displayed as before, horizontally.
Does someone know what's wrong?
It's not clear from the example, but did you remember to convert the 90 degrees into radians? The convention is that 360 degrees is the same as 2pi radians. Or dividing by 360, we get that 1 degree is 2pi/360 radians.
Multiplying by 90, the result is that 90 degrees is 90*2*pi/360 = 180pi/260 = pi/2 ~ 1.5707963267948966. That is, to rotate the text 90 degrees, use 1.5707963267948966 as the rotate-angle.
Also (send bitmap-dc draw-text text x y [angle rotate-angle])
should be
(send bitmap-dc draw-text text x y combine? offset? angle])
For example:
(send bitmap-dc draw-text "A text" 100 100 #t 0 1.570])

Stuck in AutoLISP using polar

Well I'm sort of stuck and don't know what to do. I need to write program using AutoLisp, which would draw five-pointed star. I don't have any knowledge in AutoLisp programming, but managed to write this and it seems to me, correct, but AutoCAD won't draw anything. Maybe someone could help? (long numbers are angles in radian)
Code:
(defun C:Figura3 ()
(setq pl (getpoint "\nStart coordinate: ")) ;;; Coordinates of circle center
(setq aukst (getint "\nRadius: "))
;;; Coordinates of vertices
(setq p2 (polar p1 1.570796327 aukst)) ;;; 90 (degrees)
(setq p3 (polar p1 2.827433388 aukst)) ;;; 162
(setq p4 (polar p1 4.08407045 aukst)) ;;; 234
(setq p5 (polar p1 5.340707511 aukst)) ;;; 306
(setq p6 (polar p1 0.3141592654 aukst)) ;;; 18
;;; Drawing
(command "color" "white")
(command "lweight" 0.35)
(command "circle" p1 aukst)
(command "line" p2 p4 p6 p3 p5 p2 "")
)
You've defined the command 'Figura3', however you'll need to actually call it as well for it to do any work. Type Figura3 at the command prompt after you load/type your function definition and AutoCAD will run your function like you'd expect.
There's also an issue with your first point though. It's defined as 'pl' (lowercase 'L') and later referenced as 'p1'.

openGL Texture masking

I am attempting to fill a circle with a series of other images and have those images masked off by the circle. I can see why this isn't working, but I can't come up with a solution as to how to fix it.
My drawing code (using processing) is as follows:
PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; // g may change
// This fixes the overlap issue
gl.glDisable(GL.GL_DEPTH_TEST);
// Turn on the blend mode
gl.glEnable(GL.GL_BLEND);
// Define the blend mode
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
// draw the backgroud
fill(200,200,200);
rect(0, 0, width, height);
// cut out the circle
gl.glBlendFunc(GL.GL_ZERO, GL.GL_ONE_MINUS_SRC_ALPHA);
tint(0,0,0,255);
image(circle, 0, 0);
// draw the circle
gl.glBlendFunc(GL.GL_ONE_MINUS_DST_ALPHA, GL.GL_ONE);
tint(140,0,0,255);
image(circle, 0, 100);
gl.glBlendFunc(GL.GL_ONE_MINUS_DST_ALPHA, GL.GL_ONE);
tint(140,0,140,255);
image(circle, 0, 0);
I have been following the directions at http://bigbucketsoftware.com/2010/10/04/how-to-blend-an-8-bit-slide-to-unlock-widget/ which seem to describe the effect that I want. I have also tried this on iphone with similar results.
Here is what I was expecting to happen, and what happened:
The problem must be with how you treat the transparent region. You could enable GL_ALPHA_TEST.
Or if your pictures stay that simple you can just draw them with triangles.
I can't really help you with the blending code but I have another suggestion that might simplify your drawing logic.
I have used the stencil buffer for something like that. I wanted to draw a disk textured with a linear grating. I didn't want to bother with texture coordinates because an important function was to be able to exactly step through the phases of the grating.
I drew the texture in a big rectangle and afterwards I drew in the stencil a white disk.
http://www.swiftless.com/tutorials/opengl/basic_reflection.html
(let ((cnt 0d0))
(defmethod display ((w window))
;; the complex number z represents amplitude and direction
;; of the grating constant
;; r and psi addresses different points in the back focal plane
;; r=0 will result in z=w0. the system is aligned to illuminate
;; the center of the back focal plane for z=w0.
(let* ((w0 (* 540d0 (exp (complex 0d0 (/ pi 4d0)))))
(r 260d0)
(psi 270d0)
(w (* r (exp (complex 0d0 (* psi (/ pi 180d0))))))
(z (+ w w0)))
(clear-stencil 0)
(clear :color-buffer-bit :stencil-buffer-bit)
(load-identity)
;; http://www.swiftless.com/tutorials/
;; opengl/basic_reflection.html
;; use stencil buffer to cut a disk out of the grating
(color-mask :false :false :false :false)
(depth-mask :false)
(enable :stencil-test)
(stencil-func :always 1 #xffffff)
(stencil-op :replace :replace :replace)
(draw-disk 100d0 (* .5d0 1920) (* .5d0 1080))
;; center on camera 549,365
;; 400 pixels on lcos = 276 pixels on camera (with binning 2)
(color-mask :true :true :true :true)
(depth-mask :false)
(stencil-func :equal 1 #xffffff)
(stencil-op :keep :keep :keep)
;; draw the grating
(disable :depth-test)
(with-pushed-matrix
(translate (* .5 1920) (* .5 1080) 0)
(rotate (* (phase z) 180d0 (/ pi)) 0 0 1)
(translate (* -.5 1920) (* -.5 1080) 0)
(draw *bild*))
(disable :stencil-test)
(enable :depth-test)
(fill-grating *grating* (abs z))
(format t "~a~%" cnt)
(if (< cnt 360d0)
(incf cnt 30d0)
(setf cnt 0d0))
(update *bild*)
(swap-buffers)
(sleep (/ 1d0)) ;; 1 frame per second
(post-redisplay))))

GUI elements in (Dr) Racket

I need some basic stuff for working with the GUI library in Racket.
How do I set the callback function to a button like this:
(define next (new button% [parent frame] [label "Next ->"]))
How do I draw something on a canvas after it's been created like this:
(define canvas (new canvas% [parent frame]
[paint-callback canvasdc]))
(define canvasdc (lambda (canvas dc)
(send dc set-text-foreground "black")
(send dc draw-text "Some title!" 0 0)
))
I would need to draw (rescaled jpegs or, if not able) compound shapes and repaint with something else on every button pressed event
There's an optional callback argument to the button constructor.
See http://docs.racket-lang.org/draw/overview.html. But I'm confused by your question since the code you've posted includes drawing to the canvas. For images, specifically, read-bitmap will read a bitmap from a file; draw-bitmap will draw a bitmap into a DC. You can get it (along with all other drawing to that DC) scaled by calling set-scale. If the DC you're drawing into is a bitmap-dc (I don't think a canvas-dc is, but I am not a Racket expert and could be wrong) then you can do it directly using draw-bitmap-section-smooth.

Resources