296 lines
7.5 KiB
C
296 lines
7.5 KiB
C
|
/*
|
|||
|
Apophysis Plugin
|
|||
|
|
|||
|
This program is free software; you can redistribute it and/or modify
|
|||
|
it under the terms of the GNU General Public License as published by
|
|||
|
the Free Software Foundation; either version 2 of the License, or
|
|||
|
(at your option) any later version.
|
|||
|
|
|||
|
This program is distributed in the hope that it will be useful,
|
|||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
GNU General Public License for more details.
|
|||
|
|
|||
|
You should have received a copy of the GNU General Public License
|
|||
|
along with this program; if not, write to the Free Software
|
|||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
Some comments on TriBorders plugin structure. It builds dual tessellation
|
|||
|
on triangle grid as Boarders variation does for square one and it uses
|
|||
|
trilinear coordinates ([link])
|
|||
|
instead of usual Cartesian system (from where Tri Borders in plugin name).
|
|||
|
Hex function doesn<EFBFBD>t work correctly in general case because its second part
|
|||
|
(determines nonlinear texture) doesn<EFBFBD>t transform lines (passes from triangle vertex)
|
|||
|
to itself for arbitrary triangle.
|
|||
|
It possible to do and I<EFBFBD>ve done main job but have not finished.
|
|||
|
*/
|
|||
|
|
|||
|
// Must define this structure before we include apoplugin.h
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
int xtrb_power;
|
|||
|
double xtrb_dist;
|
|||
|
double xtrb_radius, xtrb_width, xtrb_a, xtrb_b;
|
|||
|
double angle_Ar, angle_Br, angle_Cr;
|
|||
|
double sinA2, cosA2, sinB2, cosB2, sinC2, cosC2, sinC, cosC;
|
|||
|
double a, b, c;
|
|||
|
double Ha, Hb, Hc, S2;
|
|||
|
double ab, ac, ba, bc, ca, cb, S2a, S2b, S2c, S2ab, S2ac, S2bc;
|
|||
|
double width1, width2, width3;
|
|||
|
double absN, cN;
|
|||
|
} Variables;
|
|||
|
|
|||
|
#define _USE_MATH_DEFINES
|
|||
|
#include "apoplugin.h"
|
|||
|
|
|||
|
// Set the name of this plugin
|
|||
|
APO_PLUGIN("xtrb");
|
|||
|
|
|||
|
// Define the Variables
|
|||
|
APO_VARIABLES(
|
|||
|
VAR_INTEGER_NONZERO(xtrb_power, 2),
|
|||
|
VAR_REAL(xtrb_radius, 1.0),
|
|||
|
VAR_REAL(xtrb_width, 0.5),
|
|||
|
VAR_REAL(xtrb_dist, 1.0),
|
|||
|
VAR_REAL(xtrb_a, 1.0),
|
|||
|
VAR_REAL(xtrb_b, 1.0)
|
|||
|
);
|
|||
|
|
|||
|
// You must call the argument "vp".
|
|||
|
int PluginVarPrepare(Variation* vp)
|
|||
|
{
|
|||
|
//VAR(angle_B)= 60;
|
|||
|
//VAR(angle_C)= 60;
|
|||
|
|
|||
|
VAR(angle_Br) = 0.047 + VAR(xtrb_a);///180.0*M_PI; // angeles in radians
|
|||
|
VAR(angle_Cr) = 0.047 + VAR(xtrb_b);///180.0*M_PI;
|
|||
|
VAR(angle_Ar) =M_PI - VAR(angle_Br) - VAR(angle_Cr);
|
|||
|
|
|||
|
fsincos(0.5*VAR(angle_Ar), &VAR(sinA2), &VAR(cosA2)); // its sin, cos
|
|||
|
fsincos(0.5*VAR(angle_Br), &VAR(sinB2), &VAR(cosB2));
|
|||
|
fsincos(0.5*VAR(angle_Cr), &VAR(sinC2), &VAR(cosC2));
|
|||
|
fsincos( VAR(angle_Cr), &VAR(sinC), &VAR(cosC));
|
|||
|
|
|||
|
VAR(a) = VAR(xtrb_radius)*( VAR(sinC2)/VAR(cosC2)+ VAR(sinB2)/VAR(cosB2)); //sides
|
|||
|
VAR(b) = VAR(xtrb_radius)*( VAR(sinC2)/VAR(cosC2)+ VAR(sinA2)/VAR(cosA2));
|
|||
|
VAR(c) = VAR(xtrb_radius)*( VAR(sinB2)/VAR(cosB2)+ VAR(sinA2)/VAR(cosA2));
|
|||
|
|
|||
|
VAR(width1) = 1 - VAR(xtrb_width);
|
|||
|
VAR(width2) = 2* VAR(xtrb_width);
|
|||
|
VAR(width3) = 1 - VAR(xtrb_width)*VAR(xtrb_width);
|
|||
|
|
|||
|
VAR(S2) = VAR(xtrb_radius)*( VAR(a)+VAR(b) +VAR(c)); //square
|
|||
|
|
|||
|
VAR(Ha) = VAR(S2)/VAR(a)/6.0; //Hight div on 6.0
|
|||
|
VAR(Hb) = VAR(S2)/VAR(b)/6.0;
|
|||
|
VAR(Hc) = VAR(S2)/VAR(c)/6.0;
|
|||
|
|
|||
|
VAR(ab) = VAR(a)/VAR(b);// a div on b
|
|||
|
VAR(ac) = VAR(a)/VAR(c);
|
|||
|
VAR(ba) = VAR(b)/VAR(a);
|
|||
|
VAR(bc) = VAR(b)/VAR(c);
|
|||
|
VAR(ca) = VAR(c)/VAR(a);
|
|||
|
VAR(cb) = VAR(c)/VAR(b);
|
|||
|
VAR(S2a) = 6.0*VAR(Ha);
|
|||
|
VAR(S2b) = 6.0*VAR(Hb);
|
|||
|
VAR(S2c) = 6.0*VAR(Hc);
|
|||
|
VAR(S2bc) =VAR(S2)/(VAR(b)+VAR(c))/6.0;
|
|||
|
VAR(S2ab) =VAR(S2)/(VAR(a)+VAR(b))/6.0;
|
|||
|
VAR(S2ac) =VAR(S2)/(VAR(a)+VAR(c))/6.0;
|
|||
|
|
|||
|
VAR(absN) = (int)abs(VAR(xtrb_power));
|
|||
|
VAR(cN) = VAR(xtrb_dist) / VAR(xtrb_power) / 2;
|
|||
|
|
|||
|
|
|||
|
// Always return TRUE.
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void DirectTrilinear(Variation* vp, double x, double y, double* Al, double* Be, double* Ga)
|
|||
|
{
|
|||
|
double U = y + VAR(xtrb_radius);
|
|||
|
double V = x * VAR(sinC) - y * VAR(cosC) + VAR(xtrb_radius);
|
|||
|
*Al =U;
|
|||
|
*Be =V;
|
|||
|
*Ga = VAR(S2c) - VAR(ac) * U - VAR(bc) * V;
|
|||
|
}
|
|||
|
|
|||
|
void InverseTrilinear(Variation* vp, double Al, double Be, double* x, double* y)
|
|||
|
{
|
|||
|
double inx = (Be - VAR(xtrb_radius) +(Al - VAR(xtrb_radius))* VAR(cosC))/ VAR(sinC);
|
|||
|
double iny = Al - VAR(xtrb_radius);
|
|||
|
|
|||
|
double sina = 0.0, cosa = 0.0;
|
|||
|
|
|||
|
double angle = (atan2(iny, inx) + M_2PI * (rand() % (int)VAR(absN)))/ VAR(xtrb_power);
|
|||
|
double r = VVAR * pow(sqr(inx) + sqr(iny), VAR(cN));
|
|||
|
|
|||
|
fsincos(angle, &sina, &cosa);
|
|||
|
*x = r * cosa;
|
|||
|
*y = r * sina;
|
|||
|
//*x = 0; *y = 0;
|
|||
|
}
|
|||
|
|
|||
|
void Hex(Variation* vp, double Al, double Be, double Ga, double* Al1, double* Be1) // it's necessary
|
|||
|
//to improve for correct work for any triangle
|
|||
|
{
|
|||
|
double Ga1, De1, R;
|
|||
|
R = random01();
|
|||
|
if (Be < Al)
|
|||
|
{
|
|||
|
if (Ga < Be)
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
De1 = VAR(xtrb_width) * Be;
|
|||
|
Ga1 = VAR(xtrb_width) * Ga;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Ga1 = VAR(width1) * Ga + VAR(width2)*VAR(Hc)* Ga / Be;
|
|||
|
De1 = VAR(width1)*Be+VAR(width2)*VAR(S2ab)*(3 -Ga / Be);
|
|||
|
|
|||
|
}
|
|||
|
*Al1 = VAR(S2a) - VAR(ba)* De1 - VAR(ca)* Ga1;
|
|||
|
*Be1 = De1;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Ga < Al)
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
Ga1 = VAR(xtrb_width) * Ga;
|
|||
|
De1 = VAR(xtrb_width) * Be;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
De1 = VAR(width1) * Be + VAR(width2)*VAR(Hb)* Be / Ga;
|
|||
|
Ga1 = VAR(width1)*Ga+VAR(width2)*VAR(S2ac)*(3 -Be / Ga);
|
|||
|
|
|||
|
}
|
|||
|
*Al1 = VAR(S2a) - VAR(ba)* De1 - VAR(ca)* Ga1;
|
|||
|
*Be1 = De1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
*Al1 = VAR(xtrb_width) * Al;
|
|||
|
*Be1 = VAR(xtrb_width) * Be;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*Be1 = VAR(width1) * Be+VAR(width2)*VAR(Hb)* Be / Al;
|
|||
|
*Al1 = VAR(width1) * Al+VAR(width2)*VAR(S2ac)*(3-Be /Al);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Ga < Al)
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
De1 = VAR(xtrb_width) * Al;
|
|||
|
Ga1 = VAR(xtrb_width) * Ga;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Ga1 = VAR(width1) * Ga+VAR(width2)*VAR(Hc)* Ga / Al;
|
|||
|
De1 = VAR(width1) *Al+VAR(width2)*VAR(S2ab)*(3 -Ga /Al);
|
|||
|
|
|||
|
}
|
|||
|
*Be1 = VAR(S2b) - VAR(ab)* De1 - VAR(cb)* Ga1;
|
|||
|
*Al1 = De1;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Ga < Be)
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
Ga1 = VAR(xtrb_width) * Ga;
|
|||
|
De1 = VAR(xtrb_width) * Al;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
De1 = VAR(width1) * Al + VAR(width2)*VAR(Ha)* Al / Ga;
|
|||
|
Ga1 = VAR(width1)*Ga + VAR(width2)*VAR(S2bc)*(3 -Al/Ga);
|
|||
|
|
|||
|
}
|
|||
|
*Be1 = VAR(S2b) - VAR(ab)* De1 - VAR(cb)* Ga1;
|
|||
|
*Al1 = De1;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (R >= VAR(width3))
|
|||
|
{
|
|||
|
*Be1 = VAR(xtrb_width) * Be;
|
|||
|
*Al1 = VAR(xtrb_width) * Al;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*Al1 = VAR(width1) * Al + VAR(width2)*VAR(Ha)* Al / Be;
|
|||
|
*Be1 = VAR(width1)*Be+VAR(width2)*VAR(S2bc)*(3-Al / Be);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// You must call the argument "vp".
|
|||
|
int PluginVarCalc(Variation* vp)
|
|||
|
{
|
|||
|
double Alpha, Beta, Gamma, OffsetAl, OffsetBe, OffsetGa, X, Y;
|
|||
|
int M, N;
|
|||
|
|
|||
|
// transfer to trilinear coordinates, normalized to real distances from triangle sides
|
|||
|
|
|||
|
DirectTrilinear(vp, FTx, FTy, &Alpha, &Beta, &Gamma);
|
|||
|
|
|||
|
M = floor(Alpha/VAR(S2a));
|
|||
|
OffsetAl = Alpha - M*VAR(S2a);
|
|||
|
N = floor(Beta/VAR(S2b));
|
|||
|
OffsetBe = Beta - N*VAR(S2b);
|
|||
|
OffsetGa = VAR(S2c) - VAR(ac)*OffsetAl - VAR(bc)*OffsetBe;
|
|||
|
|
|||
|
if ( OffsetGa > 0 )
|
|||
|
{
|
|||
|
Hex(vp, OffsetAl, OffsetBe, OffsetGa, &Alpha, &Beta);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
OffsetAl = VAR(S2a) - OffsetAl;
|
|||
|
OffsetBe = VAR(S2b) - OffsetBe;
|
|||
|
OffsetGa = - OffsetGa;
|
|||
|
|
|||
|
Hex(vp, OffsetAl, OffsetBe, OffsetGa, &Alpha, &Beta);
|
|||
|
|
|||
|
Alpha = VAR(S2a) - Alpha;
|
|||
|
Beta = VAR(S2b) - Beta;
|
|||
|
|
|||
|
}
|
|||
|
Alpha = Alpha + M*VAR(S2a);
|
|||
|
Beta = Beta + N*VAR(S2b);
|
|||
|
|
|||
|
InverseTrilinear(vp, Alpha, Beta, &X, &Y);
|
|||
|
FPx += VVAR * X;
|
|||
|
FPy += VVAR * Y;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|