How to add evaluated results to 2d list

113 Views Asked by At

I'm trying to make a list of 3d coordinates of a sphere vertices, starting with ((0 0 1) ...) like this:

(defvar spherelatamount 7)
(defvar spherelonamount 8)
(defparameter sphereverticeslist
  (make-list (+ 2 (* (- spherelatamount 2) spherelonamount))))
(setf (elt sphereverticeslist 0) '(0 0 1))

Trying to add next point

(setf (elt sphereverticeslist 1)
      '(0 (sin (/ pi 6)) (cos (/ pi 6))))

this gives result

((0 0 1) (sin (/ pi 6)) (cos (/ pi 6)) ...)

while I need:

((0 0 1) (0 0.5 0.866) ...)

i.e. evaluated sin and cos. How do I achieve that? Thanks.

wrote:

(defvar spherelatamount 7)
(defvar spherelonamount 8)
(defparameter sphereverticeslist
  (make-list (+ 2 (* (- spherelatamount 2) spherelonamount))))
(setf (elt sphereverticeslist 0)
      '(0 0 1))
(setf (elt sphereverticeslist 1)
     '(0 (sin (/ pi 6)) (cos (/ pi 6))))

expecting:

((0 0 1) (0 0.5 0.866) ...) 
3

There are 3 best solutions below

6
Barmar On

Quoting the list prevents evaluation of everything in the list, so you just insert the literal values.

Call list to create a list with evaluated values.

(setf (elt sphereverticeslist 1) (list 0 (sin (/ pi 6)) (cos (/ pi 6))))

If you have a mixture of literal and evaluated values, you can use backquote/comma.

(setf (elt sphereverticeslist 1) `(0 ,(sin (/ pi 6)) ,(cos (/ pi 6))))
0
khachik On

You need to evaluate the calls:

(defvar spherelonamount 8)
(defparameter sphereverticeslist
   (make-list (+ 2 (* (- spherelatamount 2) spherelonamount))))
(setf (elt sphereverticeslist 0) '(0 0 1))
(setf (elt sphereverticeslist 1)
      `(0 ,(sin (/ pi 6)) ,(cos (/ pi 6))))
0
Shawn On

Instead of using an inefficient 3-element list, consider using a structure to represent the coordinates instead. This stores the values more compactly, gives you O(1) accessors and setters instead of a list's O(N), and lets you use symbolic names for components of the coordinates, leading to more readable code. Something like:

(defstruct sphere (distance 0.0 :type float) ; r
                  (polar-angle 0.0 :type float) ; θ
                  (azimuth 0.0 :type float)) ; φ

;; Make a list of sphere coordinates
(defparameter sphere-vertices-list
  (list (make-sphere :distance 0.0 :polar-angle 0.0 :azimuth 1.0)
        (make-sphere :distance 0.0 :polar-angle (sin (/ pi 6)) :azimuth (cos (/ pi 6)))))

;; Set and get a value
(setf (sphere-distance (first sphere-vertices-list)) 0.5)
(print (sphere-distance (first sphere-vertices-list)))
;; etc.