/
squirl.lisp
26 lines (23 loc) · 1.26 KB
/
squirl.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*-
(in-package :squirl)
(defun moment-of-inertia-for-circle (mass inner-diameter outer-diameter &optional (offset +zero-vector+))
"Calculate the moment of inertia for a circle.
A solid circle has an inner diameter of 0."
(+ (* mass 1/2 (+ (expt inner-diameter 2) (expt outer-diameter 2)))
(* mass (vec-length-sq offset))))
(defun moment-of-inertia-for-segment (mass point-a point-b)
"Calculate the moment of inertia for a line segment connecting POINT-A to POINT-B."
(let ((length (vec-length (vec- point-b point-a))))
(+ (* mass length (/ length 12))
(* mass (vec-length-sq (vec* (vec+ point-a point-b) 0.5d0))))))
(defun moment-of-inertia-for-poly (m verts &optional (offset +zero-vector+))
"Calculate the moment of inertia for a solid convex polygon."
(flet ((transform-vertex (vertex) (vec+ vertex offset)))
(let ((vertices (coerce verts 'list))) ; I would dx, but shitux.
(loop
for vertex in vertices
for v1 = (transform-vertex vertex)
and v2 = (transform-vertex (car (last vertices))) then v1
for a = (vec-cross v2 v1) sum a into sum2
sum (* a (+ (vec. v1 v1) (vec. v1 v2) (vec. v2 v2))) into sum1
finally (return (/ (* m sum1) (* 6 sum2)))))))