Select Git revision
ScriptMenuView.js
-
Amanda Ghassaei authoredAmanda Ghassaei authored
frep.cpp 19.15 KiB
#include <iostream>
#include <math.h>
#include <vector>
#include <sstream> // std::ostringstream
namespace cpp_frep {
using scalar=float;
class Frep {
public:
scalar X;
scalar Y;
std::string name;
std::vector<scalar> params;
Frep* shape1;
Frep* shape2;
Frep* shape;
Frep():X(0.0f),Y(0.0f){};
Frep(std::string name_,scalar X_, scalar Y_) {
X=X_;
Y=Y_;
name=name_;
};
Frep get(){
return *this;
}
void setXY(scalar X_,scalar Y_){
X=X_;
Y=Y_;
}
virtual scalar eval(){
return 0.0f;
}
virtual void setParameters(std::vector<scalar> params_){
params=params_;
}
virtual void printName(){
std::cout<<"Frep";
}
virtual std::string getPrintedName(){
return "Frep";
}
void setShape1(Frep* shape1_){
shape1=shape1_;
}
void setShape2(Frep* shape2_){
shape2=shape2_;
}
void setShape(Frep* shape_){
shape=shape_;
}
virtual ~Frep() {
// std::cout<<"deleted_"<<name<<" \n";
}
// private:
};
//..........................SHAPES..................................//
class FrepPrimitive: public Frep {
public:
scalar center_x;
scalar center_y;
FrepPrimitive():center_x(0.0f),center_y(0.0f){};
FrepPrimitive(scalar center_x_, scalar center_y_) {
center_x=center_x_;
center_y=center_y_;
};
FrepPrimitive get(){
return *this;
}
virtual scalar eval(){
return 0.0f;
}
virtual void printName(){
std::cout<<name;
}
virtual std::string getPrintedName(){
return name;
}
};
class Circle: public FrepPrimitive {
public:
scalar radius;
Circle():radius(1.0f){
name="Circle";
};
Circle(scalar radius_,scalar center_x_, scalar center_y_) {
radius=radius_;
center_x=center_x_;
center_y=center_y_;
name="Circle";
};
scalar eval(){
return ((radius)*(radius)-((X-(center_x))*(X-(center_x))+(Y-(center_y))*(Y-(center_y))));
}
Circle get(){
return *this;
}
// private:
};
class Rectangle: public FrepPrimitive {
public:
scalar xmin;
scalar xmax;
scalar ymin;
scalar ymax;
Rectangle():xmin (-1.0f), xmax (1.0f), ymin (-1.0f), ymax (1.0f) {
name="Rectangle";
};
Rectangle(scalar xmin_, scalar xmax_,scalar ymin_,scalar ymax_) {
xmin=xmin_;
xmax=xmax_;
ymin=ymin_;
ymax=ymax_;
name="Rectangle";
};
scalar eval(){
scalar xfn = std::min(X-(xmin),(xmax)-X);
scalar yfn = std::min(Y-(ymin),(ymax)-Y);
scalar fn = std::min((xfn),(yfn));
return fn;
}
Rectangle get(){
return *this;
}
// private:
};
class InvoluteGear: public FrepPrimitive {
public:
scalar module =1.0f;
scalar angle =20.0f;
scalar teeth =10.0f;
scalar addendum =1.0f;
scalar dedendum =1.1f;
const float PI_F=3.14159265358979f;
InvoluteGear():module (1.0f), addendum (1.0f), dedendum (1.1f), angle (20.0f), teeth (10.0f) {
name="Rectangle";
};
InvoluteGear(scalar module_, scalar addendum_,scalar dedendum_,scalar angle_,scalar teeth_) {
module =module_;
angle =angle_;
teeth =teeth_;
addendum =addendum_;
dedendum =dedendum_;
name="Gear";
};
scalar eval(){
scalar rp = module*teeth/2.0f; // pitch radius
scalar rb = rp*cos(angle); // base radius
scalar ha = addendum*module; // addendum height
scalar hd= dedendum*module; // dedendum height
scalar ai = tan(angle)-angle; // involute angle
scalar ap = 2.0f*PI_F/teeth; // pitch angle
angle=PI_F*angle/180.0f;
scalar fn=std::max(std::min(std::min((rp+ha)-sqrtf(X*X+Y*Y),remainderf((PI_F+atan2f(Y,X)),ap)-(sqrtf(pow(std::max(rb,sqrtf(X*X+Y*Y))/rb,2.0)-1.0)-acosf(rb/std::max(rb,sqrt(X*X+Y*Y))))),-(sqrtf(powf(std::max(rb,sqrtf(X*X+Y*Y))/rb,2.0)-1.0)-acosf(rb/std::max(rb,sqrtf(X*X+Y*Y))))-(-(ap/2+2*ai)+remainderf((PI_F+atan2f(Y,X)),ap))),(rp-hd)-sqrtf(X*X+Y*Y));
return fn;
}
InvoluteGear get(){
return *this;
}
// private:
};
//..................................................................//
//.......................OPERATORS..................................//
class FrepOperators: public Frep {
public:
FrepOperators(){};
virtual void printName(){
std::cout<<name<<"(";
shape1->printName();
std::cout<<",";
shape2->printName();
std::cout<<")";
}
virtual std::string getPrintedName(){
std::string frepName=name+"("+shape1->getPrintedName()+","+shape2->getPrintedName()+")" ;
return frepName;
}
};
class Add: public FrepOperators {
public:
Add(){
name="Add";
};
Add(Frep* shape1_,Frep* shape2_) {
shape1=shape1_;
shape2=shape2_;
name="Add";
};
float eval(){
//change x and y
shape1->setXY(X,Y);
shape2->setXY(X,Y);
// std::cout<<"addddd\n";
return std::max(shape1->eval(),shape2->eval());
}
Add get(){
return *this;
}
};
class Subtract: public FrepOperators {
public:
Subtract(){
name="Subtract";
};
Subtract(Frep* shape1_,Frep* shape2_) {
shape1=shape1_;
shape2=shape2_;
name="Subtract";
};
float eval(){
//change x and y
shape1->setXY(X,Y);
shape2->setXY(X,Y);
return std::min(shape1->eval(),-shape2->eval());
}
Subtract get(){
return *this;
}
};
class Intersect: public FrepOperators {
public:
Intersect(){
name="Intersect";
};
Intersect(Frep* shape1_,Frep* shape2_) {
shape1=shape1_;
shape2=shape2_;
name="Intersect";
};
float eval(){
//change x and y
shape1->setXY(X,Y);
shape2->setXY(X,Y);
return std::min(shape1->eval(),shape2->eval());
}
Intersect get(){
return *this;
}
};
class Clearance: public FrepOperators {
public:
scalar offset;
Clearance():offset(0.5f){
name="Clearance";
};
Clearance(Frep* shape1_,Frep* shape2_,scalar offset_) {
shape1=shape1_;
shape2=shape2_;
offset=offset_;
name="Clearance";
};
float eval(){
//change x and y
shape1->setXY(X,Y);
shape2->setXY(X,Y);
return std::min(shape1->eval(),-(offset+shape2->eval()));
}
void setParameters(std::vector<scalar> offset_){
offset=offset_[0];
}
Clearance get(){
return *this;
}
};
class Blend: public FrepOperators {
public:
scalar offset;
Blend():offset(0.5f){
name="Blend";
};
Blend(Frep* shape1_,Frep* shape2_,scalar offset_) {
shape1=shape1_;
shape2=shape2_;
offset=offset_;
name="Blend";
};
Blend get(){
return *this;
}
void setParameters(std::vector<scalar> offset_){
offset=offset_[0];
}
float eval(){
//change x and y
shape1->setXY(X,Y);
shape2->setXY(X,Y);
scalar fn =std::max(shape1->eval(),shape2->eval());
return std::max(fn,(shape1->eval())+(shape2->eval())+(offset));
}
};
class Morph: public FrepOperators {
public:
scalar weight;
Morph():weight(0.5f){
name="Morph";
};
Morph(Frep* shape1_,Frep* shape2_,scalar weight_) {
shape1=shape1_;
shape2=shape2_;
weight=weight_;
name="Morph";
};
void setParameters(std::vector<scalar> weight_){
weight=weight_[0];
}
Morph get(){
return *this;
}
float eval(){
//change x and y
// std::cout<<"xv cv\n";
shape1->setXY(X,Y);
shape2->setXY(X,Y);
// std::cout<<"moorrrphhhh\n";
return (weight*shape1->eval()+(1-weight)*shape2->eval());
}
std::string to_string_with_precision(const scalar a_value, const int n = 2)
{
std::ostringstream out;
out.precision(n);
out << std::fixed << a_value;
return out.str();
}
std::string getPrintedName(){
std::string frepName=name+"("+shape1->getPrintedName()+","+shape2->getPrintedName()+","+ to_string_with_precision(weight,2) +")" ;
return frepName;
}
};
//..................................................................//
//.......................TRANSFORMS.................................//
class FrepTransforms: public Frep {
public:
//Frep(std::string const& name): name_(std::move(name)) {}
FrepTransforms(){};
virtual void printName(){
std::cout<<name<<"(";
shape->printName();
std::cout<<")";
}
virtual std::string getPrintedName(){
std::string frepName=name+"("+shape->getPrintedName()+")" ;
return frepName;
}
};
class Translate: public FrepTransforms {
public:
scalar dx;
scalar dy;
Translate():dx(1.0f),dy(1.0f){
name="Translate";
};
Translate(Frep* shape_,scalar dx_,scalar dy_) {
shape= shape_;
dx=dx_;
dy=dy_;
name="Translate";
};
float eval(){
//change x and y
shape->setXY(X-dx,Y-dy);
return shape->eval();
}
void setParameters(std::vector<scalar> params_){
dx=params_[0];
dy=params_[1];
}
Translate get(){
return *this;
}
};
class Scale: public FrepTransforms {
public:
scalar sx;
scalar sy;
scalar ox;
scalar oy;
Scale():sx(0.5f),sy(0.5f),ox(0.0f),oy(0.0f){
name="Scale";
};
Scale(Frep* shape_,scalar scale_factor_):sx(scale_factor_),sy(scale_factor_),ox(0.0f),oy(0.0f){
shape=shape_;
name="Scale";
};
Scale(Frep* shape_,scalar ox_, scalar oy_,scalar sx_,scalar sy_) {
shape=shape_;
sx=sx_;
sy=sy_;
ox=ox_;
oy=oy_;
name="Scale";
};
float eval(){
//change x and y
shape->setXY(((ox)+(X-(ox))/(sx)),((oy)+(Y-(oy))/(sy)));
return shape->eval();
}
void setParameters(std::vector<scalar> params_){
sx=params_[0];
sy=params_[1];
ox=params_[2];
oy=params_[3];
}
Scale get(){
return *this;
}
};
class Rotate: public FrepTransforms {
public:
scalar angle;
scalar ox;
scalar oy;
const float PI_F=3.14159265358979f;
Rotate():angle(45.0f),ox(0.0f),oy(0.0f){
name="Rotate";
};
Rotate(Frep* shape_,scalar ox_, scalar oy_, scalar angle_) {
shape=shape_;
angle=angle_;
ox=ox_;
oy=oy_;
name="Rotate";
};
Rotate get(){
return *this;
}
void setParameters(std::vector<scalar> params_){
angle=params_[0];
ox=params_[1];
oy=params_[2];
}
float eval(){
//change x and y
scalar r =angle*PI_F/180.0f;
scalar newX=((ox)+(X-(ox))*cos(r)+(Y-(oy))*sin(r));
scalar newY=((oy)-(X-(ox))*sin(r)+(Y-(oy))*cos(r));
shape->setXY(newX,newY);
// std::cout<<"rooottaattte\n";
// std::cout<< shape->name<<"\n";
float result=shape->eval();
// std::cout<<"dvds\n";
return result;
}
};
class LinearArrayX: public FrepTransforms {
public:
scalar spacing;
scalar number;
scalar size;
const float PI_F=3.14159265358979f;
LinearArrayX():spacing(0.5f),number(2.0f),size(1.0f){
name="LinearArrayX";
};
LinearArrayX(Frep* shape_,scalar spacing_,scalar number_,scalar size_) {
shape=shape_;
spacing=spacing_;
number=number_;
size=size_;
name="LinearArrayX";
};
LinearArrayX get(){
return *this;
}
void setParameters(std::vector<scalar> params_){
spacing=params_[0];
number=params_[1];
size=params_[2];
}
float eval(){
//change x and y
scalar xmin=-size;
scalar xmax=size;
scalar newX=remainderf( X ,spacing+xmax-xmin );
shape->setXY(newX,Y);
scalar fn=shape->eval();
fn = std::min(X-(xmin),fn);
fn = std::min((xmin+number*(spacing+xmax-xmin))-X,fn);
return fn;
}
};
class LinearArrayY: public FrepTransforms {
public:
scalar spacing;
scalar number;
scalar size;
const float PI_F=3.14159265358979f;
LinearArrayY():spacing(0.5f),number(2.0f),size(1.0f){
name="LinearArrayY";
};
LinearArrayY(Frep* shape_,scalar spacing_,scalar number_,scalar size_) {
shape=shape_;
spacing=spacing_;
number=number_;
size=size_;
name="LinearArrayY";
};
LinearArrayY get(){
return *this;
}
void setParameters(std::vector<scalar> params_){
spacing=params_[0];
number=params_[1];
size=params_[2];
}
float eval(){
//change x and y
scalar ymin=-size;
scalar ymax=size;
scalar newY=remainderf( Y ,spacing+ymax-ymin );
shape->setXY(X,newY);
scalar fn=shape->eval();
fn = std::min(Y-(ymin),fn);
fn = std::min((ymin+number*(spacing+ymax-ymin))-Y,fn);
return fn;
}
};
class PolarArray: public FrepTransforms {
public:
scalar angle;
scalar radius;
scalar ox;
scalar oy;
const float PI_F=3.14159265358979f;
PolarArray():angle(45.0f),radius(1.0f),ox(0.0f),oy(0.0f){
name="PolarArray";
};
PolarArray(Frep* shape_,scalar angle_,scalar radius_) {
shape=shape_;
angle=angle_;
radius=radius_;
name="PolarArray";
};
PolarArray get(){
return *this;
}
void setParameters(std::vector<scalar> params_){
angle=params_[0];
radius=params_[1];
ox=params_[2];
oy=params_[3];
}
float eval(){
//change x and y
scalar r =angle*PI_F/180.0f;
ox=-radius;
oy=radius;
scalar tmin = atan2f(-oy,-ox);
scalar newX;
scalar newY;
newX=((0.0f)+(X-(0.0f))*cos(r/2.0f)+(Y-(0.0f))*sin(r/2.0f));
newY=((0.0f)-(X-(0.0f))*sin(r/2.0f)+(Y-(0.0f))*cos(r/2.0f));
X=newX;
Y=newY;
X-=radius;
Y+=radius;
newX=(ox)+sqrt((X-(ox))*(X-(ox))+(Y-(oy))*(Y-(oy)))*cos((tmin)+remainderf((2.0f*PI_F+atan2f(Y-(oy),X-(ox))-(tmin)),(r)));
newY=(oy)+sqrt((X-(ox))*(X-(ox))+(Y-(oy))*(Y-(oy)))*sin((tmin)+remainderf((2.0f*PI_F+atan2f(Y-(oy),X-(ox))-(tmin)),(r)));
shape->setXY(newX,newY);
return shape->eval();
}
};
//..................................................................//
}