Customising Microcharts - charts

I'm trying to achieve the chart similar to the attached screenshot. The problem is, how can I put values in each arc (70, 76) of the chart? I'm using Microchart library.
The attached screenshot is from SmartHotel360 xamarin demo app. It would be really helpful if someone can help me to point in the correct direction.
void PopulateChart()
{
var data = new[]
{
new Microcharts.Entry(50)
{
ValueLabel = "50",
Color = SKColor.Parse("#104950")
},
new Microcharts.Entry(70)
{
ValueLabel = "70",
Color = SKColor.Parse("#F7A4B9")
},
new Microcharts.Entry(90)
{
ValueLabel = "90",
Color = SKColor.Parse("#0084b4")
}
};
this.chartView.Chart = new TemperatureChart() { Entries = data };
}
using Microcharts;
using SkiaSharp;
using System;
using System.Linq;
namespace chart
{
public class TemperatureChart : Chart
{
public TemperatureChart()
{
BackgroundColor = SKColor.Parse("#F6F1E9");
}
public float CaptionMargin { get; set; } = 12;
public float LineSize { get; set; } = 18;
public float StartAngle { get; set; } = -180;
private float AbsoluteMinimum => Entries.Select(x => x.Value).Concat(new[] { MaxValue, MinValue, InternalMinValue ?? 0 }).Min(x => Math.Abs(x));
private float AbsoluteMaximum => Entries.Select(x => x.Value).Concat(new[] { MaxValue, MinValue, InternalMinValue ?? 0 }).Max(x => Math.Abs(x));
private float ValueRange => AbsoluteMaximum - AbsoluteMinimum;
public override void DrawContent(SKCanvas canvas, int width, int height)
{
var sumValue = Entries.Sum(x => Math.Abs(x.Value));
var radius = (Math.Min(width, height) - (2 * Margin)) / 2;
var cx = width / 2;
var cy = Convert.ToInt32(height / 1.25);
var lineWidth = (LineSize < 0) ? (radius / ((Entries.Count() + 1) * 2)) : LineSize;
var radiusSpace = lineWidth * 4;
foreach (var entry in Entries.OrderByDescending(e => e.Value))
{
DrawChart(canvas, entry, radiusSpace, cx, cy, lineWidth);
}
DrawCaption(canvas, cx, cy, radiusSpace);
}
public void DrawChart(SKCanvas canvas, Entry entry, float radius, int cx, int cy, float strokeWidth)
{
using (var paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
StrokeWidth = strokeWidth,
StrokeCap = SKStrokeCap.Round,
Color = entry.Color,
IsAntialias = true
})
{
using (SKPath path = new SKPath())
{
var sweepAngle = 180 * (Math.Abs(entry.Value) - AbsoluteMinimum) / ValueRange;
path.AddArc(SKRect.Create(cx - radius, cy - radius, 2 * radius, 2 * radius), StartAngle, sweepAngle);
canvas.DrawPath(path, paint);
}
}
}
private void DrawCaption(SKCanvas canvas, int cx, int cy, float radius)
{
var minimum = 0;
var medium = Math.Round(Entries.Max(e => e.Value) / 2);
var maximum = Entries.Max(e => e.Value);
canvas.DrawCaptionLabels(string.Empty, SKColor.Empty, $"{minimum}°", SKColors.Black, LabelTextSize, new SKPoint(cx - radius - LineSize - CaptionMargin, cy), SKTextAlign.Center);
canvas.DrawCaptionLabels(string.Empty, SKColor.Empty, $"{medium}°", SKColors.Black, LabelTextSize, new SKPoint(cx, cy - radius - LineSize), SKTextAlign.Center);
canvas.DrawCaptionLabels(string.Empty, SKColor.Empty, $"{maximum}°", SKColors.Black, LabelTextSize, new SKPoint(cx + radius + LineSize + CaptionMargin, cy), SKTextAlign.Center);
}
}
}

Related

How to fix Invalid worldAABB?

