Created
December 7, 2014 21:42
-
-
Save RenaissanceBug/fd3ae0a9b0ff94c31e20 to your computer and use it in GitHub Desktop.
Drawing a Bezier curve in Racket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
;; Bezier curve drawing. jmj, 4/22/10. | |
;; Illustrates using posns to represent 2d locations, and drawing using 2htdp/image library. | |
;; Test cases removed. | |
(require 2htdp/image) | |
(define BG (rectangle 220 150 'solid 'white)) | |
;; color -> image | |
;; create a dot of the given color | |
(define (dot color) (square 2 'solid color)) | |
;; bezier : posn posn posn color image -> image | |
;; draws a bezier curve from p1 to p3, in the triangle specified by p1, p2, and | |
;; p3, onto the given background image, using the given color. | |
;; Example: | |
(define (bezier p1 p2 p3 c bg) | |
(cond | |
[(too-small? p1 p2 p3) (place-image (dot c) (posn-x p2) (posn-y p2) bg)] | |
[else | |
(local [(define m1 (midpoint p1 p2)) | |
(define m2 (midpoint p2 p3)) | |
(define mm (midpoint m1 m2))] | |
(bezier p1 m1 mm c | |
(bezier mm m2 p3 c bg)))])) | |
;; too-small? : posn posn posn -> boolean | |
;; True iff the given points are sufficiently close that no further subdivision | |
;; should happen. | |
(define (too-small? p1 p2 p3) | |
(< (+ (posn-distance p1 p2) (posn-distance p2 p3)) 2)) | |
;; midpoint : posn posn -> posn | |
;; find the midpoint between two posns | |
(define (midpoint p1 p2) | |
(local [(define (avg m n) (/ (+ m n) 2))] | |
(make-posn (avg (posn-x p1) (posn-x p2)) | |
(avg (posn-y p1) (posn-y p2))))) | |
;; posn-distance : posn posn -> num[>=0] | |
;; Pythagorean distance. | |
(define (posn-distance p1 p2) | |
(sqrt (+ (sqr (- (posn-x p1) (posn-x p2))) | |
(sqr (- (posn-y p1) (posn-y p2)))))) | |
;; Example: | |
(bezier (make-posn 10 50) (make-posn 40 10) (make-posn 70 75) 'red BG) | |
;; draws a curve from (10,50) to (70,75) pulling towards (40,10). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment