// File: intheswim[P]FractalTubes/m3d.cpp
// Function: M3DDrawer::GetMandelColor3(DrawParams&, ShapeParams&, long double, long double, int&, int&)
long M3DDrawer::GetMandelColor3 (struct DrawParams &params, struct ShapeParams &sp,
                                 long double alpha, long double alp, int &mandel, int &fraction)
{
    long double xRadius = params.xRadius;
    
	long double currentRadius;
	double k ;
	double deltaRe = (params.xCenter2 - params.xCenter);
	double deltaIm = (params.yCenter2 - params.yCenter);
	double half_dist = sqrt (deltaRe * deltaRe + deltaIm * deltaIm) / 2;
	double ellipse_half_dist ;
	double horizRadius;
	double xDelta = 0, yDelta = 0, ellipseXCenter, ellipseYCenter;
	double cos_angle = 0.0, sin_angle = 1.0;
	double focus_dist = 2 * sqrt (half_dist * half_dist + params.max_radius * params.max_radius);
	double a = focus_dist / 2;
	double height = params.max_radius; // a always >= than b.
    
	long color = 0;
	long double Re, Im, tRe, tIm;
	long double magic = (sp.alpha_range) * params.steps1 / (params.steps1 + params.steps2);
    
	if (alpha < magic)
    {
		k = pow ((double)POWER_BASE, (double)(POWER_ADD + params.steps1 * alpha / magic));
		currentRadius = xRadius / k;
		horizRadius = currentRadius * a / height;
		ellipse_half_dist = half_dist * currentRadius / params.max_radius;
        
		if (half_dist > 0)
        {
			xDelta = ellipse_half_dist * deltaRe / (2 * half_dist);
			yDelta = ellipse_half_dist * deltaIm / (2 * half_dist);
        }
        
		ellipseXCenter =  params.xCenter + xDelta;
		ellipseYCenter =  params.yCenter + yDelta;
        
		tRe = horizRadius * cos (alp + params.sampleRotation);
		tIm = currentRadius * sin (alp + params.sampleRotation);
        
		if (half_dist > 0)
        {
			cos_angle = deltaRe / (2 *half_dist);
			sin_angle = deltaIm / (2 *half_dist);
            
			Re = tRe * cos_angle - tIm * sin_angle;
			Im = tRe * sin_angle + tIm * cos_angle;
        }
		else
        {
			Re = tRe ;
			Im = tIm ;
        }
        
		Re += ellipseXCenter; //currentParams.xCenter;
		Im += ellipseYCenter; //currentParams.yCenter;
    }
	else
    {
		k = pow ((double)POWER_BASE, (double)(POWER_ADD + params.steps2 * (sp.alpha_range - alpha) / (sp.alpha_range - magic)));
        
		currentRadius = params.xRadius2 / k;
		horizRadius = currentRadius * a / height;
		ellipse_half_dist = half_dist * currentRadius / params.max_radius;
        
		if (half_dist > 0)
        {
			xDelta = ellipse_half_dist * deltaRe / (2 * half_dist);
			yDelta = ellipse_half_dist * deltaIm / (2 * half_dist);
        }
        
		ellipseXCenter =  params.xCenter2 - xDelta;
		ellipseYCenter =  params.yCenter2 - yDelta;
        
		tRe = horizRadius * cos (alp + params.sampleRotation);
		tIm = currentRadius * sin (alp + params.sampleRotation);
        
		if (half_dist > 0)
        {
			cos_angle = deltaRe / (2 * half_dist);
			sin_angle = deltaIm / (2 * half_dist);
            
			Re = tRe * cos_angle - tIm * sin_angle;
			Im = tRe * sin_angle + tIm * cos_angle;
        }
		else
        {
			Re = tRe ;
			Im = tIm ;
        }
        
		Re += ellipseXCenter; //currentParams.xCenter;
		Im += ellipseYCenter; //currentParams.yCenter;
    }
    
	if (params.juliaSet)
    {
		color = Julia (params.juliaRe, params.juliaIm, Re, Im, mandel, fraction);
    }
	else
    {
		color = Strange(Re, Im, mandel, fraction);
    }
    
	return color;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
fldt 0x20(%rbp)
fldt 0x10(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
fstpt -0x30(%rbp)
fstpt -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movq %r8, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x10(%rbp), %rax
fldt 0x70(%rax)
fstpt -0x60(%rbp)
movq -0x10(%rbp), %rax
fldt 0x80(%rax)
fldt 0x50(%rax)
fsubrp %st, %st(1)
fstpl -0x80(%rbp)
movq -0x10(%rbp), %rax
fldt 0x90(%rax)
fldt 0x60(%rax)
fsubrp %st, %st(1)
fstpl -0x88(%rbp)
movsd -0x80(%rbp), %xmm0
movsd -0x88(%rbp), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
callq 0x32a0
movsd 0x3f13(%rip), %xmm1     # 0xe260
movsd %xmm1, -0x170(%rbp)
mulsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movq $0x0, -0xa8(%rbp)
movq $0x0, -0xb0(%rbp)
movq $0x0, -0xc8(%rbp)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0xd0(%rbp)
movsd -0x90(%rbp), %xmm0
movq -0x10(%rbp), %rax
movsd 0xb0(%rax), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
callq 0x32a0
movsd -0x170(%rbp), %xmm1
addsd %xmm0, %xmm0
movsd %xmm0, -0xd8(%rbp)
movsd -0xd8(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0xe0(%rbp)
movq -0x10(%rbp), %rax
movsd 0xb0(%rax), %xmm0
movsd %xmm0, -0xe8(%rbp)
movq $0x0, -0xf0(%rbp)
movq -0x18(%rbp), %rax
movsd 0x18(%rax), %xmm0
movq -0x10(%rbp), %rax
movss 0xbc(%rax), %xmm1
movss 0xc0(%rax), %xmm2
cvtss2sd %xmm1, %xmm3
mulsd %xmm3, %xmm0
addss %xmm2, %xmm1
cvtss2sd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x148(%rbp)
fldl -0x148(%rbp)
fstpt -0x140(%rbp)
fldt -0x30(%rbp)
fldt -0x140(%rbp)
fucompi %st(1), %st
fstp %st(0)
jbe 0xa6b7
jmp 0xa459
movq -0x10(%rbp), %rax
flds 0xbc(%rax)
fldt -0x30(%rbp)
fmulp %st, %st(1)
fldt -0x140(%rbp)
fdivrp %st, %st(1)
fldz
faddp %st, %st(1)
fstpl -0x160(%rbp)
movsd -0x160(%rbp), %xmm1
movsd 0x4006(%rip), %xmm0     # 0xe490
callq 0x3690
movsd %xmm0, -0x78(%rbp)
fldt -0x60(%rbp)
fldl -0x78(%rbp)
fdivrp %st, %st(1)
fstpt -0x70(%rbp)
fldt -0x70(%rbp)
fldl -0xe0(%rbp)
fmulp %st, %st(1)
fldl -0xe8(%rbp)
fdivrp %st, %st(1)
fstpl -0xa0(%rbp)
fldl -0x90(%rbp)
fldt -0x70(%rbp)
fmulp %st, %st(1)
movq -0x10(%rbp), %rax
fldl 0xb0(%rax)
fdivrp %st, %st(1)
fstpl -0x168(%rbp)
movsd -0x168(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x90(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa54b
movsd -0x98(%rbp), %xmm0
mulsd -0x80(%rbp), %xmm0
movsd 0x3d4d(%rip), %xmm1     # 0xe258
mulsd -0x90(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0x98(%rbp), %xmm0
mulsd -0x88(%rbp), %xmm0
movsd 0x3d21(%rip), %xmm1     # 0xe258
mulsd -0x90(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xb0(%rbp)
movq -0x10(%rbp), %rax
fldt 0x50(%rax)
fldl -0xa8(%rbp)
faddp %st, %st(1)
fstpl -0xb8(%rbp)
movq -0x10(%rbp), %rax
fldt 0x60(%rax)
fldl -0xb0(%rbp)
faddp %st, %st(1)
fstpl -0xc0(%rbp)
fldl -0xa0(%rbp)
fstpt -0x190(%rbp)
fldt -0x40(%rbp)
movq -0x10(%rbp), %rax
flds 0x34(%rax)
faddp %st, %st(1)
movq %rsp, %rax
fstpt (%rax)
callq 0xb1e0
fldt -0x190(%rbp)
fmulp %st, %st(1)
fstpt -0x120(%rbp)
fldt -0x70(%rbp)
fstpt -0x184(%rbp)
fldt -0x40(%rbp)
movq -0x10(%rbp), %rax
flds 0x34(%rax)
faddp %st, %st(1)
movq %rsp, %rax
fstpt (%rax)
callq 0xb210
fldt -0x184(%rbp)
fmulp %st, %st(1)
fstpt -0x130(%rbp)
movsd -0x90(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa672
movsd -0x80(%rbp), %xmm0
movsd -0x90(%rbp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd -0x88(%rbp), %xmm0
movsd -0x90(%rbp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xd0(%rbp)
fldt -0x120(%rbp)
fldl -0xc8(%rbp)
fldt -0x130(%rbp)
fldl -0xd0(%rbp)
fmulp %st, %st(1)
fxch %st(2)
fmulp %st, %st(1)
fsubp %st, %st(1)
fstpt -0x100(%rbp)
fldt -0x120(%rbp)
fldl -0xd0(%rbp)
fldt -0x130(%rbp)
fldl -0xc8(%rbp)
fmulp %st, %st(1)
fxch %st(2)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0x110(%rbp)
jmp 0xa68a
fldt -0x120(%rbp)
fstpt -0x100(%rbp)
fldt -0x130(%rbp)
fstpt -0x110(%rbp)
fldl -0xb8(%rbp)
fldt -0x100(%rbp)
faddp %st, %st(1)
fstpt -0x100(%rbp)
fldl -0xc0(%rbp)
fldt -0x110(%rbp)
faddp %st, %st(1)
fstpt -0x110(%rbp)
jmp 0xa928
movq -0x10(%rbp), %rax
flds 0xc0(%rax)
movq -0x18(%rbp), %rax
fldl 0x18(%rax)
fldt -0x30(%rbp)
fsubr %st(1), %st
fmulp %st, %st(2)
fldt -0x140(%rbp)
fsubrp %st, %st(1)
fdivrp %st, %st(1)
fldz
faddp %st, %st(1)
fstpl -0x150(%rbp)
movsd -0x150(%rbp), %xmm1
movsd 0x3d9d(%rip), %xmm0     # 0xe490
callq 0x3690
movsd %xmm0, -0x78(%rbp)
movq -0x10(%rbp), %rax
fldt 0xa0(%rax)
fldl -0x78(%rbp)
fdivrp %st, %st(1)
fstpt -0x70(%rbp)
fldt -0x70(%rbp)
fldl -0xe0(%rbp)
fmulp %st, %st(1)
fldl -0xe8(%rbp)
fdivrp %st, %st(1)
fstpl -0xa0(%rbp)
fldl -0x90(%rbp)
fldt -0x70(%rbp)
fmulp %st, %st(1)
movq -0x10(%rbp), %rax
fldl 0xb0(%rax)
fdivrp %st, %st(1)
fstpl -0x158(%rbp)
movsd -0x158(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x90(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa7bb
movsd -0x98(%rbp), %xmm0
mulsd -0x80(%rbp), %xmm0
movsd 0x3add(%rip), %xmm1     # 0xe258
mulsd -0x90(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0x98(%rbp), %xmm0
mulsd -0x88(%rbp), %xmm0
movsd 0x3ab1(%rip), %xmm1     # 0xe258
mulsd -0x90(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xb0(%rbp)
movq -0x10(%rbp), %rax
fldt 0x80(%rax)
fldl -0xa8(%rbp)
fsubrp %st, %st(1)
fstpl -0xb8(%rbp)
movq -0x10(%rbp), %rax
fldt 0x90(%rax)
fldl -0xb0(%rbp)
fsubrp %st, %st(1)
fstpl -0xc0(%rbp)
fldl -0xa0(%rbp)
fstpt -0x1a8(%rbp)
fldt -0x40(%rbp)
movq -0x10(%rbp), %rax
flds 0x34(%rax)
faddp %st, %st(1)
movq %rsp, %rax
fstpt (%rax)
callq 0xb1e0
fldt -0x1a8(%rbp)
fmulp %st, %st(1)
fstpt -0x120(%rbp)
fldt -0x70(%rbp)
fstpt -0x19c(%rbp)
fldt -0x40(%rbp)
movq -0x10(%rbp), %rax
flds 0x34(%rax)
faddp %st, %st(1)
movq %rsp, %rax
fstpt (%rax)
callq 0xb210
fldt -0x19c(%rbp)
fmulp %st, %st(1)
fstpt -0x130(%rbp)
movsd -0x90(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa8e8
movsd -0x80(%rbp), %xmm0
movsd -0x90(%rbp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd -0x88(%rbp), %xmm0
movsd -0x90(%rbp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0xd0(%rbp)
fldt -0x120(%rbp)
fldl -0xc8(%rbp)
fldt -0x130(%rbp)
fldl -0xd0(%rbp)
fmulp %st, %st(1)
fxch %st(2)
fmulp %st, %st(1)
fsubp %st, %st(1)
fstpt -0x100(%rbp)
fldt -0x120(%rbp)
fldl -0xd0(%rbp)
fldt -0x130(%rbp)
fldl -0xc8(%rbp)
fmulp %st, %st(1)
fxch %st(2)
fmulp %st, %st(1)
faddp %st, %st(1)
fstpt -0x110(%rbp)
jmp 0xa900
fldt -0x120(%rbp)
fstpt -0x100(%rbp)
fldt -0x130(%rbp)
fstpt -0x110(%rbp)
fldl -0xb8(%rbp)
fldt -0x100(%rbp)
faddp %st, %st(1)
fstpt -0x100(%rbp)
fldl -0xc0(%rbp)
fldt -0x110(%rbp)
faddp %st, %st(1)
fstpt -0x110(%rbp)
movq -0x10(%rbp), %rax
testb $0x1, (%rax)
je 0xa972
movq -0x178(%rbp), %rdi
movq -0x10(%rbp), %rax
fldt 0x10(%rax)
fldt 0x20(%rax)
fldt -0x100(%rbp)
fldt -0x110(%rbp)
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq %rsp, %rax
fstpt 0x30(%rax)
fstpt 0x20(%rax)
fstpt 0x10(%rax)
fstpt (%rax)
callq 0x86b0
movq %rax, -0xf0(%rbp)
jmp 0xa9a1
movq -0x178(%rbp), %rdi
fldt -0x100(%rbp)
fldt -0x110(%rbp)
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq %rsp, %rax
fstpt 0x10(%rax)
fstpt (%rax)
callq 0x8870
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
nopw %cs:(%rax,%rax)