public class path : MonoBehaviour
{
[Header("Line renderer veriables")]
public LineRenderer line;
[Range(2, 30)]
public int resolution;
Rigidbody rb;
[Header("Formula variables")]
public Vector3 velocity;
public float yLimit;
private float g;
[Header("Linecast variables")]
[Range(2, 30)]
public int linecastResolution;
public LayerMask canHit;
public Rigidbody ballRigid;
public open2close claw;
private void Start()
{
rb = GetComponent<Rigidbody>();
g = Mathf.Abs(Physics.gravity.y);
}
private void Update()
{
if(claw.isClosed)
RenderArc();
}
private void RenderArc()
{
line.positionCount = resolution + 1;
line.SetPositions(CalculateLineArray());
}
private Vector3[] CalculateLineArray()
{
Vector3[] lineArray = new Vector3[resolution + 1];
var lowestTimeValueX = MaxTimeX() / resolution;
var lowestTimeValueZ = MaxTimeZ() / resolution;
var lowestTimeValue = lowestTimeValueX > lowestTimeValueZ ? lowestTimeValueZ : lowestTimeValueX;
for (int i = 0; i < lineArray.Length; i++)
{
var t = lowestTimeValue * i;
lineArray[i] = CalculateLinePoint(t);
}
return lineArray;
}
private Vector3 HitPosition()
{
var lowestTimeValue = MaxTimeY() / linecastResolution;
for (int i = 0; i < linecastResolution + 1; i++)
{
RaycastHit rayHit;
var t = lowestTimeValue * i;
var tt = lowestTimeValue * (i + 1);
if (Physics.Linecast(CalculateLinePoint(t), CalculateLinePoint(tt), out rayHit, canHit))
return rayHit.point;
}
return CalculateLinePoint(MaxTimeY());
}
private Vector3 CalculateLinePoint(float t)
{
float x = rb.velocity.x * t;
float z = rb.velocity.z * t;
float y = (rb.velocity.y * t) - (g * Mathf.Pow(t, 2) / 2);
return new Vector3(x + transform.position.x, y + transform.position.y, z + transform.position.z);
}
private float MaxTimeY()
{
var v = rb.velocity.y;
var vv = v * v;
var t = (v + Mathf.Sqrt(vv + 2 * g * (transform.position.y - yLimit))) / g;
return t;
}
private float MaxTimeX()
{
if (IsValueAlmostZero(rb.velocity.x))
SetValueToAlmostZero(ref velocity.x);
var x = rb.velocity.x;
var t = (HitPosition().x - transform.position.x) / x;
return t;
}
private float MaxTimeZ()
{
if (IsValueAlmostZero(rb.velocity.z))
SetValueToAlmostZero(ref velocity.z);
var z = rb.velocity.z;
var t = (HitPosition().z - transform.position.z) / z;
return t;
}
private bool IsValueAlmostZero(float value)
{
return value < 0.0001f && value > -0.0001f;
}
private void SetValueToAlmostZero(ref float value)
{
value = 0.0001f;
}
public void SetVelocity(Vector3 velocity)
{
this.velocity = velocity;
}
}
I have this code but for some reason it shows these errors:
*Invalid AABB a
*Invalid AABB a
*UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
*Assertion failed on expression: 'IsFinite(outDistanceForSort)'
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
My trajectory isnt even showing anymore. ANyone know how to fix this?

Alternative to System.Drawing.Bitmap for Xamarin Forms

I need to use Bitmap class from System.Drawing.Bitmap, this is a function that works fine on windows Platform. But after I tried to run on Xamarin Forms, and installed nuget package System.Drawing, the program compiles correctly without errors.
But when running program I receive an error. Somehow seems to point to System.Drawing from windows, not the System.Drawing from the nuget package.
What I need to do is, get Photo from Camera and print it.
Below is the code to print. Problem is with "Bitmap" converter.
Tried several nuget packages, none worked:
System.Drawing.Common
Fast-Bitmap
Bitmap.Net
public byte[] PrintImage(byte[] PHOTO)
{
Bitmap bmp;
using (var ms = new MemoryStream(PHOTO))
{
bmp = new Bitmap(ms);
}
BitmapData data = GetBitmapData(bmp);
BitArray dots = data.Dots;
byte[] width = BitConverter.GetBytes(data.Width);
int offset = 0;
MemoryStream stream = new MemoryStream();
BinaryWriter bw = new BinaryWriter(stream);
// center command
bw.Write(27);
bw.Write('a');
bw.Write(1);
// print image
bw.Write((char)0x1B);
bw.Write('#');
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)24);
while (offset < data.Height)
{
bw.Write((char)0x1B);
bw.Write('*'); // bit-image mode
bw.Write((byte)33); // 24-dot double-density
bw.Write(width[0]); // width low byte
bw.Write(width[1]); // width high byte
for (int x = 0; x < data.Width; ++x)
{
for (int k = 0; k < 3; ++k)
{
byte slice = 0;
for (int b = 0; b < 8; ++b)
{
int y = (((offset / 8) + k) * 8) + b;
// Calculate the location of the pixel.
// It'll be at (y * width) + x.
int i = (y * data.Width) + x;
// If the image is shorter than 24 dots.
bool v = false;
if (i < dots.Length)
{
v = dots[i];
}
slice |= (byte)((v ? 1 : 0) << (7 - b));
}
bw.Write(slice);
}
}
offset += 24;
bw.Write((char)0x0A);
}
// Restore the line spacing to the default of 30 dots.
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)30);
bw.Flush();
byte[] bytes = stream.ToArray();
return bytes; // logo + Encoding.Default.GetString(bytes);
}
public BitmapData GetBitmapData(Bitmap bmp) // (string bmpFileName)
{
//using (var bitmap = (Bitmap)Bitmap.FromFile(bmpFileName))
using (var bitmap = bmp)
{
var threshold = 127;
var index = 0;
double multiplier = 570; // this depends on your printer
double scale = (double)(multiplier / (double)bitmap.Width);
int xheight = (int)(bitmap.Height * scale);
int xwidth = (int)(bitmap.Width * scale);
var dimensions = xwidth * xheight;
var dots = new BitArray(dimensions);
for (var y = 0; y < xheight; y++)
{
for (var x = 0; x < xwidth; x++)
{
var _x = (int)(x / scale);
var _y = (int)(y / scale);
var color = bitmap.GetPixel(_x, _y);
var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
dots[index] = (luminance < threshold);
index++;
}
}
return new BitmapData()
{
Dots = dots,
Height = (int)(bitmap.Height * scale),
Width = (int)(bitmap.Width * scale)
};
}
}
public class BitmapData
{
public BitArray Dots
{
get;
set;
}
public int Height
{
get;
set;
}
public int Width
{
get;
set;
}
}
Error occurs when function is called as:
byte[] _buffer = PrintImage(FOTO);
The error:
"Could not resolve type with token 01000119 from typeref (expected class 'System.Drawing.Bitmap' in assembly 'System.Drawing.Common, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51')"

