Music intervals graphic with TIKZ - trigonometry

I am drawing a picture showing how to position segments for the natural music scale. My trigonometry lessons are long ago forgotten, so I apologize for this is going to be a very dummy question.
Consider the followintìg tikz picture. I need to place the segment re-D so that its measure will be 8/9 the measure of the segment ut-C. Now I just placed it at a random distance of 8/9 between ut and ut'.
What mathematical function should I use (sen, cos...???) and how do I write it down for tikz?
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[scale=2]
\coordinate (o) at (0,0);
\coordinate [label=below:ut] (ut) at (2,0);
\coordinate [label=below:ut'] (ut') at (4,0);
\coordinate [label=above:C] (C) at (2, 2.4);
\coordinate [label=above:c] (c) at (4, 1.2);
\coordinate (O) at ($ (c)!2!(C) $);
\draw (ut) -- (ut');
\draw (ut) -- (C);
\draw (C) -- (c);
\draw (ut') -- (c);
\coordinate [label=below:re] (re) at ($ (ut)!8.0/9!(ut') $);
\coordinate [label=above:D] (D) at ($ (C)!8.0/9!(c) $);
\draw (re) --(D);
\node [fill=black, inner sep=1pt] (c') at ($ (ut)!1.0/6!(C) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut)!2.0/6!(C) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut)!3.0/6!(C) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut)!4.0/6!(C) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut)!5.0/6!(C) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut')!1.0/3!(c) $) {};
\node [fill=black, inner sep=1pt] (c') at ($ (ut')!2.0/3!(c) $) {};
\draw (ut') -- (c);
\end{tikzpicture}
\end{document}
Thank you,
A

If you are still interested, here is an answer to your question.
In the following code, I assumed that c is always half as high as C on the diagram. You may change the fraction for the position of D. Right now it is set at 8/9. No trigonometry was required. I removed the code defining the origin (o). It was not used in any way.
\begin{tikzpicture}[scale=1]
\newlength{\height}\setlength{\height}{2.4cm}
\newlength{\width}\setlength{\width}{4cm}
\def\fraction{0.889} %8/9
\coordinate [label=below:ut] (ut) at (0,0);
\coordinate [label=below:ut'] (ut') at (\width,0);
\coordinate [label=above:C] (C) at ($(ut) + (0,\height)$);
\coordinate [label=above:c] (c) at ($(ut') + (0,0.5\height)$);
\draw (ut) -- (ut') -- (c) -- (C) -- cycle;
\draw let
\p{C} = (C),
\p{c} = (c),
\n{y_D} = {\fraction*\y{C}},
\n{x_D} = {\x{c}*2*(1-\fraction)}
in
(\n{x_D},\n{y_D}) coordinate[label=above:D] (D) -- (\n{x_D},0) coordinate[label=below:re] (re);
%you could replace the previous line by
%(\n{x_D},\n{y_D}) -- (\n{x_D},0);
%because (D) and (re) aren't used later
\foreach \x in {1,...,5}{
\fill[black] ($ (ut)!\x/6!(C) - (1pt,1pt)$) rectangle ++(2pt,2pt);
}
\foreach \x in {1,2}{
\fill[black] ($ (ut')!\x/3!(c) - (1pt,1pt)$) rectangle ++(2pt,2pt);
}
\end{tikzpicture}
\end{document}

Related

Load image from file in Ocaml Graphics

I'm reading the documentation for the Graphics module, and there isn't any information on loading images from a file, only from a colour array. How would I go about doing this? For example, suppose I have file.png, and I want to draw it at co-ordinates (x, y) with z degrees rotation.
The camlimages library can load png files (if they are not represented in RGBA or CMYK format). A simple example:
open Images
let () = Graphics.open_graph "";;
let img = Png.load "png.png" [];;
let g = Graphic_image.of_image img;;
Graphics.draw_image g 0 0;;
Unix.sleep 10;;
To run:
opam install graphics camlimages
ocamlfind ocamlc -o test -package graphics -package unix \
-package camlimages.png -package camlimages.graphics \
-linkpkg test.ml
wget https://bytebucket.org/camlspotter/camlimages/raw/1611545463f493462aeafab65839c1112162559a/test/images/png.png
./test
(Based on the example in the library source code.)
But, I don't think camlimages can rotate pngs. You could roll your own rotate function (adapted from Mortimer's code on Dr. Dobb's):
let rotate src dst angle =
let sh, sw = Array.(float (length src), float (length src.(0))) in
let dh, dw = Array.(length dst, length dst.(0)) in
let dx, dy = float dw /. 2., float dh /. 2. in
let scale = min (float dh /. sh) (float dw /. sw) in
let duCol = sin(-.angle) *. (1. /. scale) in
let dvCol = cos(-.angle) *. (1. /. scale) in
let rec col dst x u v =
if x < dw then (
dst.(x) <- if (0. <= u && u < sw) && (0. <= v && v < sh)
then src.(truncate v).(truncate u)
else Graphics.white;
col dst (x + 1) (u +. dvCol) (v -. duCol))
in
let rec row y rowu rowv =
if y < dh then (col dst.(y) 0 rowu rowv;
row (y + 1) (rowu +. duCol) (rowv +. dvCol))
in
row 0 ((sw /. 2.) -. (dx *. dvCol +. dy *. duCol))
((sh /. 2.) -. (dx *. (-.duCol) +. dy *. dvCol))
And call it from the example code above with
let dg = Graphics.dump_image g
let dgr =Array.(make_matrix (length dg) (length dg.(0)) Graphics.white);;
rotate dg dgr (4. *. atan 1. /. 2);;
let g = Graphics.make_image dgr;;
Or, you could use something like the Sdlgfx.rotozoomSurface function of OCamlSDL.
A simple example:
let png = Sdlloader.load_image "png.png"
let png_rot = Sdlgfx.rotozoomSurface png 45.0 1.0 true;;
Sdl.init [`VIDEO];;
let screen = Sdlvideo.set_video_mode ~w:250 ~h:166 [];;
Sdlvideo.(blit_surface ~dst_rect:{ r_x = 0; r_y = 0; r_w = 250; r_h = 166}
~src:png_rot ~dst:screen ());;
Sdlvideo.flip screen;
Sdltimer.delay 10000;
Sdl.quit ();;
After installing the appropriate SDL packages on your system (not always easy...), to run:
opam install ocamlsdl
ocamlfind ocamlc -o test -package sdl -package sdl.sdlimage \
-package sdl.sdlgfx -linkpkg test.ml
./test

Is possible to define a random limit for a loop in JAGS?

I am trying to implement a Weibull proportional hazards model with a cure fraction following the approach outlined by Hui, Ibrahim and Sinha (1999) - A New Bayesian Model for Survival Data with a Surviving Fraction. However, I am not sure if it is possible to define a random limit for a looping in JAGS.
library(R2OpenBUGS)
library(rjags)
set.seed(1234)
censored <- c(1, 1)
time_mod <- c(NA, NA)
time_cens <- c(5, 7)
tau <- 4
design_matrix <- rbind(c(1, 0, 0, 0), c(1, 0.2, 0.2, 0.04))
jfun <- function() {
for(i in 1:nobs) {
censored[i] ~ dinterval(time_mod[i], time_cens[i])
time_mod[i] <- ifelse(N[i] == 0, tau, min(Z))
for (k in 1:N[i]){
Z[k] ~ dweib(1, 1)
}
N[i] ~ dpois(fc[i])
fc[i] <- exp(inprod(design_matrix[i, ], beta))
}
beta[1] ~ dnorm(0, 10)
beta[2] ~ dnorm(0, 10)
beta[3] ~ dnorm(0, 10)
beta[4] ~ dnorm(0, 10)
}
inits <- function() {
time_init <- rep(NA, length(time_mod))
time_init[which(!status)] <- time_cens[which(!status)] + 1
out <- list(beta = rnorm(4, 0, 10),
time_mod = time_init,
N = rpois(length(time_mod), 5))
return(out)
}
data_base <- list('time_mod' = time_mod, 'time_cens' = time_cens,
'censored' = censored, 'design_matrix' = design_matrix,
'tau' = tau,
'nobs' = length(time_cens[!is.na(time_cens)]))
tc1 <- textConnection("jmod", "w")
write.model(jfun, tc1)
close(tc1)
# Calling JAGS
tc2 <- textConnection(jmod)
j <- jags.model(tc2,
data = data_base,
inits = inits(),
n.chains = 1,
n.adapt = 1000)
I observed the below error:
Error in jags.model(tc2, data = data_base, inits = inits(), n.chains = 1, :
RUNTIME ERROR:
Compilation error on line 6.
Unknown variable N
Either supply values for this variable with the data
or define it on the left hand side of a relation.
I am not entirely certain, but I am pretty sure that you cannot declare a random number of nodes in BUGS in general, so it would not be a specific JAGS' quirk.
Nevertheless, you can get a way around that.
Since BUGS is a declarative language instead of a procedural one, it is enough to declare an arbitrary but deterministic number of nodes (let's say "large enough") and then associate only a random number of them with a distribution and with observed data, leaving the remaining nodes deterministic.
Once you have observed the maximum value of N[i] (let's say N.max), you can pass it as a parameter to JAGS and then change this code of yours:
for (k in 1:N[i]){
Z[k] ~ dweib(1, 1)
}
into this:
for (k in 1:N.max){
if (k <= N[i]){
Z[k] ~ dweib(1, 1)
} else {
Z[k] <- 0
}
}
I hope this will do the trick in your case. So please give feedback latter about it.
Needless to say, if you have some non-zero, observed data associated to a deterministic Z[k], then all hell breaks loose inside Jags...

Parse error on input 'let' [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
The code takes a quadtree and inserts a rectangle. However I get a parse error on the let statment. I want to call the function newExtent without having to add all the arguments. So newExtent TopLeft instead of having to call newExtent TopLeft extent rectangle. How do I make it work?
insert :: QuadTree -> Rectangle -> QuadTree
insert (Qt extent horizontal vertical qTL qTR qBL qBR) rectangle
| quadPart extent rectangle == VerLine = Qt extent horizontal (rectangle:vertical) qTL qTR qBL qBR
| quadPart extent rectangle == HorLine = Qt extent (rectangle:horizontal) vertical qTL qTR qBL qBR
| quadPart extent rectangle == TopLeft && qTL == EmptyQuadTree = Qt extent horizontal vertical (newExtent TopLeft) qTR qBL qBR
| quadPart extent rectangle == TopLeft = Qt extent horizontal vertical (insert qTL rectangle) qTR qBL qBR
| quadPart extent rectangle == TopRight && qTR == EmptyQuadTree = Qt extent horizontal vertical qTL (newExtent TopRight) qBL qBR
| quadPart extent rectangle == TopRight = Qt extent horizontal vertical qTL (insert qTR rectangle) qBL qBR
| quadPart extent rectangle == BottomLeft && qBL == EmptyQuadTree = Qt extent horizontal vertical qTL qTR (newExtent BottomLeft) qBR
| quadPart extent rectangle == BottomLeft = Qt extent horizontal vertical qTL qTR (insert qBL rectangle) qBR
| quadPart extent rectangle == BottomRight && qBR == EmptyQuadTree = Qt extent horizontal vertical qTL qTR qBL (newExtent BottomRight)
| otherwise = Qt extent horizontal vertical qTL qTR qBL (insert qBR rectangle)
let (Rect eL eT eR eB) = extent
in newExtent :: TreeParts -> Rectangle -> Rectangle -> QuadTree
newExtent part (Rect eL eT eR eB) rectangle
| part == TopLeft = insert (emptyQtree (Rect eL eT ((eL + eR) `div` 2) ((eT + eB) `div` 2))) rectangle
| part == TopRight = insert (emptyQtree (Rect ((eL + eR) `div` 2) eT eR ((eT + eB) `div` 2))) rectangle
| part == BottomLeft = insert (emptyQtree (Rect eL ((eT + eB) `div` 2) ((eL + eR) `div` 2) eB)) rectangle
| part == BottomRight = insert (emptyQtree (Rect ((eL + eR) `div` 2) ((eT + eB) `div` 2) eR eB)) rectangle
Don't indent the type signature of insert
You don't define functions in the expression after in. A let
statement allows you do define things you can then use in the
expression after in and only there. In this case a where statement would probably be easier. In constrast to the let statement here you define things after the definition of a function and you can use them in the function which seems like what you are trying to do. So try replacing your let block by
where (Rect eL eT eR eB) = extent
newExtent part
| part == TopLeft = insert (emptyQtree (Rect eL eT ((eL + eR) `div` 2) ((eT + eB) `div` 2))) rectangle
| part == TopRight = insert (emptyQtree (Rect ((eL + eR) `div` 2) eT eR ((eT + eB) `div` 2))) rectangle
| part == BottomLeft = insert (emptyQtree (Rect eL ((eT + eB) `div` 2) ((eL + eR) `div` 2) eB)) rectangle
| part == BottomRight = insert (emptyQtree (Rect ((eL + eR) `div` 2) ((eT + eB) `div` 2) eR eB)) rectangle

Focus+Context via Brushing for scatter plot in d3

How can I make dots responsive to the chart changes via brushing? I've tried to use tranfsorm attribute but it doesn't work good. Here is my fiddle. Coffescript is below
# draw dots
dots = focus.selectAll(".dot")
.data(bubbleData)
.enter().append("circle")
.attr("class", "dot")
.attr("r", (d) -> 2*Math.abs(d.surprise))
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", (d) -> color(d.surprise))
brushed = ->
xScale.domain (if brush.empty() then xScale2.domain() else brush.extent())
focus.select("._x._axis").call xAxis
focus.select(".line1").attr("d", line1(data))
focus.select(".line2").attr("d", line2(data))
focus.selectAll(".dot").attr "transform", (d, i) ->
"translate(" + xScale(d.date) + "," + yLeftScale(d.price) + ")"
Just like with the lines, you need to redraw the circles on brush:
focus.selectAll(".dot")
.attr("cx", xMap)
.attr("cy", yMap)
Complete demo here.

How can I find the general form equation of a line from two points?

Given the input:
double x1,y1,x2,y2;
How can I find the general form equation (double a,b,c where ax + by + c = 0) ?
Note: I want to be able to do this computationally. So the equivalent for slope-intercept form would be something like:
double dx, dy;
double m, b;
dx = x2 - x1;
dy = y2 - y1;
m = dy/dx;
b = y1;
Obviously, this is very simple, but I haven't been able to find the solution for the general equation form (which is more useful since it can do vertical lines). I already looked in my linear algebra book and two books on computational geometry (both too advanced to explain this).
If you start from the equation y-y1 = (y2-y1)/(x2-x1) * (x-x1) (which is the equation of the line defined by two points), through some manipulation you can get (y1-y2) * x + (x2-x1) * y + (x1-x2)*y1 + (y2-y1)*x1 = 0, and you can recognize that:
a = y1-y2,
b = x2-x1,
c = (x1-x2)*y1 + (y2-y1)*x1.
Get the tangent by subtracting the two points (x2-x1, y2-y1). Normalize it and rotate by 90 degrees to get the normal vector (a,b). Take the dot product with one of the points to get the constant, c.
If you start from the equation of defining line from 2 points
(x - x1)/(x2 - x1) = (y - y1)/(y2 - y1)
you can end up with the next equation
x(y2 - y1) - y(x2 - x1) - x1*y2 + y1*x2 = 0
so the coefficients will be:
a = y2 - y1
b = -(x2 - x1) = x1 - x2
c = y1*x2 - x1*y2
My implementation of the algorithm in C
inline v3 LineEquationFrom2Points(v2 P1, v2 P2) {
v3 Result;
Result.A = P2.y - P1.y;
Result.B = -(P2.x - P1.x);
Result.C = P1.y * P2.x - P1.x * P2.y;
return(Result);
}
Shortcut steps:
"Problem : (4,5) (3,-7)"
Solve:
m=-12/1 then
12x-y= 48
"NOTE:m is a slope"
COPY THE NUMERATOR, AFFIX "X"
Positive fraction Negative sign on between.
(tip: simmilar sign = add + copy the sign)
1.Change the second set into opposite signs,
2.ADD y1 to y2 (means add or subtract them depending of the sign),
3.ADD x1 to x2 (also means add or subtract them depending of the sign),
4.Then Multiply 12 and 1 to any of the problem set.
After that "BOOM" Tada!, you have your answer
#include <stdio.h>
main()
{
int a,b,c;
char x,y;
a=5;
b=10;
c=15;
x=2;
y=3;
printf("the equation of line is %dx+%dy=%d" ,a,b,c);
}

Resources