OneSpace Modeling: Draw sine curves and spirals in a workplane
A user recently asked how to draw a sine curve using Lisp. Oh well;
my math is way too rusty for this, but I'll give it a try anyway.
The following code draws a sine curve on the current workplane -
it doesn't check if there is a current workplane.
The technique which this code demonstrates is how to build a
command which takes a long sequence of input coordinates.
;; -*-Lisp-*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Description: Draw sine curve in current workplane
;; Author: Claus Brod
;; Language: Lisp
;;
;; (C) Copyright 2006 Claus Brod, all rights reserved
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(in-package :clausbrod.de)
(use-package :oli)
(defun draw-sine-curve(low high step scale)
(let (cmd (curr low))
;; loop from 0 to (high-low)/step
(dotimes (i (+ 1 (floor (/ (- high low) step))))
(push (oli:make-gpnt2d :x i :y (* scale (sin curr))) cmd)
(setf curr (+ curr step)))
(push 'bspline_int cmd)
(eval cmd)))
;; Usage example:
;;(draw-sine-curve -3.14 3.14 0.03 100)
--
ClausBrod - 24 Jan 2006
This is a trivial add-on, but for those who wonder how to use
code like the above from, say, the toolbox, here's a
minimum-effort
sd-defdialog
wrapper for the function
draw-sine-curve
.
(sd-defdialog 'DRAW_SINE
:variables
'(
(low :value-type :number)
(high :value-type :number)
(step :value-type :positive-number)
(scale :value-type :positive-integer)
)
:ok-action '(sd-call-cmds (draw-sine-curve low high step scale)))
--
ClausBrod - 25 Jan 2006
And here is how you would draw an
Archimedean spiral
which follows the formula
r = a + b * theta
(r, theta) are polar coordinates and must be converted into
cartesian coordinates for our 2D points on the workplane, but otherwise
the code is very similar to the original sine example.
Did I get the math right? I'm not sure. But anyway, the code produces
some interesting spirals!
(defun draw-archimedean-spiral(low high step &optional (a 1.0) (b 1.0))
(let (cmd r (curr low))
;; loop from 0 to (high-low)/step
(dotimes (theta (+ 1 (floor (/ (- high low) step))))
;; r = a + b * theta
(setf r (+ a (* b theta)))
(push (oli:make-gpnt2d :x (* r (cos theta)) :y (* r (sin theta))) cmd)
(setf curr (+ curr step)))
(push 'bspline_int cmd)
(eval cmd)))
;; Usage examples:
;;(draw-archimedean-spiral -3.14 3.14 0.1)
;;(draw-archimedean-spiral -3.14 3.14 0.1 100 10)
--
ClausBrod - 31 Jan 2006
Revision: r1.5 - 18 Dec 2006 - 20:38 - ClausBrod