[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: arcs in 3d?
On Thu, 31 Mar 2005, Jeffrey A. Edlund wrote:
> I'm drawing a figure using epix using arrows in 3d.
>
> arrow(lisa1center,lisa1center-1*lisa1normal); // representing the normal to a triangle in 3d
>
> arrow(lisa1center,lisa1center-(1.0/sqrt(lisa1center|lisa1center))*lisa1center); // arrow pointing towards the origin
>
> I'd like to draw an arc between the 2 arrows an then place a label next
> to the arc to indicate the angle. Is this possible when neither arrow
> is in the (x1,x2) plane?
>
Hi Jeffrey,
Here are (lightly tested:) functions that
* draw the smaller arc between two arrows in the plane spanned by the
arrows, assuming the arrows have the same length,
* return a point along said arc, with t=0 corresponding to the first point
and t=1 to the second.
---(snip)---
// arc joining arrow(center, arg1) and arrow(center, arg2)
void arc_span(P center, P arg1, P arg2)
{
// construct orthogonal basis of plane spanned
P v1=arg1-center, v2=arg2-center; // direction vectors
P perp1 = v2%v1; // orthogonalize
perp1 *= 1/norm(perp1); // OK if arrows not parallel
double norm1=norm(v1);
double norm2=norm(v2);
double theta=Acos((v1|v2)/(norm1*norm2));
ellipse(center, v1, norm1*perp1, 0, theta);
}
// generalized midpoint of arc: t=0 <-> arg1, t=1 <-> arg2
P arc_point(P center, P arg1, P arg2, double t=0.5)
{
P v1=arg1-center, v2=arg2-center;
P perp1 = v2%v1;
perp1 *= 1/norm(perp1);
double norm1=norm(v1);
double norm2=norm(v2);
double theta=t*Acos((v1|v2)/(norm1*norm2));
return center+ Cos(theta)*v1 + (Sin(theta)*norm1)*perp1;
}
---(snip)---
The attached file is a complete figure.
> Another simple question: If I have a P point, how to I access the
> members of the triple? i.e. something like point.x point.y point.z?
>
point.x1(), etc. :)
Best, Andy
Andrew D. Hwang ahwang@mathcs.holycross.edu
Department of Math and CS http://math.holycross.edu/~ahwang
College of the Holy Cross (508) 793-2458 (Office: 320 Swords)
Worcester, MA, 01610-2395 (508) 793-3530 (fax)
/* -*-ePiX-*- */
#include "epix.h"
using namespace ePiX;
void arc_span(P center, P arg1, P arg2)
{
P v1=arg1-center, v2=arg2-center;
P perp1 = v2%v1;
perp1 *= 1/norm(perp1);
double norm1=norm(v1);
double norm2=norm(v2);
double theta=Acos((v1|v2)/(norm1*norm2));
ellipse(center, v1, norm1*perp1, 0, theta);
}
P arc_point(P center, P arg1, P arg2, double t)
{
P v1=arg1-center, v2=arg2-center;
P perp1 = v2%v1;
perp1 *= 1/norm(perp1);
double norm1=norm(v1);
double norm2=norm(v2);
double theta=t*Acos((v1|v2)/(norm1*norm2));
return center+ Cos(theta)*v1 + (Sin(theta)*norm1)*perp1;
}
P ctr(2,1,0), arg1=ctr+sph(2,-M_PI/6,M_PI_4), arg2=ctr+sph(2,M_PI/8,-M_PI/3);
int main()
{
bounding_box(P(-4,-4),P(4,4));
unitlength("1in");
picture(6,6);
begin();
camera.at(P(5,4,0));
arrow_fill(1);
arrow(ctr, arg1, 0.5);
arrow(ctr, arg2, 0.5);
dot(arc_point(ctr, arg1, arg2, 0), P(0,4), "A", t);
dot(arc_point(ctr, arg1, arg2, 0.25), P(-4,0), "B", tl);
dot(arc_point(ctr, arg1, arg2, 0.5), P(-4,0), "C", l);
dot(arc_point(ctr, arg1, arg2, 0.75), P(-2,-2), "D", bl);
dot(arc_point(ctr, arg1, arg2, 1), P(0,-4), "E", b);
red(); bold();
arc_span(ctr, arg1, arg2);
end();
}
- References:
- arcs in 3d?
- From: "Jeffrey A. Edlund" <jaedlund@glaxonlabs.com>