Racket 转换图形上下文的原点

Racket 转换图形上下文的原点,racket,Racket,我试图转换一个dc实例,以便将原点(0,0)设置为左下角。但原则上,我很难理解它是如何工作的,以及为什么我会看到自己的行为。首先,以下是我正在使用的代码。请注意,我绘制的线从左上角的(0,0)开始 #lang racket (require racket/draw) ;;; Begin our drawing (define w 200) (define h 200) (define dc (new pdf-dc% [interactive #f]

我试图转换一个
dc
实例,以便将原点(0,0)设置为左下角。但原则上,我很难理解它是如何工作的,以及为什么我会看到自己的行为。首先,以下是我正在使用的代码。请注意,我绘制的线从左上角的(0,0)开始

#lang racket
(require racket/draw)


;;; Begin our drawing
(define w 200)
(define h 200)
(define dc (new pdf-dc%
                [interactive #f]
                [use-paper-bbox #f]
                [width w]
                [height h]
                [output "./foo.pdf"]))

(send dc start-doc "file output")
(send dc start-page)

(send dc draw-line 0 0 150 150)

(send dc end-page)
(send dc end-doc)

从那里,我相信我应该能够向我的dc实例发送带有适当转换矩阵的
set transformation
消息。然而,我仍然无法找到合适的转换数据结构

请让我参考有关的文档。在这里,我了解到我需要传入一个包含初始变换矩阵的向量,我可以通过它检索,以及变换参数x origin、y origin、x scale、y scale和rotation

我对这一点的第一次天真攻击让我按照如下方式构建转换数据结构,通过第一部分的
get initial matrix
获取初始矩阵,然后翻转y比例:

#lang racket
(require racket/draw)

;;; Begin our drawing
(define w 50)
(define h 50)
(define dc (new pdf-dc%
                [interactive #f]
                [use-paper-bbox #f]
                [width w]
                [height h]
                [output "./foo.pdf"]))

(send dc start-doc "file output")
(send dc start-page)

;(send dc get-transformation)
;; returns '#(#(1.0 0.0 0.0 1.0 0.0 0.0) 0.0 0.0 1.0 1.0 0.0)

(send dc set-transformation
      (vector (send dc get-initial-matrix)
              0  0  ; x origin, y origin
              1  -1  ; x scale, y scale
              0))   ; rotation

(send dc draw-line 0 0 50 50)

(send dc end-page)
(send dc end-doc)
这将导致一个空的图形,大概是将线条平移到了视图之外的某个位置

阅读上的注释,它建议我需要向y原点添加偏移(即,需要翻转比例并转换原点)。我的下一次尝试添加了以下内容:

#lang racket
(require racket/draw)

;;; Begin our drawing
(define w 50)
(define h 50)
(define dc (new pdf-dc%
                [interactive #f]
                [use-paper-bbox #f]
                [width w]
                [height h]
                [output "./foo.pdf"]))

(send dc start-doc "file output")
(send dc start-page)

;(send dc get-transformation)
;; returns '#(#(1.0 0.0 0.0 1.0 0.0 0.0) 0.0 0.0 1.0 1.0 0.0)

(send dc set-transformation
      (vector (send dc get-initial-matrix)
              0  h  ; x origin, y origin
              1  -1  ; x scale, y scale
              0))   ; rotation

(send dc draw-line 0 0 50 50)

(send dc end-page)
(send dc end-doc)
这似乎会将绘图元素带回框架中,但我不太在原点:

在该图形中,我注意到我的原点似乎仍然垂直移动,大约向上移动了图形上下文的四分之一。我可以为我的y原点添加另一个位(摘自完整示例):

看起来不错,但还是有点不对劲:

链接SO线程中的最后一条注释建议我需要提供一个修改初始转换矩阵的函数。这对我来说没有什么意义,因为我从文档中推断,初始转换矩阵是一个起点,而不是终点。此外,在这一点上,似乎需要做很多额外的工作来做一些看起来应该很简单的事情,这似乎符合逻辑,这将是集转换之类的函数的一部分


对不起,这里的问题太长了,但我希望有人能告诉我,我在哪里误解了一些显而易见的事情。

你的方法是正确的。你只是错过了一个小细节

PDF和postscript文件通常用于打印。打印的文档需要一个边距(打印机需要抓住纸张的边缘)。
(当前ps设置)
中的设置用于纸张大小、边距大小和缩放。将缩放比例设置为1,边距大小设置为0,将得到预期的结果

#lang racket
(require racket/draw)

;;; Begin our drawing
(define w 200)
(define h 200)

(define setup (new ps-setup%))
(send setup set-paper-name "Peter")
; introduce margins such that the result is centered
(define α 1) ; a scale, try 0.9 to see how it works
(send setup set-margin (/ (* (- 1 α) w) 2) (/ (* (- 1 α) h) 2))
(send setup set-editor-margin 0 0)
(send setup set-scaling α α)
(current-ps-setup setup)

(define dc (new pdf-dc%
                [interactive #f]
                [use-paper-bbox #f]
                [width w]
                [height h]
                [output "./foo.pdf"]))

(send dc start-doc "file output")
(send dc start-page)

(send (current-ps-setup) set-margin 0 0) 
(send (current-ps-setup) set-scaling 1 1)
(send (current-ps-setup) set-translation 0 0)
(send (current-ps-setup) set-editor-margin 0 0)

(send dc set-transformation
      (vector (send dc get-initial-matrix)
              0  h  ; x origin, y origin
              1  -1  ; x scale, y scale
              0))   ; rotation

(send dc draw-line 0 0 150 150)
(send dc draw-line 0 200 200 0)

(send dc end-page)
(send dc end-doc)

滚动查看最后一行。谢谢!我完全误解了文档中关于
使用纸质bbox#f
选项的内容。这是一个非常有益的澄清。
#lang racket
(require racket/draw)

;;; Begin our drawing
(define w 200)
(define h 200)

(define setup (new ps-setup%))
(send setup set-paper-name "Peter")
; introduce margins such that the result is centered
(define α 1) ; a scale, try 0.9 to see how it works
(send setup set-margin (/ (* (- 1 α) w) 2) (/ (* (- 1 α) h) 2))
(send setup set-editor-margin 0 0)
(send setup set-scaling α α)
(current-ps-setup setup)

(define dc (new pdf-dc%
                [interactive #f]
                [use-paper-bbox #f]
                [width w]
                [height h]
                [output "./foo.pdf"]))

(send dc start-doc "file output")
(send dc start-page)

(send (current-ps-setup) set-margin 0 0) 
(send (current-ps-setup) set-scaling 1 1)
(send (current-ps-setup) set-translation 0 0)
(send (current-ps-setup) set-editor-margin 0 0)

(send dc set-transformation
      (vector (send dc get-initial-matrix)
              0  h  ; x origin, y origin
              1  -1  ; x scale, y scale
              0))   ; rotation

(send dc draw-line 0 0 150 150)
(send dc draw-line 0 200 200 0)

(send dc end-page)
(send dc end-doc)