The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle General (http://forums.omnigroup.com/forumdisplay.php?f=10)
-   -   Drawing Parabolas (http://forums.omnigroup.com/showthread.php?t=22598)

ajrose 2011-11-08 04:20 PM

Drawing Parabolas
 
I would like to use Omnigraffle for drawing physics diagrams. Is there a simple way to draw parabolas, hyperbolas, etc.?

RobTrew 2011-11-09 04:03 AM

Well, you can always use Applescript to plot any list of points,

(see code in subsequent post)

though it might be more efficient to import graphs from something like [I]Mathematica[/I] ...

[COLOR="White"]--[/COLOR]

RobTrew 2011-11-09 01:36 PM

FWIW an approach to plotting in OmniGraffle using the Korn shell functions and custom functions.

[IMG]http://farm7.static.flickr.com/6036/6331841492_ed50c8ff47_o.png[/IMG]

To quote from [I]man ksh[/I] (Terminal.app):[INDENT][I]Any of the following math library functions that are in the C math library can be used within an arithmetic expression:[/I]
abs acos acosh asin asinh atan atan2 atanh cbrt copysign cos cosh erf erfc exp exp2 expm1 fabs fdim finite floor fma fmax fmod hypot ilogb int isinf isnan lgamma log log2 logb nearbyint nextafter nextroward pow rint round sin sinh sqrt tan tanh tgamma trunc[/INDENT]
[CODE]-- Ver 0.8

-- Plots more complex Korn Shell expressions
-- Puts the data into the clipboard for pasting into OmniGraphSketcher etc
-- No longer chokes on Inf and NaN (infinities and non-numeric results)

property plstOrigin : {500, 500} -- Position of origin on the OG canvas
property pMargin : 75 -- Margin between axes and edge of canvas
property pPoints : 64 -- Number of plot points per curve

property plstRed : {65535, 0, 0}
property plstBlue : {0, 0, 65535}
property plstGray : {32767, 32767, 32767}

property pblnData2Clipboard : true


-- PLOTTING EXPRESSION DEFINED WITH KORN SHELL MATH LIBRARY FUNCTIONS
-- From the ksh Man Page: In Terminal.app:
-- man ksh
-- Any of the following math library functions that are in the C math library
-- can be used within an arithmetic expression:
-- abs acos acosh asin asinh atan atan2 atanh cbrt copysign cos cosh erf erfc
-- exp exp2 expm1 fabs fdim finite floor fma fmax fmod hypot ilogb int isinf
-- isnan lgamma log log2 logb nearbyint nextafter nextroward pow rint round
-- sin sinh sqrt tan tanh tgamma trunc

on run
tell application id "OGfl"
set recDataStyle to {line type:curved, draws stroke:true, thickness:2, draws shadow:true}
set recDataStyle1 to recDataStyle & {stroke color:plstRed}
set recDataStyle2 to recDataStyle & {stroke color:plstBlue}
set recAxisStyle to {draws stroke:true, thickness:1, stroke color:plstGray}

tell front canvas of front document
set automatic layout of its layout info to false
-- DRAW AXES
set {rX, rY} to plstOrigin
set {rX, rY} to {rX - pMargin, rY - pMargin}
repeat with oAxis in {{{-rX, 0}, {rX, 0}}, {{0, -rY}, {0, rY}}}
make new line with properties {point list:my MapList(oAxis, plstOrigin, {1, 1})} & recAxisStyle
end repeat

-- USE EXPRESSIONS IN THE SYNTAX OF THE KORN SHELL LANGUAGE
-- Plot the parabolic Fn (X^2 + 4x - 5) from x=-7 to x=5, scaling the X axis * 40 and the y axis * 10
set lstData to my DataPoints("pow(x,2)+(4*x)-5", "x", -7, 5, pPoints)
make new line with properties {point list:my MapList(lstData, plstOrigin, {40, 10})} & recDataStyle1

set lstData to my DataPoints("sin(x)", "x", -pi, pi, pPoints)
make new line with properties {point list:my MapList(lstData, plstOrigin, {100, 200})} & recDataStyle1

set lstData to my DataPoints("sinh(x)", "x", -4, 4, pPoints)
make new line with properties {point list:my MapList(lstData, plstOrigin, {100, 15})} & recDataStyle1

set lstData to my DataPoints("tanh(x)", "x", -4, 4, pPoints)
make new line with properties {point list:my MapList(lstData, plstOrigin, {100, 200})} & recDataStyle1

set lstData to my DataPoints("2*sin(x)+x", "x", -5 * pi, 5 * pi, pPoints)
make new line with properties {point list:my MapList(lstData, plstOrigin, {20, 20})} & recDataStyle2

if pblnData2Clipboard then
set strClip to ""
set {dlm, my text item delimiters} to {my text item delimiters, tab}
repeat with i from 1 to length of lstData
set strClip to (strClip & (item i of lstData) as string) & return
end repeat
set the clipboard to strClip
set my text item delimiters to dlm
end if
end tell
end tell
end run

-- Call a function to generate a number of plot points between xMin and xMax
-- KORN SHELL MATH EXPRESSION, THE VARIABLE TO BE PLOTTED (usually "x"), the range, and the number of plot points
on DataPoints(strExpr, strVar, xMin, xMax, lngPlotPoints)
set rDelta to 0
if lngPlotPoints > 1 then set rDelta to (xMax - xMin) / (lngPlotPoints - 1)
set x to xMin
set strCmd to "echo 'echo "
set lst to {}
repeat with i from 1 to lngPlotPoints
set end of lst to x
set strCmd to strCmd & "$((" & Replace(strExpr, strVar, x as string) & ")) "
set x to x + rDelta
end repeat
set strCmd to strCmd & "' | ksh"
set my text item delimiters to space
set lstData to text items of (do shell script strCmd)
set lstPoints to {}
repeat with i from 1 to lngPlotPoints
set strVar to item i of lstData
if strVar is not in {"nan", "inf"} then set end of lstPoints to {item i of lst, strVar as number}
end repeat
lstPoints
end DataPoints

-- Translate and scale the plot points into Canvas coordinates
on MapList(lstData, lstOrigin, {rXScale, rYScale})
set lst to contents of lstData
set {oX, oY} to lstOrigin
repeat with i from 1 to length of lst
set {nX, nY} to item i of lst
set item i of lst to {oX + (nX * rXScale), oY - (nY * rYScale)}
end repeat
lst
end MapList

on Replace(str, strFind, strReplace)
set {dlm, my text item delimiters} to {my text item delimiters, strFind}
set lstParts to text items of str
set my text item delimiters to strReplace
set str to lstParts as string
set my text item delimiters to dlm
str
end Replace[/CODE]

john.gersh 2011-11-10 04:50 AM

One could also send a feedback message to Omni: ask for the capability to export curves from OmniGraphSketcher to OmniGraffle.

RobTrew 2011-11-10 03:11 PM

Exchanging data with Sketcher does sound like a good approach.
(A pity that it doesn't give direct access to a language for mathematical expressions).

FWIW I've amended the code above to allow OmniGraffle to plot more complex Korn shell expressions like:[INDENT][I]2*sin(x)+x[/I][/INDENT]or [INDENT][I]pow(x,2)+(4*x)-5[/I][/INDENT] over a specified range of x.

[IMG]http://farm7.static.flickr.com/6219/6332619925_e74e28508a_o.png[/IMG]

(It's also a bit faster now, and puts the data into the clipboard, from where, incidentally, it could be pasted straight into OmniGraphSketcher ...)

[COLOR="White"]--[/COLOR]

RobTrew 2011-11-10 11:31 PM

Edited (above) to properly handle [I]Inf[/I] and [I]NaN[/I] results of the evaluation of an expression (infinities and numerically undefined).


All times are GMT -8. The time now is 01:21 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.