Metapict questions on filling polygons from points

I am trying to draw something in metapict and I am having trouble simplifying code.

Lets say I have 2 rectangles side by side, roughly:

A            B            C
x------------x------------x
|            |            |
x------------x------------x
D            E            F

and I want to draw them. I can do:

(curve A -- B -- C -- F -- E -- D -- cycle)
(curve B -- E)

But then I run into trouble if I want to fill the left side and right rides with different colours.
So I need to do in other to fill both parts

(curve A -- B -- E -- D -- cycle)
(curve B -- C -- F -- E -- cycle)

But this is not great because it redraws B -- E. Is there a better way to do this?

Another issue is... Lets say I define a bunch of point in a list. Like

(define left  (list A B E D))
(define right (list B C F E))

How do I draw the above from these lists?
The obvious (apply curve left)... of course doesn't work.

If you want to avoid redrawing, you can draw the background (the two filled rectangles) first,
then draw the lines on top. See below.

But why is redrawing a problem in the first place - do you have an example of what it looks like?
[I get the best results, when I save as svg.]

The obvious (apply curve left) ... of course doesn't work.
I think (curve* left) is what you are looking for.

#lang racket
(require metapict)

;; A            B            C
;; x------------x------------x
;; |            |            |
;; x------------x------------x
;; D            E            F

(def A (pt 0 2))
(def B (pt 2 2))
(def C (pt 4 2))

(def D (pt 0 0))
(def E (pt 2 0))
(def F (pt 4 0))

(def ACFD  (curve A -- C -- F -- D -- cycle))
(def LEFT  (curve A -- B -- E -- D -- cycle))
(def RIGHT (curve B -- C -- F -- E -- cycle))

(def BE   (curve B -- E))

(define win (window -1 5 -1 5))

(set-curve-pict-size 401 401)
(with-window win
  (draw (color "red"  (fill LEFT))
        (color "blue" (fill RIGHT))
        ACFD
        BE))

image

I forgot to use rectangle. It takes two corners (or a corner and a vector) and
makes a rectangular path. The corners become a diagonal.

(def AF    (rectangle A F))  ; A -- C -- F -- D
(def LEFT  (rectangle A E))  ; A -- B -- E -- D
(def RIGHT (rectangle B F))  ; B -- C -- F -- E

Cool thanks.

Thanks for all the explanation. Somehow I missed curve*, and I noticed now that it's because it's undocumented.

The rectangle stuff is cool but unneeded since this was just a simple example. What I am currently doing needs no rectangles. Once I get this right, I will post here what I came up with. :slight_smile:

Paulo

About curve* and curve*: I forgot to say that you need "path joins" between the points.

For example: (curve* (add-between (list (pt 1 0) (pt 2 3) (pt 3 -1)) ..))

I did an experiment with redrawing the middle vertical line.
Both look fine when svg is used.

If you save the images as "png" you can see the difference.

(set-curve-pict-size 150 150)
(with-window win
  (draw (filldraw LEFT  "red")
        (filldraw RIGHT "blue")))

(set-curve-pict-size 151 151)
(with-window win
  (draw (filldraw LEFT  "red")
        (filldraw RIGHT "blue")))

image

The effect is explained in the documentation of racket/draw.
Basically the first version where the width is 150 draws between the pixels
and the second one draws perfectly in the middle of the pixels.

The reason is due to the model used in Cairo:
http://stevehanov.ca/blog/?id=28