Unity3d code size differs from UI size

I got a square in Unity with a size of 500x500(slightly transparent).
Additionally, I want to take a snapshot of this area. Therefore, I created the following code for taking a picture(the area has got a size of 500x500).
public class CameraShot : MonoBehaviour{
private int width = 500;
private int height = 500;
private string saveFolder = "/picture";
private string saveType = ".png";
public void MakePicture()
{
var texture = SetClipping();
EncodeAndSafe(texture);
}
private Texture2D SetClipping()
{
int x = (Screen.width - width) / 2;
int y = (Screen.height - height) / 2;
Debug.Log("[AR_Recognition] CameraShot: " + Screen.dpi);
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
Rect rect = new Rect(x, y, width, height);
tex.ReadPixels(rect, 0, 0);
tex.Apply();
return tex;
}
private void EncodeAndSafe(Texture2D texture)
{
int count = 1;
var bytes = texture.EncodeToPNG();
Destroy(texture);
string savePath = Application.persistentDataPath + saveFolder;
while (true) {
if (System.IO.File.Exists(savePath))
{
count++;
}
else
{
File.WriteAllBytes(savePath+count+saveType, bytes);
Debug.Log("[AR_Recognition] CameraShot: " + savePath + saveType);
break;
}
}
}
Now I got the following issue:
The picture taken is not matching the 500x500 square but I cannot figure out why.
Ty
EDIT: The Canvas information

Fill polygon in unity 3d

I've some problem when draw manual in unity 2d.
I used list vector to draw polygon, but I can't fill it.
I also read this tutorial: http://forum.unity3d.com/threads/draw-polygon.54092/
But it's seem I need to convert polygon to triangles.(because my polygon is complex so convert to triangles is hard. I need to use some algorithm like Ear clipping...).
Please help me an easy way to fill it. (I think unity is top of game engine, then have some way to do it easiest).
Thanks so so much.
You are stuck with converting to mesh to get fill to work... GPUs(shaders) can only fill the interior spaces of triangles... This is fairly easy if you are working with closed convex polygons. Polygons with concave sections will take a bit more complicated algorithm to convert to mesh, but it seems you've already done some research on the subject (you mentioned ear clipping).
Good luck implementing your polygon list to triangle algo :)
I can offer Poisson-Disc algorithm remodel UniformPoissonDiskSampler.cs like :
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AwesomeNamespace
{
public static class UniformPoissonDiskSampler
{
public const int DefaultPointsPerIteration = 30;
static readonly float SquareRootTwo = (float)Math.Sqrt(2);
struct Settings
{
public UnityEngine.Vector2 TopLeft, LowerRight, Center;
public UnityEngine.Vector2 Dimensions;
public float? RejectionSqDistance;
public float MinimumDistance;
public float CellSize;
public int GridWidth, GridHeight;
}
struct State
{
public UnityEngine.Vector2?[,] Grid;
public List<UnityEngine.Vector2> ActivePoints, Points;
}
public static List<UnityEngine.Vector2> SampleCircle(UnityEngine.Vector2 center, float radius, float minimumDistance)
{
return SampleCircle(center, radius, minimumDistance, DefaultPointsPerIteration);
}
public static List<UnityEngine.Vector2> SampleCircle(UnityEngine.Vector2 center, float radius, float minimumDistance, int pointsPerIteration)
{
return Sample(center - new UnityEngine.Vector2(radius, radius), center + new UnityEngine.Vector2(radius, radius), radius, minimumDistance, pointsPerIteration, null);
}
public static List<UnityEngine.Vector2> SampleRectangle(UnityEngine.Vector2 topLeft, UnityEngine.Vector2 lowerRight, float minimumDistance)
{
return SampleRectangle(topLeft, lowerRight, minimumDistance, DefaultPointsPerIteration);
}
public static List<UnityEngine.Vector2> SampleRectangle(UnityEngine.Vector2 topLeft, UnityEngine.Vector2 lowerRight, float minimumDistance, int pointsPerIteration)
{
return Sample(topLeft, lowerRight, null, minimumDistance, pointsPerIteration, null);
}
public static List<UnityEngine.Vector2> SamplePolygon(UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric, float minimumDistance)
{
return Sample(null, null, null, minimumDistance, DefaultPointsPerIteration, metric);
}
static List<UnityEngine.Vector2> Sample(UnityEngine.Vector2? topLeft, UnityEngine.Vector2? lowerRight, float? rejectionDistance, float minimumDistance, int pointsPerIteration, UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
if (!topLeft.HasValue && !lowerRight.HasValue && metric != null)
{
topLeft = new Vector2(metric.minpointx, metric.minpointz);
lowerRight = new Vector2(metric.maxpointx, metric.maxpointz);
}
var settings = new Settings
{
TopLeft = (Vector2)topLeft,
LowerRight = (Vector2)lowerRight,
Dimensions = (Vector2)lowerRight - (Vector2)topLeft,
Center = ((Vector2)topLeft + (Vector2)lowerRight) / 2,
CellSize = minimumDistance / SquareRootTwo,
MinimumDistance = minimumDistance,
RejectionSqDistance = rejectionDistance == null ? null : rejectionDistance * rejectionDistance
};
settings.GridWidth = (int)(settings.Dimensions.x / settings.CellSize) + 1;
settings.GridHeight = (int)(settings.Dimensions.y / settings.CellSize) + 1;
// Debug.Log("settings.GridWidth"+settings.GridWidth+"settings.GridHeight"+settings.GridHeight);
var state = new State
{
Grid = new UnityEngine.Vector2?[settings.GridWidth, settings.GridHeight],
ActivePoints = new List<UnityEngine.Vector2>(),
Points = new List<UnityEngine.Vector2>()
};
AddFirstPoint(ref settings, ref state, (metric == null) ? null : metric);
while (state.ActivePoints.Count != 0)
{
var listIndex = RandomHelper.Random.Next(state.ActivePoints.Count);
var point = state.ActivePoints[listIndex];
var found = false;
for (var k = 0; k < pointsPerIteration; k++)
found |= AddNextPoint(point, ref settings, ref state, (metric == null) ? null : metric);
if (!found)
state.ActivePoints.RemoveAt(listIndex);
}
return state.Points;
}
static void AddFirstPoint(ref Settings settings,
ref State state,
UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
var added = false;
while (!added)
{
var d = RandomHelper.Random.NextDouble();
var xr = settings.TopLeft.x + settings.Dimensions.x * d;
d = RandomHelper.Random.NextDouble();
var yr = settings.TopLeft.y + settings.Dimensions.y * d;
var p = new UnityEngine.Vector2((float)xr, (float)yr);
if (settings.RejectionSqDistance != null && DistanceSquared(settings.Center, p) > settings.RejectionSqDistance)
continue;
added = true;
if (UnityEditor.Experimental.TerrainAPI.Processing.figures_Included(p.x, p.y, metric.metricIn, metric.count) == true)
{
var index = Denormalize(p, settings.TopLeft, settings.CellSize);
state.Grid[(int)index.x, (int)index.y] = p;
state.ActivePoints.Add(p);
state.Points.Add(p);
}
else
{
AddFirstPoint(ref settings, ref state, metric);
}
}
}
static float DistanceSquared(Vector2 A, Vector2 B)
{
return (float)Math.Pow(Math.Sqrt(Math.Pow((A.x - B.x), 2) + Math.Pow((A.y - B.y), 2)), 2);
}
static bool AddNextPoint(UnityEngine.Vector2 point,
ref Settings settings,
ref State state,
UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
var found = false;
var q = GenerateRandomAround(point, settings.MinimumDistance);
if (metric != null)
{
if (UnityEditor.Experimental.TerrainAPI.Processing.figures_Included(q.x, q.y, metric.metricIn, metric.count) == true &&
q.x >= settings.TopLeft.x && q.x < settings.LowerRight.x &&
q.y > settings.TopLeft.y && q.y < settings.LowerRight.y &&
(settings.RejectionSqDistance == null || DistanceSquared(settings.Center, q) <= settings.RejectionSqDistance))
{
var qIndex = Denormalize(q, settings.TopLeft, settings.CellSize);
var tooClose = false;
for (var i = (int)Math.Max(0, qIndex.x - 2); i < Math.Min(settings.GridWidth, qIndex.x + 3) && !tooClose; i++)
for (var j = (int)Math.Max(0, qIndex.y - 2); j < Math.Min(settings.GridHeight, qIndex.y + 3) && !tooClose; j++)
if (state.Grid[i, j].HasValue && Vector2.Distance(state.Grid[i, j].Value, q) < settings.MinimumDistance)
tooClose = true;
if (!tooClose)
{
found = true;
state.ActivePoints.Add(q);
state.Points.Add(q);
state.Grid[(int)qIndex.x, (int)qIndex.y] = q;
}
}
}
else
{
if (q.x >= settings.TopLeft.x && q.x < settings.LowerRight.x &&
q.y > settings.TopLeft.y && q.y < settings.LowerRight.y &&
(settings.RejectionSqDistance == null || DistanceSquared(settings.Center, q) <= settings.RejectionSqDistance))
{
var qIndex = Denormalize(q, settings.TopLeft, settings.CellSize);
var tooClose = false;
for (var i = (int)Math.Max(0, qIndex.x - 2); i < Math.Min(settings.GridWidth, qIndex.x + 3) && !tooClose; i++)
for (var j = (int)Math.Max(0, qIndex.y - 2); j < Math.Min(settings.GridHeight, qIndex.y + 3) && !tooClose; j++)
if (state.Grid[i, j].HasValue && Vector2.Distance(state.Grid[i, j].Value, q) < settings.MinimumDistance)
tooClose = true;
if (!tooClose)
{
found = true;
state.ActivePoints.Add(q);
state.Points.Add(q);
state.Grid[(int)qIndex.x, (int)qIndex.y] = q;
}
}
}
return found;
}
static Vector2 GenerateRandomAround(Vector2 center, float minimumDistance)
{
var d = RandomHelper.Random.NextDouble();
var radius = minimumDistance + minimumDistance * d;
d = RandomHelper.Random.NextDouble();
var angle = MathHelper.TwoPi * d;
var newX = radius * Math.Sin(angle);
var newY = radius * Math.Cos(angle);
return new Vector2((float)(center.x + newX), (float)(center.y + newY));
}
static Vector2 Denormalize(Vector2 point, Vector2 origin, double cellSize)
{
return new Vector2((int)((point.x - origin.x) / cellSize), (int)((point.y - origin.y) / cellSize));
}
}
public static class RandomHelper
{
public static readonly System.Random Random = new System.Random();
}
public static class MathHelper
{
public const float Pi = (float)Math.PI;
public const float HalfPi = (float)(Math.PI / 2);
public const float TwoPi = (float)(Math.PI * 2);
}
}
figures_Included:
public static bool figures_Included(float xPoint, float yPoint, float[] metricIn, int n)
{
float X = xPoint;
float Y = yPoint;
int npol = n;
int i, j;
bool res = false;
float[] XYpol = metricIn;
for (i = 0, j = npol - 1; i < npol; j = i++)
{
if ((((XYpol[i * 2 + 1] <= Y) && (Y < XYpol[j * 2 + 1])) ||
((XYpol[j * 2 + 1] <= Y) && (Y < XYpol[i * 2 + 1]))) &&
(X < (XYpol[j * 2] - XYpol[i * 2]) * (Y - XYpol[i * 2 + 1]) /
(XYpol[j * 2 + 1] - XYpol[i * 2 + 1]) + XYpol[i * 2]))
{
res = !res;
}
}
return res;
}
and InMetric :
static public InMetric getmetricIn(List<Vector3> drawcoord, bool editingmode = true)
{
float mapoffsetx = 0;
float mapoffsety = 0;
if (editingmode == true)
{
mapoffsetx = Main.mainSatting.mapoffsetx;
mapoffsety = Main.mainSatting.mapoffsetz;
}
else
{
mapoffsetx = 0;
mapoffsety = 0;
}
if (drawcoord[0].x != drawcoord[drawcoord.Count - 1].x && drawcoord[0].z != drawcoord[drawcoord.Count - 1].z) //если линия, ограничивающая полигон не замкнута
drawcoord.Add(drawcoord[0]); //добавляем замыкающую вершину
float[] metricIn = new float[drawcoord.Count * 2]; //дополнительный массив вершин, пересчитанный для проверки нахождения точки внутри полигона
drawcoord[0] = new Vector3(drawcoord[0].x - mapoffsetx, 0, drawcoord[0].z - mapoffsety); //расчет 0-ой вершины в единицах Unity (метры)
metricIn[0] = drawcoord[0].x;
metricIn[1] = drawcoord[0].z; //запись 0-ой вершины в дополнительный массив. x-координаты под четными индексами, Z-координаты под нечетными индексами
float minpointx = drawcoord[0].x; //минимальная x-координата
float maxpointx = drawcoord[0].x; //максимальная х-координата
float minpointz = drawcoord[0].z; //минимальная y-координата
float maxpointz = drawcoord[0].z; //максимальная у-координата
/*Цикл обработки вершин. начинается 1-ой вершины*/
for (int i = 1; i < drawcoord.Count; i++)
{
drawcoord[i] = new Vector3(drawcoord[i].x - mapoffsetx, 0, drawcoord[i].z - mapoffsety); //расчет i-ой вершины в единицах Unity (метры)
metricIn[i * 2] = drawcoord[i].x; //запись i-ой вершины в дополнительный массив. x-координаты под четными индексами
metricIn[i * 2 + 1] = drawcoord[i].z; //запись i-ой вершины в дополнительный массив. z-координаты под нечетными индексами
/*поиск максимальных и минимальных координат по x и максимальных и минимальных координат по z*/
if (drawcoord[i].x < minpointx)
minpointx = drawcoord[i].x;
if (drawcoord[i].x > maxpointx)
maxpointx = drawcoord[i].x;
if (drawcoord[i].z < minpointz)
minpointz = drawcoord[i].z;
if (drawcoord[i].z > maxpointz)
maxpointz = drawcoord[i].z;
}
InMetric metric = new InMetric();
metric.metricIn = metricIn;
metric.minpointx = minpointx;
metric.maxpointx = maxpointx;
metric.minpointz = minpointz;
metric.maxpointz = maxpointz;
metric.drawcoord = drawcoord;
metric.count = drawcoord.Count;
return metric;
}
public class InMetric
{
public float minpointx { get; set; }
public float maxpointx { get; set; }
public float minpointz { get; set; }
public float maxpointz { get; set; }
public float[] metricIn { get; set; }
public List<Vector3> drawcoord { get; set; }
public int count { get; set; }
}

How to use Action Script file in iOS

I have a page curl code in Action Script and i want to use that code in my app which is developed using Xcode(Objective c). Can any one tell whether it is possible or not. If possible then please tell me how to do.
The action script code follows
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import asData.clsGlobalConstants;
import com.DaveLibrary.clsSupport;
import com.cupcake.Utils;
public class clsPageTurn extends Sprite
{
private var cMain:clsMain;
private var gc:clsGlobalConstants;
private var flipDirection:int;
private var pageWidth:Number;
private var pageHeight:Number;
private var pageWidthHeight:Number;
private var pivotY:Number;
private var NextPageLeft:BitmapData;
private var NextPageRight:BitmapData;
private var StationaryPage:Sprite;
private var StationaryPageMask:Sprite;
private var StationaryPageBitmap:Bitmap;
private var StationaryShadow:Sprite;
private var StationaryShadowMask:Sprite;
private var FlippingPage:Sprite;
private var FlippingPageBitmap:Bitmap;
private var FlippingPageMask:Sprite;
private var FlippingPageBorder:Sprite;
private var FlippingPageShadow:Sprite;
private var OutsideShadow:Sprite;
private var OutsideShadowMask:Sprite;
private var LeftRect:Rectangle;
private var RightRect:Rectangle;
private var LeftPoint:Point;
private var RightPoint:Point;
private var StaticLeftRect:Rectangle;
private var StaticRightRect:Rectangle;
private var StaticLeftPoint:Point;
private var StaticRightPoint:Point;
public var percentage:Number;
public var useShadows:Boolean = false;
public function clsPageTurn(Main:clsMain, FlipDirection:int, pWidth:Number = 1366, pHeight:Number = 768, xOffset:Number = -171)
{
// constructor code
cMain = Main;
gc = cMain.gc;
this.x = xOffset;
percentage = 0; // tracks the last percentage that was drawn.
StationaryPage = new Sprite();
StationaryPage.x = xOffset;
this.addChild(StationaryPage);
StationaryPageBitmap = new Bitmap();
StationaryPageBitmap.pixelSnapping = PixelSnapping.ALWAYS;
StationaryPage.addChild(StationaryPageBitmap);
StationaryPageMask = new Sprite();
StationaryPageMask.x = xOffset;
this.addChild(StationaryPageMask);
useShadows = !clsMain.isSlow;
if ( useShadows )
{
StationaryShadow = new Sprite();
StationaryShadow.x = xOffset;
this.addChild(StationaryShadow);
OutsideShadow = new Sprite();
OutsideShadow.x = xOffset;
this.addChild(OutsideShadow);
OutsideShadowMask = new Sprite();
OutsideShadowMask.x = xOffset;
this.addChild(OutsideShadowMask);
}
FlippingPage = new Sprite();
FlippingPage.x = xOffset;
this.addChild(FlippingPage);
FlippingPageBitmap = new Bitmap();
FlippingPageBitmap.pixelSnapping = PixelSnapping.ALWAYS;
FlippingPage.addChild(FlippingPageBitmap);
if ( useShadows )
{
FlippingPageBorder = new Sprite();
FlippingPage.addChild(FlippingPageBorder);
}
FlippingPageMask = new Sprite();
FlippingPageMask.x = xOffset;
this.addChild(FlippingPageMask);
if ( useShadows )
{
FlippingPageShadow = new Sprite();
FlippingPage.addChild(FlippingPageShadow);
}
// set the page width and height and other variables for this page flip object.
pageWidth = pWidth / 2; // the width is the width of one of our half pages, not the full screen width.
pageHeight = pHeight;
pageWidthHeight = pageWidth + pageHeight;
pivotY = (pageHeight/2) + pageWidth;
// rect and points for copying the halves.
LeftRect = new Rectangle(xOffset, 0, pageWidth, pageHeight);
RightRect = new Rectangle(pageWidth + xOffset, 0, pageWidth, pageHeight);
LeftPoint = new Point(xOffset,0);
RightPoint = new Point(pageWidth + xOffset, 0);
StaticLeftRect = new Rectangle(0, 0, pageWidth, pageHeight);
StaticRightRect = new Rectangle(pageWidth, 0, pageWidth, pageHeight);
StaticLeftPoint = new Point(0,0);
StaticRightPoint = new Point(pageWidth, 0);
flipDirection = FlipDirection;
// create our page halves.
NextPageLeft = new BitmapData(pageWidth, pageHeight, true, 0);
NextPageRight = new BitmapData(pageWidth, pageHeight, true, 0);
if(flipDirection > 0) {
StationaryPageBitmap.bitmapData = NextPageRight;
FlippingPageBitmap.bitmapData = NextPageLeft;
} else {
StationaryPageBitmap.bitmapData = NextPageLeft;
FlippingPageBitmap.bitmapData = NextPageRight;
}
// disable the mouse for this sprite so it doesn't trap events.
this.mouseEnabled = false;
this.mouseChildren = false;
}
public function destroy():void
{
this.graphics.clear();
if(this.parent != null) {
if(this.parent.contains(this)) {
this.parent.removeChild(this);
}
}
if(NextPageLeft != null) NextPageLeft.dispose();
NextPageLeft = null;
if(NextPageRight != null) NextPageRight.dispose();
NextPageRight = null;
if(StationaryPage != null) {
while(StationaryPage.numChildren < 0) {
StationaryPage.removeChildAt(0);
}
}
StationaryPage = null;
if(StationaryPageMask != null) StationaryPageMask.graphics.clear();
StationaryPageMask = null;
if(StationaryShadow != null) StationaryShadow.graphics.clear();
StationaryShadow = null;
if(StationaryShadowMask != null) StationaryShadowMask.graphics.clear();
StationaryShadowMask = null;
if(OutsideShadow != null) {
while(OutsideShadow.numChildren < 0) {
OutsideShadow.removeChildAt(0);
}
}
OutsideShadow = null;
if(OutsideShadowMask != null) OutsideShadowMask.graphics.clear();
OutsideShadowMask = null;
if(FlippingPage != null) {
while(FlippingPage.numChildren > 0) {
FlippingPage.removeChildAt(0);
}
}
FlippingPage = null;
if(FlippingPageMask != null) FlippingPageMask.graphics.clear();
FlippingPageMask = null;
if(FlippingPageShadow != null) FlippingPageShadow.graphics.clear();
FlippingPageShadow = null;
if(FlippingPageBitmap != null) {
if(FlippingPageBitmap.bitmapData != null) FlippingPageBitmap.bitmapData.dispose();
}
FlippingPageBitmap = null;
gc = null;
cMain = null;
}
public function Initialize( NextPage:BitmapData ):void
{
NextPageLeft.copyPixels(NextPage, StaticLeftRect, StaticLeftPoint);
NextPageRight.copyPixels(NextPage, StaticRightRect, StaticLeftPoint);
StationaryPageBitmap.smoothing = useShadows;
FlippingPageBitmap.smoothing = useShadows;
redraw(0);
}
public function InitializeDO( NextPage:DisplayObject ):void
{
var rect:Rectangle = NextPage.scrollRect;
NextPage.scrollRect = LeftRect;
NextPageLeft.draw( NextPage );
NextPage.scrollRect = RightRect;
NextPageRight.draw( NextPage );
NextPage.scrollRect = rect;
StationaryPageBitmap.smoothing = useShadows;
FlippingPageBitmap.smoothing = useShadows;
redraw(0);
}
public function InitializeHelperObjects():void
{
var bmData:BitmapData;
var m:Matrix;
var colors:Array;
var alphas:Array;
var ratios:Array;
var maxLength:Number = Math.sqrt((pageWidth * pageWidth)+(pageWidthHeight * pageWidthHeight));
var matrix:Matrix = new Matrix();
StationaryPageBitmap.x = ((flipDirection * pageWidth) / 2) - (pageWidth / 2);
StationaryPageBitmap.y = -pivotY - (pageHeight/2);
StationaryPage.x = pageWidth;
StationaryPage.y = pivotY + (pageHeight / 2);
StationaryPageMask.graphics.clear();
StationaryPageMask.graphics.beginFill(0x00FF00,1);
StationaryPageMask.graphics.drawRect(((flipDirection > 0) ? 0 : -pageWidth) , (-pivotY) - (pageWidthHeight / 2), pageWidth, pageWidthHeight);
StationaryPageMask.graphics.endFill();
StationaryPageMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
colors = [gc.pageTurn_InsideShadow_Color, gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color];
alphas = [0,0,gc.pageTurn_InsideShadow_Stationary_Max,0,0];
ratios = [0,85,125,170,255];
matrix = new Matrix();
if ( useShadows )
{
StationaryShadow.graphics.clear();
StationaryShadow.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
StationaryShadow.graphics.drawRect(((flipDirection > 0) ? 0 : -pageWidth), (-pivotY) - (pageWidthHeight / 2), pageWidth, pageWidthHeight);
StationaryShadow.graphics.endFill();
StationaryShadow.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
}
FlippingPageBitmap.x = ((-flipDirection * pageWidth) / 2) - (pageWidth / 2);
FlippingPageBitmap.y = (-pivotY) - (pageHeight / 2);
FlippingPage.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
maxLength = Math.sqrt((pageWidth * pageWidth)+(pageWidthHeight * pageWidthHeight));
colors = [gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color];
alphas = [0, gc.pageTurn_InsideShadow_Flipping_Max, gc.pageTurn_InsideShadow_Flipping_Max, 0];
ratios = [0, 100, 150, 255];
matrix = new Matrix();
matrix.createGradientBox( pageWidth, FlippingPageBitmap.height, 0, 0, 0);
if ( useShadows )
{
FlippingPageShadow.graphics.clear();
FlippingPageShadow.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
FlippingPageShadow.graphics.drawRect(0, 0, FlippingPageBitmap.width, FlippingPageBitmap.height);
FlippingPageShadow.graphics.endFill();
FlippingPageShadow.transform.matrix = new Matrix(1,0,0,1,FlippingPageBitmap.x, FlippingPageBitmap.y);
}
FlippingPageMask.graphics.clear();
FlippingPageMask.graphics.beginFill(0xFF0000,1);
FlippingPageMask.graphics.drawRect(((-flipDirection * pageWidthHeight) / 2) - (pageWidthHeight/2), (-pivotY) - (pageWidthHeight / 2), pageWidthHeight, pageWidthHeight*2);
FlippingPageMask.graphics.endFill();
FlippingPageMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
if ( useShadows )
{
OutsideShadow.graphics.clear();
OutsideShadow.graphics.beginFill(0x000000,cMain.gc.pageTurn_OutsideShadow_Alpha);
OutsideShadow.graphics.drawRect(FlippingPageBitmap.x, FlippingPageBitmap.y, FlippingPageBitmap.width, FlippingPageBitmap.height);
OutsideShadow.graphics.endFill();
OutsideShadow.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
OutsideShadowMask.graphics.clear();
OutsideShadowMask.graphics.beginFill(0x0000FF,1);
OutsideShadowMask.graphics.drawRect(((-flipDirection * pageWidthHeight) / 2) - (pageWidthHeight/2), (-pivotY) - (pageWidthHeight / 2), pageWidthHeight, pageWidthHeight*2);
OutsideShadowMask.graphics.endFill();
OutsideShadowMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
FlippingPageBorder.x = FlippingPageBitmap.x;
FlippingPageBorder.y = FlippingPageBitmap.y;
FlippingPageBorder.width = pageWidth;
FlippingPageBorder.height = pageHeight;
FlippingPageBorder.graphics.clear();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(0,0,gc.pageTurn_Border_Size, pageHeight);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(gc.pageTurn_Border_Size,0,pageWidth-(gc.pageTurn_Border_Size*2), gc.pageTurn_Border_Size);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(gc.pageTurn_Border_Size,pageHeight - gc.pageTurn_Border_Size,pageWidth - (gc.pageTurn_Border_Size*2), gc.pageTurn_Border_Size);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(pageWidth - gc.pageTurn_Border_Size,0,gc.pageTurn_Border_Size, pageHeight);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.visible = true;
}
StationaryPage.mask = StationaryPageMask;
FlippingPage.mask = FlippingPageMask;
if ( useShadows ) OutsideShadow.mask = OutsideShadowMask;
}
public function redraw(Percentage:Number):void
{
percentage = Utils.Clamp( Percentage, 0, 1 );
var rot:Number = flipDirection * 45 * Percentage;
rotateSprite(FlippingPage, (flipDirection * 90) - rot * 2);
if ( useShadows )
{
FlippingPageShadow.alpha = 0;
StationaryShadow.alpha = clsSupport.GetBezier2DPercentage(0,0,1,1,Percentage);
FlippingPageBorder.alpha = gc.pageTurn_Border_Alpha * (1 - percentage);
rotateSprite(OutsideShadow, ((flipDirection * 90) - rot * 2) + (clsSupport.GetBezier2DPercentage(gc.pageTurn_OutsideShadow_OffsetStart, gc.pageTurn_OutsideShadow_OffsetEnd, gc.pageTurn_OutsideShadow_LeadIn, gc.pageTurn_OutsideShadow_LeadOut, Percentage) * -flipDirection));
rotateSprite(StationaryShadow, (flipDirection * 45) - rot );
rotateSprite(OutsideShadowMask, (flipDirection * 45) - rot);
}
rotateSprite(StationaryPageMask, (flipDirection * 45) - rot );
rotateSprite(FlippingPageMask, (flipDirection * 45) - rot);
if(Percentage == 0 && useShadows)
{
FlippingPageBorder.x = FlippingPageBitmap.x;
FlippingPageBorder.y = FlippingPageBitmap.y;
FlippingPageBorder.width = FlippingPageBitmap.bitmapData.width;
FlippingPageBorder.height = FlippingPageBitmap.bitmapData.height;
}
}
private function rotateSprite(spr:Sprite, degress:Number):void
{
var m:Matrix;
var x:Number;
var y:Number;
x = spr.x;
y = spr.y;
m = spr.transform.matrix;
m.a = 1;
m.b = 0;
m.c = 0;
m.d = 1;
m.rotate(clsSupport.ToRadians(degress));
m.tx = x;
m.ty = y;
spr.transform.matrix = m;
}
}
}
Can anyone tell me how to do this. Any help will be appreciated.
Impossible. if you want to use it in objective-c, must directly porting. Note that the page curl effect is built into iOS. To use the code on the iPhone using Air for iOS development.
Use a UIPageViewController to have this curl effect. Set the transitionStyle to UIPageViewControllerTransitionStylePageCurl or use the init-method – initWithTransitionStyle:navigationOrientation:options: .
Create instances of all the viewController you want use in put them into an array. This array is first argument of the setViewControllers:direction:animated:completion: method.